Compare commits
186 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f74328ffc | |||
| 54370f3188 | |||
| 4a51eae628 | |||
| 34241385f9 | |||
| 7ec01ed39f | |||
| 1ff861f9db | |||
| 4c125afd7b | |||
| e561980e7f | |||
| 7c346a3ac5 | |||
| abcf58d369 | |||
| 2211428614 | |||
| 08d31ff0d6 | |||
| e055030291 | |||
| 1e5cca5ffb | |||
| 85abeaf7f0 | |||
| 47480809d0 | |||
| 885bb41f27 | |||
| c74e92fb2e | |||
| a4f27b5c1d | |||
| a7941bb4c8 | |||
| 13c29412eb | |||
| 774e24d441 | |||
| 8822761c48 | |||
| 4215f90456 | |||
| c8ac385b88 | |||
| b1ef5c74c8 | |||
| a5ff2ca780 | |||
| f84c4b2d31 | |||
| b03e848669 | |||
| 76ea67af54 | |||
| 12c80e2d40 | |||
| c013953368 | |||
| 34457ead0a | |||
| 5e92889825 | |||
| b2606d209d | |||
| a18beeca1b | |||
| c1293ff395 | |||
| bc6f6c4c39 | |||
| befb84db5f | |||
| 2403288678 | |||
| cac8e1ba18 | |||
| 06255370f7 | |||
| 6ba70a76c2 | |||
| dd53b70b36 | |||
| 6873af5ac3 | |||
| 35d8c41a2b | |||
| 5f4eebe536 | |||
| ba4cfca45b | |||
| f6e4fcd2d0 | |||
| d5f1f76e24 | |||
| 8a0c9d0128 | |||
| a1ff69502a | |||
| b06cf0a06b | |||
| 5d976141fc | |||
| be8f9e2b5a | |||
| 6bf18096e7 | |||
| b7f0f5df90 | |||
| c4c06f0dc4 | |||
| ed569cde55 | |||
| 558a16d273 | |||
| 9290261fef | |||
| e2251c111c | |||
| 21ed17bb2c | |||
| 8cfe0bfe11 | |||
| 54ce865e45 | |||
| ae6d788aff | |||
| f0cfc860a1 | |||
| becdc060e9 | |||
| 9d25e61043 | |||
| 0debe8f7f9 | |||
| 9e68b55018 | |||
| 5783b83168 | |||
| f7060c7287 | |||
| e2866d2595 | |||
| 76701627b6 | |||
| 7f91ac734a | |||
| af7bc47cbf | |||
| a14b0a6fd0 | |||
| 855fedf3aa | |||
| 900427ad30 | |||
| 08bf19f74f | |||
| 68f7cb8f41 | |||
| 3088fae8a2 | |||
| 6d375312ae | |||
| 797a2b70f3 | |||
| 29cf1327ff | |||
| 613d45da37 | |||
| f29926748c | |||
| 9855ca8c15 | |||
| 7644decc64 | |||
| 81bf501c85 | |||
| ecf508ca93 | |||
| 2724b03301 | |||
| b2eb5efa12 | |||
| 661273f7bd | |||
| 5e37195591 | |||
| 0d85ad48de | |||
| 02ad0445b9 | |||
| 2bfe780faf | |||
| 284c1cfaf6 | |||
| a37d1c5f85 | |||
| 639e2c05bf | |||
| 7e5fb055c8 | |||
| 528c692f13 | |||
| dd17d364c7 | |||
| 6e56c3c190 | |||
| 617bb5f12d | |||
| fa1fa359fc | |||
| e9084847cf | |||
| da0a35a5d1 | |||
| 5fb3616c1a | |||
| 4f04e9e1b5 | |||
| 0c5b5ed59c | |||
| de167cdfb6 | |||
| 0a27fc1c2b | |||
| 1e537009e0 | |||
| 188f23faf4 | |||
| dca243825a | |||
| 650022ee10 | |||
| 98a7064f43 | |||
| 9804acd10c | |||
| 51550c96a6 | |||
| 491490c559 | |||
| ec1f13754d | |||
| b840988bbe | |||
| bd4b565799 | |||
| 102a7cbd9e | |||
| 8c34416b1a | |||
| 77af0b4ae4 | |||
| ed2d3ed931 | |||
| 0d584bb0ac | |||
| a95e7cc225 | |||
| c2caeb5900 | |||
| fe6e195c0a | |||
| 027a550c97 | |||
| 1074932eb5 | |||
| 9f0b0837d8 | |||
| d3f32288bf | |||
| c251db709e | |||
| 56d0eb0d0b | |||
| bbd4beeafe | |||
| 460719e0f0 | |||
| eed7f913e5 | |||
| e153eebe87 | |||
| c7eee14f7c | |||
| 48b4be68bd | |||
| 685da9af3e | |||
| ddaf329167 | |||
| 794af5e501 | |||
| 3028e9e29d | |||
| 704a75a2b4 | |||
| 63ae8e3ca5 | |||
| 0f09a15f20 | |||
| 23fbe106a7 | |||
| c7665a7845 | |||
| 41da92e43a | |||
| 9780cb6e35 | |||
| 7d2f5a4385 | |||
| 7144d81059 | |||
| ae162e3a46 | |||
| 311963f8ea | |||
| 2e70c24f29 | |||
| 7300d53a50 | |||
| b338f7750d | |||
| b9bb8d52f4 | |||
| 48396e7eaa | |||
| 27f959990f | |||
| e7d165d99b | |||
| 7df01df8fc | |||
| 896de431be | |||
| e0e6f416c0 | |||
| 07ded4986d | |||
| 0eb2b867c8 | |||
| aaf6759075 | |||
| bce9ed7a6f | |||
| 9edba5d992 | |||
| f9bcb47903 | |||
| 4333bfbeb3 | |||
| 5b2ab8b401 | |||
| 7bf287f706 | |||
| 94117e0345 | |||
| 6defdbe353 | |||
| ac1e402d1d | |||
| d358a75769 | |||
| c42ad3f042 | |||
| e75ca72abd |
@@ -255,8 +255,6 @@ dotnet_diagnostic.ca1509.severity = warning # Invalid entry in code metrics conf
|
||||
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)
|
||||
|
||||
dotnet_diagnostic.cs8618.severity = suggestion # nullable problem
|
||||
dotnet_diagnostic.CS0809.severity = suggestion # obsolete errors
|
||||
dotnet_diagnostic.CS0618.severity = suggestion # obsolete errors
|
||||
|
||||
|
||||
# Performance rules
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.2xx # Align with global.json (including roll forward rules)
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.2xx # Align with global.json (including roll forward rules)
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
run: ./build.sh test-only
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
file: Converters/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -2,7 +2,7 @@ name: .NET Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main", "dev"] # Continuous delivery on every long-lived branch
|
||||
branches: ["main", "dev", "release/*"] # Continuous delivery on every long-lived branch
|
||||
tags: ["v3.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.2xx # Align with global.json (including roll forward rules)
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
@@ -49,6 +49,7 @@ jobs:
|
||||
needs: build
|
||||
env:
|
||||
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
|
||||
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'main'}}
|
||||
steps:
|
||||
- name: 🔫 Trigger Build Installers
|
||||
uses: ALEEF02/workflow-dispatch@v3.0.0
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
workflow: Build Installers
|
||||
repo: specklesystems/connector-installers
|
||||
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }} }'
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
|
||||
ref: main
|
||||
wait-for-completion: true
|
||||
wait-for-completion-interval: 10s
|
||||
@@ -78,7 +79,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.2xx # Align with global.json (including roll forward rules)
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
@@ -90,7 +91,7 @@ jobs:
|
||||
run: ./build.sh test-only
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
file: Converters/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
+2
-1
@@ -19,4 +19,5 @@ tools
|
||||
.DS_Store
|
||||
*.snupkg
|
||||
coverage.xml
|
||||
output/
|
||||
output/
|
||||
Images/Thumbs.db
|
||||
|
||||
@@ -31,6 +31,22 @@ public static class Consts
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2025", "net8.0-windows")
|
||||
]
|
||||
),
|
||||
new(
|
||||
"civil3d",
|
||||
[
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2022", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2023", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2025", "net8.0-windows")
|
||||
]
|
||||
),
|
||||
new(
|
||||
"tekla-structures",
|
||||
[
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
|
||||
]
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
+4
-1
@@ -150,7 +150,10 @@ Target(
|
||||
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 {s} -c Release --no-restore -p:Version={version} -p:FileVersion={fileVersion} -v:m");
|
||||
Run(
|
||||
"dotnet",
|
||||
$"build {s} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ public static class Solutions
|
||||
|
||||
CheckAndRemoveKnown("Speckle.Objects");
|
||||
CheckAndRemoveKnown("Speckle.Sdk");
|
||||
CheckAndRemoveKnown("Speckle.Sdk.Dependencies");
|
||||
if (localProjects.Count != 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
|
||||
+10
-23
@@ -16,18 +16,16 @@
|
||||
},
|
||||
"Microsoft.Build": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.10.4, )",
|
||||
"resolved": "17.10.4",
|
||||
"contentHash": "ZmGA8vhVXFzC4oo48ybQKlEybVKd0Ntfdr+Enqrn5ES1R6e/krIK9hLk0W33xuT0/G6QYd3YdhJZh+Xle717Ag==",
|
||||
"requested": "[17.11.4, )",
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "UMC7DfeFEHY2GGHHaghybUuUlLaByFHEFudR2PehMgDBuRuLAUePp1iaa4eFtVzepRzMtIbeSCVJCzzX3NV2Gg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Framework": "17.10.4",
|
||||
"Microsoft.NET.StringTools": "17.10.4",
|
||||
"Microsoft.Build.Framework": "17.11.4",
|
||||
"Microsoft.NET.StringTools": "17.11.4",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Configuration.ConfigurationManager": "8.0.0",
|
||||
"System.Reflection.Metadata": "8.0.0",
|
||||
"System.Reflection.MetadataLoadContext": "8.0.0",
|
||||
"System.Security.Principal.Windows": "5.0.0",
|
||||
"System.Threading.Tasks.Dataflow": "8.0.0"
|
||||
"System.Reflection.MetadataLoadContext": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
@@ -69,8 +67,8 @@
|
||||
},
|
||||
"Microsoft.Build.Framework": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.10.4",
|
||||
"contentHash": "4qXCwNOXBR1dyCzuks9SwTwFJQO/xmf2wcMislotDWJu7MN/r3xDNoU8Ae5QmKIHPaLG1xmfDkYS7qBVzxmeKw=="
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "u28uDihlqxtt8h2dL1ZJOZ7TRkxBK+HGr+3FgQpILVo7Q7gErkw8mYW9R+RM5PtxvZTdYb/4MWDL66vdIsANBQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
@@ -79,8 +77,8 @@
|
||||
},
|
||||
"Microsoft.NET.StringTools": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.10.4",
|
||||
"contentHash": "wyABaqY+IHCMMSTQmcc3Ca6vbmg5BaEPgicnEgpll+4xyWZWlkQqUwafweUd9VAhBb4jqplMl6voUHQ6yfdUcg=="
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "mudqUHhNpeqIdJoUx2YDWZO/I9uEDYVowan89R6wsomfnUJQk6HteoQTlNjZDixhT2B4IXMkMtgZtoceIjLRmA=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
|
||||
"type": "Transitive",
|
||||
@@ -132,17 +130,6 @@
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg=="
|
||||
},
|
||||
"System.Security.Principal.Windows": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "7V0I8tPa9V7UxMx/+7DIwkhls5ouaEMQx6l/GwGm1Y8kJQ61On9B/PxCXFLbgu5/C47g0BP2CUYs+nMv1+Oaqw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Converters.ArcGIS3;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Converters.Common;
|
||||
@@ -50,10 +49,6 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1024
|
||||
public List<ICardSetting> GetReceiveSettings() => [];
|
||||
#pragma warning restore CA1024
|
||||
|
||||
public async Task Receive(string modelCardId)
|
||||
{
|
||||
try
|
||||
@@ -81,23 +76,19 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
|
||||
Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
);
|
||||
await Commands
|
||||
.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -109,7 +100,7 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
@@ -7,11 +8,13 @@ namespace Speckle.Connectors.ArcGIS.Bindings;
|
||||
|
||||
public class ArcGISSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public ArcGISSelectionBinding(IBrowserBridge parent)
|
||||
public ArcGISSelectionBinding(IBrowserBridge parent, MapMembersUtils mapMemberUtils)
|
||||
{
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
Parent = parent;
|
||||
var topLevelHandler = parent.TopLevelExceptionHandler;
|
||||
|
||||
@@ -52,14 +55,8 @@ public class ArcGISSelectionBinding : ISelectionBinding
|
||||
List<MapMember> allNestedMembers = new();
|
||||
foreach (MapMember member in selectedMembers)
|
||||
{
|
||||
if (member is GroupLayer group)
|
||||
{
|
||||
GetLayersFromGroup(group, allNestedMembers);
|
||||
}
|
||||
else
|
||||
{
|
||||
allNestedMembers.Add(member);
|
||||
}
|
||||
var layerMapMembers = _mapMemberUtils.UnpackMapLayers(selectedMembers);
|
||||
allNestedMembers.AddRange(layerMapMembers);
|
||||
}
|
||||
|
||||
List<string> objectTypes = allNestedMembers
|
||||
|
||||
@@ -9,6 +9,7 @@ using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.Filters;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
@@ -54,6 +55,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
|
||||
private List<FeatureLayer> SubscribedLayers { get; set; } = new();
|
||||
private List<StandaloneTable> SubscribedTables { get; set; } = new();
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
public ArcGISSendBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -64,7 +66,8 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISSendBinding> logger,
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -76,6 +79,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_logger = logger;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
@@ -89,22 +93,32 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private void SubscribeToArcGISEvents()
|
||||
{
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForLayersRemovedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () => await GetIdsForLayersRemovedEvent(a).ConfigureAwait(false)),
|
||||
true
|
||||
);
|
||||
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForStandaloneTablesRemovedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForStandaloneTablesRemovedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForMapPropertyChangedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapPropertyChangedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForMapMemberPropertiesChangedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapMemberPropertiesChangedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
|
||||
@@ -181,28 +195,31 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
RowCreatedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowChangedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowDeletedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
}
|
||||
|
||||
private void OnRowChanged(RowChangedEventArgs args)
|
||||
private async Task OnRowChanged(RowChangedEventArgs args)
|
||||
{
|
||||
if (args == null || MapView.Active == null)
|
||||
{
|
||||
@@ -241,60 +258,38 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
private async Task GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
{
|
||||
foreach (Layer layer in args.Layers)
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(true);
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
{
|
||||
foreach (StandaloneTable table in args.Tables)
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(true);
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void AddChangedNestedObjectIds(GroupLayer group)
|
||||
private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
{
|
||||
ChangedObjectIds[group.URI] = 1;
|
||||
foreach (var member in group.Layers)
|
||||
foreach (Map map in args.Maps)
|
||||
{
|
||||
if (member is GroupLayer subGroup)
|
||||
{
|
||||
AddChangedNestedObjectIds(subGroup);
|
||||
}
|
||||
else
|
||||
List<MapMember> allMapMembers = _mapMemberUtils.GetAllMapMembers(map);
|
||||
foreach (MapMember member in allMapMembers)
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
{
|
||||
foreach (Map map in args.Maps)
|
||||
{
|
||||
foreach (MapMember member in map.Layers)
|
||||
{
|
||||
if (member is GroupLayer group)
|
||||
{
|
||||
AddChangedNestedObjectIds(group);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersAddedEvent(LayerEventsArgs args)
|
||||
@@ -316,7 +311,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
private void GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
|
||||
private async Task GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
|
||||
{
|
||||
// don't subscribe to all events (e.g. expanding group, changing visibility etc.)
|
||||
bool validEvent = false;
|
||||
@@ -344,7 +339,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +381,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
);
|
||||
List<MapMember> mapMembers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.GetObjectIds()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
@@ -417,13 +412,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
@@ -432,7 +421,9 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -444,7 +435,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +444,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
/// <summary>
|
||||
/// Checks if any sender model cards contain any of the changed objects. If so, also updates the changed objects hashset for each model card - this last part is important for on send change detection.
|
||||
/// </summary>
|
||||
private void RunExpirationChecks(bool idsDeleted)
|
||||
private async Task RunExpirationChecks(bool idsDeleted)
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
List<string> expiredSenderIds = new();
|
||||
@@ -463,9 +454,9 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
|
||||
foreach (SenderModelCard sender in senders)
|
||||
{
|
||||
var objIds = sender.SendFilter.NotNull().GetObjectIds();
|
||||
var objIds = sender.SendFilter.NotNull().RefreshObjectIds();
|
||||
var intersection = objIds.Intersect(objectIdsList).ToList();
|
||||
bool isExpired = sender.SendFilter.NotNull().CheckExpiry(objectIdsList);
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(sender.ModelCardId.NotNull());
|
||||
@@ -479,7 +470,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -59,10 +60,10 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightObjects(List<string> objectIds) =>
|
||||
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList()).ConfigureAwait(false);
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
@@ -75,7 +76,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (model is SenderModelCard senderModelCard)
|
||||
{
|
||||
objectIds = senderModelCard.SendFilter.NotNull().GetObjectIds().Select(x => new ObjectID(x)).ToList();
|
||||
objectIds = senderModelCard.SendFilter.NotNull().RefreshObjectIds().Select(x => new ObjectID(x)).ToList();
|
||||
}
|
||||
|
||||
if (model is ReceiverModelCard receiverModelCard)
|
||||
@@ -87,27 +88,27 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
{
|
||||
return;
|
||||
}
|
||||
HighlightObjectsOnView(objectIds);
|
||||
await HighlightObjectsOnView(objectIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async void HighlightObjectsOnView(List<ObjectID> objectIds)
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
await SelectMapMembersInTOC(mapMembersFeatures).ConfigureAwait(false);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private List<MapMemberFeature> GetMapMembers(List<ObjectID> objectIds, MapView mapView)
|
||||
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
|
||||
{
|
||||
// find the layer on the map (from the objectID) and add the featureID is available
|
||||
List<MapMemberFeature> mapMembersFeatures = new();
|
||||
@@ -145,7 +146,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
MapView.Active.ClearTOCSelection();
|
||||
}
|
||||
|
||||
private void SelectMapMembersAndFeatures(List<MapMemberFeature> mapMembersFeatures)
|
||||
private void SelectMapMembersAndFeatures(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
|
||||
{
|
||||
@@ -170,7 +171,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectMapMembersInTOC(List<MapMemberFeature> mapMembersFeatures)
|
||||
private async Task SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
List<Layer> layers = new();
|
||||
List<StandaloneTable> tables = new();
|
||||
@@ -186,7 +187,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
else
|
||||
{
|
||||
QueuedTask.Run(() => layer.SetExpanded(true));
|
||||
await QueuedTask.Run(() => layer.SetExpanded(true)).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (member is StandaloneTable table)
|
||||
|
||||
+1
-3
@@ -154,7 +154,6 @@
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
return Success;
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
@@ -190,7 +189,7 @@
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "RelativePaths: " + i.ToString());
|
||||
}
|
||||
return true;
|
||||
Success = true;
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
@@ -266,7 +265,6 @@
|
||||
CleanInfo = AssemblyName + extension;
|
||||
}
|
||||
Success = true;
|
||||
return Success;
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Filters;
|
||||
|
||||
public class ArcGISEverythingFilter : EverythingSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => new(); // TODO
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => true;
|
||||
}
|
||||
@@ -4,7 +4,10 @@ namespace Speckle.Connectors.ArcGIS.Filters;
|
||||
|
||||
public class ArcGISSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
public ArcGISSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
public override List<string> RefreshObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Drawing;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Objects;
|
||||
using Speckle.Objects.Other;
|
||||
@@ -55,14 +56,15 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseColors(List<ColorProxy> colorProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseColors(List<ColorProxy> colorProxies, IProgress<CardProgress> onOperationProgressed)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectColorsIdMap = new();
|
||||
var count = 0;
|
||||
foreach (ColorProxy colorProxy in colorProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting colors", (double)++count / colorProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
await Task.Yield();
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value);
|
||||
@@ -76,14 +78,18 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="materialProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseMaterials(List<RenderMaterialProxy> materialProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseMaterials(
|
||||
List<RenderMaterialProxy> materialProxies,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectMaterialsIdMap = new();
|
||||
var count = 0;
|
||||
foreach (RenderMaterialProxy colorProxy in materialProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting materials", (double)++count / materialProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting materials", (double)++count / materialProxies.Count));
|
||||
await Task.Yield();
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value.diffuse);
|
||||
@@ -310,6 +316,11 @@ public class ArcGISColorManager
|
||||
int count = 1;
|
||||
using (RowCursor rowCursor = layer.Search())
|
||||
{
|
||||
// if layer doesn't have a valid data source (and the conversion likely failed), don't create a colorProxy
|
||||
if (rowCursor is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
string elementAppId = $"{layer.URI}_{count}";
|
||||
@@ -445,6 +456,11 @@ public class ArcGISColorManager
|
||||
out int color
|
||||
)
|
||||
{
|
||||
if (uniqueRenderer.DefaultSymbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(uniqueRenderer.DefaultSymbol.Symbol, out color)) // get default color
|
||||
{
|
||||
return false;
|
||||
@@ -487,6 +503,11 @@ public class ArcGISColorManager
|
||||
// set the group color to class symbol color if conditions are met
|
||||
if (groupConditionsMet)
|
||||
{
|
||||
if (groupClass.Symbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(groupClass.Symbol.Symbol, out color))
|
||||
{
|
||||
return false;
|
||||
@@ -538,6 +559,11 @@ public class ArcGISColorManager
|
||||
out int color
|
||||
)
|
||||
{
|
||||
if (graduatedRenderer.DefaultSymbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(graduatedRenderer.DefaultSymbol.Symbol, out color)) // get default color
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp;
|
||||
|
||||
public class SyncToQueuedTask : ISyncToThread
|
||||
{
|
||||
public Task<T> RunOnThread<T>(Func<T> func) => QueuedTask.Run(func);
|
||||
}
|
||||
+80
-69
@@ -62,7 +62,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -70,7 +70,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
|
||||
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// get materials
|
||||
List<RenderMaterialProxy>? materials = (rootObject[ProxyKeys.RENDER_MATERIAL] as List<object>)
|
||||
@@ -78,14 +78,14 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
.ToList();
|
||||
if (materials != null)
|
||||
{
|
||||
_colorManager.ParseMaterials(materials, onOperationProgressed);
|
||||
await _colorManager.ParseMaterials(materials, onOperationProgressed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// get colors
|
||||
List<ColorProxy>? colors = (rootObject[ProxyKeys.COLOR] as List<object>)?.Cast<ColorProxy>().ToList();
|
||||
if (colors != null)
|
||||
{
|
||||
_colorManager.ParseColors(colors, onOperationProgressed);
|
||||
await _colorManager.ParseColors(colors, onOperationProgressed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@@ -125,24 +125,32 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
results.Add(new(Status.ERROR, obj, null, null, ex));
|
||||
}
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / objectsToConvert.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / objectsToConvert.Count));
|
||||
}
|
||||
|
||||
// 2.1. Group conversionTrackers (to write into datasets)
|
||||
onOperationProgressed?.Invoke("Grouping features into layers", null);
|
||||
onOperationProgressed.Report(new("Grouping features into layers", null));
|
||||
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups = await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
return _featureClassUtils.GroupConversionTrackers(conversionTracker, onOperationProgressed);
|
||||
return await _featureClassUtils
|
||||
.GroupConversionTrackers(conversionTracker, (s, progres) => onOperationProgressed.Report(new(s, progres)))
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// 2.2. Write groups of objects to Datasets
|
||||
onOperationProgressed?.Invoke("Writing to Database", null);
|
||||
onOperationProgressed.Report(new("Writing to Database", null));
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
_featureClassUtils.CreateDatasets(conversionTracker, convertedGroups, onOperationProgressed);
|
||||
await _featureClassUtils
|
||||
.CreateDatasets(
|
||||
conversionTracker,
|
||||
convertedGroups,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
@@ -153,7 +161,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
int bakeCount = 0;
|
||||
Dictionary<string, (MapMember, CIMUniqueValueRenderer?)> bakedMapMembers = new();
|
||||
onOperationProgressed?.Invoke("Adding to Map", bakeCount);
|
||||
onOperationProgressed.Report(new("Adding to Map", bakeCount));
|
||||
|
||||
foreach (var item in conversionTracker)
|
||||
{
|
||||
@@ -215,7 +223,8 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
// add report item
|
||||
AddResultsFromTracker(trackerItem, results);
|
||||
}
|
||||
onOperationProgressed?.Invoke("Adding to Map", (double)++bakeCount / conversionTracker.Count);
|
||||
|
||||
onOperationProgressed.Report(new("Adding to Map", (double)++bakeCount / conversionTracker.Count));
|
||||
}
|
||||
|
||||
// apply renderers to baked layers
|
||||
@@ -295,78 +304,80 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
}
|
||||
|
||||
private Task<MapMember> AddDatasetsToMap(
|
||||
private async Task<MapMember> AddDatasetsToMap(
|
||||
ObjectConversionTracker trackerItem,
|
||||
Dictionary<string, GroupLayer> createdLayerGroups,
|
||||
string projectName,
|
||||
string modelName
|
||||
)
|
||||
{
|
||||
return QueuedTask.Run(() =>
|
||||
{
|
||||
// get layer details
|
||||
string? datasetId = trackerItem.DatasetId; // should not be null here
|
||||
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
|
||||
string nestedLayerName = trackerItem.NestedLayerName;
|
||||
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
return await QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = _settingsStore.Current.Map;
|
||||
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
|
||||
mainGroupLayer.SetExpanded(true);
|
||||
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
|
||||
}
|
||||
// get layer details
|
||||
string? datasetId = trackerItem.DatasetId; // should not be null here
|
||||
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
|
||||
string nestedLayerName = trackerItem.NestedLayerName;
|
||||
|
||||
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
|
||||
// Most of the Speckle-written datasets will be containing geometry and added as Layers
|
||||
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
|
||||
// We can create a connection to the dataset in advance and determine its type, but this will be more
|
||||
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
|
||||
try
|
||||
{
|
||||
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
{
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
Map map = _settingsStore.Current.Map;
|
||||
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
|
||||
mainGroupLayer.SetExpanded(true);
|
||||
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
// if Scene
|
||||
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
|
||||
if (_settingsStore.Current.Map.IsScene)
|
||||
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
|
||||
|
||||
// Most of the Speckle-written datasets will be containing geometry and added as Layers
|
||||
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
|
||||
// We can create a connection to the dataset in advance and determine its type, but this will be more
|
||||
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
|
||||
try
|
||||
{
|
||||
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
|
||||
var layerElevationSurface = new CIMLayerElevationSurface
|
||||
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
{
|
||||
ElevationSurfaceLayerURI = groundSurfaceLayer.URI,
|
||||
};
|
||||
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
}
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
return (MapMember)layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
});
|
||||
// if Scene
|
||||
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
|
||||
if (_settingsStore.Current.Map.IsScene)
|
||||
{
|
||||
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
|
||||
var layerElevationSurface = new CIMLayerElevationSurface
|
||||
{
|
||||
ElevationSurfaceLayerURI = groundSurfaceLayer.URI,
|
||||
};
|
||||
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
}
|
||||
}
|
||||
|
||||
return (MapMember)layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary<string, GroupLayer> createdLayerGroups)
|
||||
|
||||
+7
-7
@@ -57,7 +57,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
#pragma warning restore CA1506
|
||||
IReadOnlyList<MapMember> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
|
||||
List<SendConversionResult> results = new(objects.Count);
|
||||
var cacheHitCount = 0;
|
||||
List<(GroupLayer, Collection)> nestedGroups = new();
|
||||
List<(ILayerContainer, Collection)> nestedGroups = new();
|
||||
|
||||
// reorder selected layers by Table of Content (TOC) order
|
||||
List<(MapMember, int)> layersWithDisplayPriority = _mapMemberUtils.GetLayerDisplayPriority(
|
||||
@@ -79,7 +79,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
objects
|
||||
);
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using (var __ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
foreach ((MapMember mapMember, _) in layersWithDisplayPriority)
|
||||
@@ -112,7 +112,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
|
||||
// don't use cache for group layers
|
||||
if (
|
||||
mapMember is not GroupLayer
|
||||
mapMember is not ILayerContainer
|
||||
&& _sendConversionCache.TryGetValue(sendInfo.ProjectId, applicationId, out ObjectReference? value)
|
||||
)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mapMember is GroupLayer group)
|
||||
if (mapMember is ILayerContainer group)
|
||||
{
|
||||
// group layer will always come before it's contained layers
|
||||
// keep active group last in the list
|
||||
@@ -183,13 +183,13 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
}
|
||||
}
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / objects.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / objects.Count));
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// POC: Add Color Proxies
|
||||
|
||||
@@ -5,18 +5,15 @@ using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
public class ArcGISDocumentStore : DocumentModelStore
|
||||
{
|
||||
public ArcGISDocumentStore(
|
||||
JsonSerializerSettings serializerOption,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(serializerOption, true)
|
||||
public ArcGISDocumentStore(IJsonSerializer jsonSerializer, ITopLevelExceptionHandler topLevelExceptionHandler)
|
||||
: base(jsonSerializer, true)
|
||||
{
|
||||
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
|
||||
ProjectSavingEvent.Subscribe(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using ArcGIS.Desktop.Internal.Mapping;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
@@ -28,21 +27,13 @@ public class MapMembersUtils
|
||||
List<MapMember> mapMembers = new();
|
||||
foreach (var layer in mapMembersToUnpack)
|
||||
{
|
||||
mapMembers.Add(layer);
|
||||
switch (layer)
|
||||
{
|
||||
case GroupLayer subGroup:
|
||||
mapMembers.Add(layer);
|
||||
var subGroupMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subGroupMapMembers);
|
||||
break;
|
||||
case ILayerContainerInternal subLayerContainerInternal:
|
||||
mapMembers.Add(layer);
|
||||
var subLayerMapMembers = UnpackMapLayers(subLayerContainerInternal.InternalLayers);
|
||||
case ILayerContainer subGroup:
|
||||
var subLayerMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subLayerMapMembers);
|
||||
break;
|
||||
default:
|
||||
mapMembers.Add(layer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -88,17 +93,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -127,11 +132,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -161,24 +161,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -244,8 +226,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -253,7 +236,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -278,7 +262,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -290,6 +274,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -310,31 +300,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -83,17 +91,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -122,11 +130,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -156,24 +159,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -308,7 +295,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -320,6 +307,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -346,31 +339,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -83,17 +91,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -122,11 +130,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -156,24 +159,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -308,7 +295,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -320,6 +307,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -346,31 +339,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -83,17 +91,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -122,11 +130,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -156,24 +159,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -309,7 +296,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -321,6 +308,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -347,31 +340,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -82,17 +82,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -121,11 +121,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -155,24 +150,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -238,8 +215,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -247,7 +225,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -273,7 +252,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -285,6 +264,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -311,31 +296,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
+63
-57
@@ -37,10 +37,10 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -72,17 +72,17 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightObjects(List<string> objectIds)
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
|
||||
var dbObjects = doc.GetObjects(objectIds);
|
||||
var acadObjectIds = dbObjects.Select(tuple => tuple.Root.Id).ToArray();
|
||||
HighlightObjectsOnView(acadObjectIds);
|
||||
await HighlightObjectsOnView(acadObjectIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
@@ -104,7 +104,7 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (model is SenderModelCard senderModelCard)
|
||||
{
|
||||
var dbObjects = doc.GetObjects(senderModelCard.SendFilter.NotNull().GetObjectIds());
|
||||
var dbObjects = doc.GetObjects(senderModelCard.SendFilter.NotNull().RefreshObjectIds());
|
||||
objectIds = dbObjects.Select(tuple => tuple.Root.Id).ToArray();
|
||||
}
|
||||
|
||||
@@ -116,72 +116,78 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds.Length == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(objectIds, modelCardId);
|
||||
await HighlightObjectsOnView(objectIds, modelCardId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void HighlightObjectsOnView(ObjectId[] objectIds, string? modelCardId = null)
|
||||
private async Task HighlightObjectsOnView(ObjectId[] objectIds, string? modelCardId = null)
|
||||
{
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
|
||||
Parent.RunOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(Array.Empty<ObjectId>()); // Deselects
|
||||
try
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(objectIds);
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// SWALLOW REASON:
|
||||
// If the objects under the blocks, it won't be able to select them.
|
||||
// If we try, API will throw the invalid input error, because we request something from API that Autocad doesn't
|
||||
// handle it on its current canvas. Block elements only selectable when in its scope.
|
||||
}
|
||||
doc.Editor.UpdateScreen();
|
||||
|
||||
Extents3d selectedExtents = new();
|
||||
|
||||
var tr = doc.TransactionManager.StartTransaction();
|
||||
foreach (ObjectId objectId in objectIds)
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(Array.Empty<ObjectId>()); // Deselects
|
||||
try
|
||||
{
|
||||
var entity = (Entity?)tr.GetObject(objectId, OpenMode.ForRead);
|
||||
if (entity?.GeometricExtents != null)
|
||||
{
|
||||
selectedExtents.AddExtents(entity.GeometricExtents);
|
||||
}
|
||||
doc.Editor.SetImpliedSelection(objectIds);
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// Note: we're swallowing exeptions here because of a weird case when receiving blocks, we would have
|
||||
// acad api throw an error on accessing entity.GeometricExtents.
|
||||
// SWALLOW REASON:
|
||||
// If the objects under the blocks, it won't be able to select them.
|
||||
// If we try, API will throw the invalid input error, because we request something from API that Autocad doesn't
|
||||
// handle it on its current canvas. Block elements only selectable when in its scope.
|
||||
}
|
||||
doc.Editor.UpdateScreen();
|
||||
|
||||
Extents3d selectedExtents = new();
|
||||
|
||||
var tr = doc.TransactionManager.StartTransaction();
|
||||
foreach (ObjectId objectId in objectIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = (Entity?)tr.GetObject(objectId, OpenMode.ForRead);
|
||||
if (entity?.GeometricExtents != null)
|
||||
{
|
||||
selectedExtents.AddExtents(entity.GeometricExtents);
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// Note: we're swallowing exeptions here because of a weird case when receiving blocks, we would have
|
||||
// acad api throw an error on accessing entity.GeometricExtents.
|
||||
}
|
||||
}
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
if (modelCardId != null)
|
||||
{
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("Failed to highlight objects."))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will happen, in some cases, where we highlight individual objects. Should be caught by the top level handler and not
|
||||
// crash the host app.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
if (modelCardId != null)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("Failed to highlight objects."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will happen, in some cases, where we highlight individual objects. Should be caught by the top level handler and not
|
||||
// crash the host app.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-15
@@ -7,7 +7,6 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
@@ -51,10 +50,6 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1024
|
||||
public List<ICardSetting> GetReceiveSettings() => [];
|
||||
#pragma warning restore CA1024
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId)
|
||||
@@ -84,18 +79,14 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelReceiveResult(modelCardId, operationResults.BakedObjectIds, operationResults.ConversionResults);
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, operationResults.BakedObjectIds, operationResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -107,7 +98,7 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
+5
-3
@@ -41,7 +41,9 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
if (!_visitedDocuments.Contains(document))
|
||||
{
|
||||
document.ImpliedSelectionChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => Parent.RunOnMainThread(OnSelectionChanged));
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await Parent.RunOnMainThreadAsync(OnSelectionChanged).ConfigureAwait(false)
|
||||
);
|
||||
|
||||
_visitedDocuments.Add(document);
|
||||
}
|
||||
@@ -52,10 +54,10 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
// Ui requests to GetSelection() should just return this local copy that is kept up to date by the event handler.
|
||||
private SelectionInfo _selectionInfo;
|
||||
|
||||
private void OnSelectionChanged()
|
||||
private async Task OnSelectionChanged()
|
||||
{
|
||||
_selectionInfo = GetSelectionInternal();
|
||||
Parent.Send(SELECTION_EVENT, _selectionInfo);
|
||||
await Parent.Send(SELECTION_EVENT, _selectionInfo).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection() => _selectionInfo;
|
||||
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
{
|
||||
public string Name => "sendBinding";
|
||||
public SendBindingUICommands Commands { get; }
|
||||
private OperationProgressManager OperationProgressManager { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAutocadIdleManager _idleManager;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
/// [CNX-202: Unhandled Exception Occurred when receiving in Rhino](https://linear.app/speckle/issue/CNX-202/unhandled-exception-occurred-when-receiving-in-rhino)
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
protected AutocadSendBaseBinding(
|
||||
DocumentModelStore store,
|
||||
IAutocadIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
CancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
|
||||
Application.DocumentManager.DocumentActivated += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => SubscribeToObjectChanges(args.Document));
|
||||
|
||||
if (Application.DocumentManager.CurrentDocument != null)
|
||||
{
|
||||
// catches the case when autocad just opens up with a blank new doc
|
||||
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
|
||||
}
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_docSubsTracker.Add(doc.Name);
|
||||
doc.Database.ObjectAppended += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectErased += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject)
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
}
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(AutocadSendBinding),
|
||||
async () => await RunExpirationChecks().ConfigureAwait(false)
|
||||
);
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
List<string> expiredSenderIds = new();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().RefreshObjectIds().Intersect(objectIdsList).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(modelCard.ModelCardId.NotNull());
|
||||
}
|
||||
}
|
||||
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () => await SendInternal(modelCardId).ConfigureAwait(false))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
private async Task SendInternal(string modelCardId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No publish model card was found.");
|
||||
}
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
InitializeSettings(scope.ServiceProvider);
|
||||
|
||||
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Get elements to convert
|
||||
List<AutocadRootObject> autocadObjects = Application.DocumentManager.CurrentDocument.GetObjects(
|
||||
modelCard.SendFilter.NotNull().RefreshObjectIds()
|
||||
);
|
||||
|
||||
if (autocadObjects.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// renable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
+17
-187
@@ -1,54 +1,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public sealed class AutocadSendBinding : ISendBinding
|
||||
public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
{
|
||||
public string Name => "sendBinding";
|
||||
public SendBindingUICommands Commands { get; }
|
||||
private OperationProgressManager OperationProgressManager { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAutocadIdleManager _idleManager;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
/// [CNX-202: Unhandled Exception Occurred when receiving in Rhino](https://linear.app/speckle/issue/CNX-202/unhandled-exception-occurred-when-receiving-in-rhino)
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
public AutocadSendBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -63,163 +30,26 @@ public sealed class AutocadSendBinding : ISendBinding
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
idleManager,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
|
||||
Application.DocumentManager.DocumentActivated += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => SubscribeToObjectChanges(args.Document));
|
||||
|
||||
if (Application.DocumentManager.CurrentDocument != null)
|
||||
{
|
||||
// catches the case when autocad just opens up with a blank new doc
|
||||
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
|
||||
}
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_docSubsTracker.Add(doc.Name);
|
||||
doc.Database.ObjectAppended += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectErased += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject)
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
}
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void RunExpirationChecks()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
List<string> expiredSenderIds = new();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().GetObjectIds().Intersect(objectIdsList).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(modelCard.ModelCardId.NotNull());
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public Task Send(string modelCardId)
|
||||
{
|
||||
Parent.RunOnMainThread(async () => await SendInternal(modelCardId).ConfigureAwait(false));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task SendInternal(string modelCardId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No publish model card was found.");
|
||||
}
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Get elements to convert
|
||||
List<AutocadRootObject> autocadObjects = Application.DocumentManager.CurrentDocument.GetObjects(
|
||||
modelCard.SendFilter.NotNull().GetObjectIds()
|
||||
);
|
||||
|
||||
if (autocadObjects.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// renable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
|
||||
+14
-1
@@ -1,5 +1,11 @@
|
||||
#if AUTOCAD
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.DependencyInjection;
|
||||
|
||||
@@ -9,9 +15,16 @@ public static class AutocadConnectorModule
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
|
||||
// Operations
|
||||
// Send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, AutocadRootObjectBuilder>();
|
||||
|
||||
// Receive
|
||||
serviceCollection.LoadReceive();
|
||||
|
||||
// Register vertical specific bindings
|
||||
serviceCollection.AddSingleton<IBinding, AutocadSendBinding>();
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+5
@@ -1,5 +1,7 @@
|
||||
#if CIVIL3D
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.DependencyInjection;
|
||||
|
||||
@@ -8,7 +10,10 @@ public static class Civil3dConnectorModule
|
||||
public static void AddCivil3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
|
||||
// send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-7
@@ -12,6 +12,7 @@ using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
@@ -49,7 +50,7 @@ public static class SharedRegistration
|
||||
serviceCollection.AddScoped<AutocadMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<AutocadMaterialBaker>();
|
||||
|
||||
serviceCollection.AddSingleton<IAutocadIdleManager, AutocadIdleManager>();
|
||||
serviceCollection.AddSingleton<IAppIdleManager, AutocadIdleManager>();
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
@@ -70,12 +71,6 @@ public static class SharedRegistration
|
||||
// Operations
|
||||
serviceCollection.AddScoped<SendOperation<AutocadRootObject>>();
|
||||
|
||||
// Object Builders
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, AutocadRootObjectBuilder>();
|
||||
|
||||
// Register bindings
|
||||
serviceCollection.AddSingleton<IBinding, AutocadSendBinding>();
|
||||
|
||||
// register send filters
|
||||
serviceCollection.AddTransient<ISendFilter, AutocadSelectionFilter>();
|
||||
|
||||
|
||||
+5
-2
@@ -4,7 +4,10 @@ namespace Speckle.Connectors.Autocad.Filters;
|
||||
|
||||
public class AutocadSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
public AutocadSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
public override List<string> RefreshObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Autodesk.AutoCAD.Colors;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
@@ -28,14 +29,17 @@ public class AutocadColorBaker
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseColors(List<ColorProxy> colorProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseColors(
|
||||
IReadOnlyCollection<ColorProxy> colorProxies,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
var count = 0;
|
||||
foreach (ColorProxy colorProxy in colorProxies)
|
||||
{
|
||||
try
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting colors", (double)++count / colorProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
|
||||
// skip any colors with source = layer, since object color default source is by layer
|
||||
if (colorProxy["source"] is string source && source == "layer")
|
||||
@@ -60,6 +64,8 @@ public class AutocadColorBaker
|
||||
{
|
||||
_logger.LogError(ex, "Failed parsing color proxy");
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
@@ -12,11 +12,11 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
private readonly AutocadDocumentManager _autocadDocumentManager;
|
||||
|
||||
public AutocadDocumentStore(
|
||||
JsonSerializerSettings jsonSerializerSettings,
|
||||
IJsonSerializer jsonSerializer,
|
||||
AutocadDocumentManager autocadDocumentManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(jsonSerializerSettings, true)
|
||||
: base(jsonSerializer, true)
|
||||
{
|
||||
_autocadDocumentManager = autocadDocumentManager;
|
||||
_previousDocName = _nullDocumentName;
|
||||
|
||||
@@ -3,23 +3,20 @@ using Speckle.InterfaceGenerator;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
|
||||
public partial interface IAutocadIdleManager : IAppIdleManager;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public class AutocadIdleManager(IIdleCallManager idleCallManager) : IAutocadIdleManager
|
||||
public sealed class AutocadIdleManager(IIdleCallManager idleCallManager)
|
||||
: AppIdleManager(idleCallManager),
|
||||
IAutocadIdleManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscribe deferred action to AutocadIdle event to run it whenever Autocad become idle.
|
||||
/// </summary>
|
||||
/// <param name="action"> Action to call whenever Autocad become Idle.</param>
|
||||
public void SubscribeToIdle(string id, Action action) =>
|
||||
idleCallManager.SubscribeToIdle(
|
||||
id,
|
||||
action,
|
||||
() =>
|
||||
{
|
||||
Application.Idle += AutocadAppOnIdle;
|
||||
}
|
||||
);
|
||||
private readonly IIdleCallManager _idleCallManager = idleCallManager;
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
Application.Idle += AutocadAppOnIdle;
|
||||
}
|
||||
|
||||
private void AutocadAppOnIdle(object? sender, EventArgs e) =>
|
||||
idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
|
||||
_idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
|
||||
}
|
||||
|
||||
+10
-4
@@ -1,14 +1,17 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
@@ -45,11 +48,12 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
_converterSettings = converterSettings;
|
||||
}
|
||||
|
||||
public BakeResult BakeInstances(
|
||||
List<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
[SuppressMessage("Maintainability", "CA1506:Avoid excessive class coupling")]
|
||||
public async Task<BakeResult> BakeInstances(
|
||||
IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
Dictionary<string, List<Entity>> applicationIdMap,
|
||||
string baseLayerName,
|
||||
Action<string, double?>? onOperationProgressed
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
var sortedInstanceComponents = instanceComponents
|
||||
@@ -69,7 +73,8 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
{
|
||||
try
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting blocks", (double)++count / sortedInstanceComponents.Count);
|
||||
onOperationProgressed.Report(new("Converting blocks", (double)++count / sortedInstanceComponents.Count));
|
||||
|
||||
if (instanceOrDefinition is InstanceDefinitionProxy { applicationId: not null } definitionProxy)
|
||||
{
|
||||
// TODO: create definition (block table record)
|
||||
@@ -162,6 +167,7 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
await Task.Yield();
|
||||
return new(createdObjectIds, consumedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
@@ -19,14 +19,12 @@ public class AutocadLayerUnpacker
|
||||
}
|
||||
if (tr.GetObject(entity.LayerId, OpenMode.ForRead) is LayerTableRecord autocadLayer)
|
||||
{
|
||||
// Layers and geometries can have same application ids.....
|
||||
// We should prevent it for sketchup converter. Because when it happens "objects_to_bake" definition
|
||||
// is changing on the way if it happens.
|
||||
speckleLayer = new Layer(layerName) { applicationId = autocadLayer.GetSpeckleApplicationId() }; // Do not use handle directly, see note in the 'GetSpeckleApplicationId' method
|
||||
_layerCollectionCache[layerName] = speckleLayer;
|
||||
layer = autocadLayer;
|
||||
return speckleLayer;
|
||||
}
|
||||
throw new SpeckleConversionException("Unexpected condition in GetOrCreateSpeckleLayer");
|
||||
|
||||
throw new SpeckleException("Unexpected condition in GetOrCreateSpeckleLayer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.GraphicsInterface;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
@@ -90,10 +91,10 @@ public class AutocadMaterialBaker
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
public void ParseAndBakeRenderMaterials(
|
||||
public async Task ParseAndBakeRenderMaterials(
|
||||
List<RenderMaterialProxy> materialProxies,
|
||||
string baseLayerPrefix,
|
||||
Action<string, double?>? onOperationProgressed
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
using var transaction = Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
||||
@@ -109,7 +110,7 @@ public class AutocadMaterialBaker
|
||||
var count = 0;
|
||||
foreach (RenderMaterialProxy materialProxy in materialProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting render materials", (double)++count / materialProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting render materials", (double)++count / materialProxies.Count));
|
||||
|
||||
// bake render material
|
||||
RenderMaterial renderMaterial = materialProxy.value;
|
||||
@@ -139,6 +140,7 @@ public class AutocadMaterialBaker
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
private (ObjectId, ReceiveConversionResult) BakeMaterial(
|
||||
|
||||
+9
-5
@@ -70,7 +70,7 @@ public class AutocadMaterialUnpacker
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: make sure we collect layer colors as well
|
||||
// Stage 2: make sure we collect layer materials as well
|
||||
foreach (LayerTableRecord layer in layers)
|
||||
{
|
||||
try
|
||||
@@ -110,10 +110,14 @@ public class AutocadMaterialUnpacker
|
||||
diffuseColor.Blue
|
||||
);
|
||||
|
||||
string name = material.Name;
|
||||
double opacity = material.Opacity.Percentage;
|
||||
|
||||
RenderMaterial renderMaterial = new(opacity: opacity, diffuse: diffuse) { name = name, applicationId = id };
|
||||
RenderMaterial renderMaterial =
|
||||
new()
|
||||
{
|
||||
name = material.Name,
|
||||
opacity = material.Opacity.Percentage,
|
||||
diffuse = diffuse.ToArgb(),
|
||||
applicationId = id
|
||||
};
|
||||
|
||||
// Add additional properties
|
||||
renderMaterial["ior"] = material.Refraction.Index;
|
||||
|
||||
+104
-94
@@ -52,118 +52,127 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
}
|
||||
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
public async Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken _
|
||||
) =>
|
||||
)
|
||||
{
|
||||
// NOTE: This is the only place we apply ISyncToThread across connectors. We need to sync up with main thread here
|
||||
// after GetObject and Deserialization. It is anti-pattern now. Happiness level 3/10 but works.
|
||||
_syncToThread.RunOnThread(() =>
|
||||
return await _syncToThread
|
||||
.RunOnThread(
|
||||
async () => await BuildImpl(rootObject, projectName, modelName, onOperationProgressed).ConfigureAwait(false)
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<HostObjectBuilderResult> BuildImpl(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// Layer filter for received commit with project and model name
|
||||
_layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 0 - Clean then Rock n Roll!
|
||||
string baseLayerPrefix = _autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
PreReceiveDeepClean(baseLayerPrefix);
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
);
|
||||
var atomicObjectsWithPath = _layerBaker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = _layerBaker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
|
||||
// POC: these are not captured by traversal, so we need to re-add them here
|
||||
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
|
||||
{
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
|
||||
// Layer filter for received commit with project and model name
|
||||
_layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 0 - Clean then Rock n Roll!
|
||||
string baseLayerPrefix = _autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
PreReceiveDeepClean(baseLayerPrefix);
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
);
|
||||
var atomicObjectsWithPath = _layerBaker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = _layerBaker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// POC: these are not captured by traversal, so we need to re-add them here
|
||||
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
await _materialBaker
|
||||
.ParseAndBakeRenderMaterials(unpackedRoot.RenderMaterialProxies, baseLayerPrefix, onOperationProgressed)
|
||||
.ConfigureAwait(true);
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
await _colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
List<ReceiveConversionResult> results = new();
|
||||
List<string> bakedObjectIds = new();
|
||||
Dictionary<string, List<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id;
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
try
|
||||
{
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
List<Entity> convertedObjects = await ConvertObject(atomicObject, layerPath, baseLayerPrefix)
|
||||
.ConfigureAwait(true);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.AddRange(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
bakedObjectIds.AddRange(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_materialBaker.ParseAndBakeRenderMaterials(
|
||||
unpackedRoot.RenderMaterialProxies,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
_colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
// 6 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker
|
||||
.BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerPrefix, onOperationProgressed)
|
||||
.ConfigureAwait(true);
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
List<ReceiveConversionResult> results = new();
|
||||
List<string> bakedObjectIds = new();
|
||||
Dictionary<string, List<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id;
|
||||
onOperationProgressed?.Invoke("Converting objects", (double)++count / atomicObjects.Count);
|
||||
try
|
||||
{
|
||||
List<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix).ToList();
|
||||
bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.AddRange(createdInstanceIds);
|
||||
results.RemoveAll(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.AddRange(instanceConversionResults);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.AddRange(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
|
||||
bakedObjectIds.AddRange(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
// 6 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
// 7 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
List<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.AddRange(groupResults);
|
||||
}
|
||||
|
||||
bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.AddRange(createdInstanceIds);
|
||||
results.RemoveAll(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.AddRange(instanceConversionResults);
|
||||
|
||||
// 7 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
List<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.AddRange(groupResults);
|
||||
}
|
||||
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
});
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
@@ -172,7 +181,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
_materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
}
|
||||
|
||||
private IEnumerable<Entity> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
private async Task<List<Entity>> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
{
|
||||
string layerName = _layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
var convertedEntities = new List<Entity>();
|
||||
@@ -195,6 +204,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
await Task.Delay(10).ConfigureAwait(true);
|
||||
return convertedEntities;
|
||||
}
|
||||
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly AutocadInstanceUnpacker _instanceUnpacker;
|
||||
private readonly AutocadMaterialUnpacker _materialUnpacker;
|
||||
private readonly AutocadColorUnpacker _colorUnpacker;
|
||||
private readonly AutocadGroupUnpacker _groupUnpacker;
|
||||
private readonly ILogger<AutocadRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
|
||||
protected AutocadRootObjectBaseBuilder(
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_instanceUnpacker = instanceObjectManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_groupUnpacker = groupUnpacker;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
) => Task.FromResult(BuildSync(objects, sendInfo, onOperationProgressed, ct));
|
||||
|
||||
[SuppressMessage(
|
||||
"Maintainability",
|
||||
"CA1506:Avoid excessive class coupling",
|
||||
Justification = """
|
||||
It is already simplified but has many different references since it is a builder. Do not know can we simplify it now.
|
||||
Later we might consider to refactor proxies from one proxy manager? but we do not know the shape of it all potential
|
||||
proxy classes yet. So I'm supressing this one now!!!
|
||||
"""
|
||||
)]
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
// 0 - Init the root
|
||||
Collection root =
|
||||
new()
|
||||
{
|
||||
name = Application
|
||||
.DocumentManager.CurrentDocument.Name // POC: https://spockle.atlassian.net/browse/CNX-9319
|
||||
.Split(_documentPathSeparator, StringSplitOptions.None)
|
||||
.Reverse()
|
||||
.First()
|
||||
};
|
||||
|
||||
// TODO: better handling for document and transactions!!
|
||||
Document doc = Application.DocumentManager.CurrentDocument;
|
||||
using Transaction tr = doc.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1 - Unpack the instances
|
||||
var (atomicObjects, instanceProxies, instanceDefinitionProxies) = _instanceUnpacker.UnpackSelection(objects);
|
||||
root[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies;
|
||||
|
||||
// 2 - Unpack the groups
|
||||
root[ProxyKeys.GROUP] = _groupUnpacker.UnpackGroups(atomicObjects);
|
||||
using (var _ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
// 3 - Convert atomic objects
|
||||
List<LayerTableRecord> usedAcadLayers = new(); // Keeps track of autocad layers used, so we can pass them on later to the material and color unpacker.
|
||||
List<SendConversionResult> results = new();
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
// Create and add a collection for this entity if not done so already.
|
||||
(Collection objectCollection, LayerTableRecord? autocadLayer) = CreateObjectCollection(entity, tr);
|
||||
|
||||
if (autocadLayer is not null)
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(objectCollection);
|
||||
}
|
||||
|
||||
var result = ConvertAutocadEntity(
|
||||
entity,
|
||||
applicationId,
|
||||
objectCollection,
|
||||
instanceProxies,
|
||||
sendInfo.ProjectId
|
||||
);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// 4 - Unpack the render material proxies
|
||||
root[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackMaterials(atomicObjects, usedAcadLayers);
|
||||
|
||||
// 5 - Unpack the color proxies
|
||||
root[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, usedAcadLayers);
|
||||
|
||||
// add any additional properties (most likely from verticals)
|
||||
AddAdditionalProxiesToRoot(root);
|
||||
|
||||
return new RootObjectBuilderResult(root, results);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
return (new(), null);
|
||||
}
|
||||
|
||||
public virtual void AddAdditionalProxiesToRoot(Collection rootCollection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private SendConversionResult ConvertAutocadEntity(
|
||||
Entity entity,
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId
|
||||
)
|
||||
{
|
||||
string sourceType = entity.GetType().ToString();
|
||||
try
|
||||
{
|
||||
Base converted;
|
||||
if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
{
|
||||
converted = instanceProxy;
|
||||
}
|
||||
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
|
||||
{
|
||||
converted = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = _converter.Convert(entity);
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
collectionHost.elements.Add(converted);
|
||||
return new(Status.SUCCESS, applicationId, sourceType, converted);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, sourceType);
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-150
@@ -1,180 +1,46 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public class AutocadRootObjectBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
private readonly IConverterSettingsStore<AutocadConversionSettings> _converterSettings;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly AutocadInstanceUnpacker _instanceUnpacker;
|
||||
private readonly AutocadMaterialUnpacker _materialUnpacker;
|
||||
private readonly AutocadColorUnpacker _colorUnpacker;
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly AutocadGroupUnpacker _groupUnpacker;
|
||||
private readonly ILogger<AutocadRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
|
||||
public AutocadRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
colorUnpacker,
|
||||
groupUnpacker,
|
||||
logger,
|
||||
activityFactory
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_instanceUnpacker = instanceObjectManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_groupUnpacker = groupUnpacker;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
_converterSettings = converterSettings;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
CancellationToken ct = default
|
||||
) => Task.FromResult(BuildSync(objects, sendInfo, onOperationProgressed, ct));
|
||||
|
||||
[SuppressMessage(
|
||||
"Maintainability",
|
||||
"CA1506:Avoid excessive class coupling",
|
||||
Justification = """
|
||||
It is already simplified but has many different references since it is a builder. Do not know can we simplify it now.
|
||||
Later we might consider to refactor proxies from one proxy manager? but we do not know the shape of it all potential
|
||||
proxy classes yet. So I'm supressing this one now!!!
|
||||
"""
|
||||
)]
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
CancellationToken ct
|
||||
)
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
// 0 - Init the root
|
||||
Collection root =
|
||||
new()
|
||||
{
|
||||
name = Application
|
||||
.DocumentManager.CurrentDocument.Name // POC: https://spockle.atlassian.net/browse/CNX-9319
|
||||
.Split(_documentPathSeparator, StringSplitOptions.None)
|
||||
.Reverse()
|
||||
.First()
|
||||
};
|
||||
root["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
// TODO: better handling for document and transactions!!
|
||||
Document doc = Application.DocumentManager.CurrentDocument;
|
||||
using Transaction tr = doc.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1 - Unpack the instances
|
||||
var (atomicObjects, instanceProxies, instanceDefinitionProxies) = _instanceUnpacker.UnpackSelection(objects);
|
||||
root[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies;
|
||||
|
||||
// 2 - Unpack the groups
|
||||
root[ProxyKeys.GROUP] = _groupUnpacker.UnpackGroups(atomicObjects);
|
||||
using (var _ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
// 3 - Convert atomic objects
|
||||
List<LayerTableRecord> usedAcadLayers = new(); // Keeps track of autocad layers used, so we can pass them on later to the material and color unpacker.
|
||||
List<SendConversionResult> results = new();
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
// Create and add a collection for each layer if not done so already.
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
if (autocadLayer is not null)
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(layer);
|
||||
}
|
||||
|
||||
var result = ConvertAutocadEntity(entity, applicationId, layer, instanceProxies, sendInfo.ProjectId);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / atomicObjects.Count);
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// 4 - Unpack the render material proxies
|
||||
root[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackMaterials(atomicObjects, usedAcadLayers);
|
||||
|
||||
// 5 - Unpack the color proxies
|
||||
root[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, usedAcadLayers);
|
||||
|
||||
return new RootObjectBuilderResult(root, results);
|
||||
}
|
||||
}
|
||||
|
||||
private SendConversionResult ConvertAutocadEntity(
|
||||
Entity entity,
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId
|
||||
)
|
||||
{
|
||||
string sourceType = entity.GetType().ToString();
|
||||
try
|
||||
{
|
||||
Base converted;
|
||||
if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
{
|
||||
converted = instanceProxy;
|
||||
}
|
||||
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
|
||||
{
|
||||
converted = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = _converter.Convert(entity);
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
collectionHost.elements.Add(converted);
|
||||
return new(Status.SUCCESS, applicationId, sourceType, converted);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, sourceType);
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,19 @@ public static class AppUtils
|
||||
#elif AUTOCAD
|
||||
HostApplications.AutoCAD;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
public static HostAppVersion Version =>
|
||||
#if CIVIL3D2024
|
||||
HostAppVersion.v2024;
|
||||
#elif AUTOCAD2025
|
||||
#if AUTOCAD2025 || CIVIL3D2025
|
||||
HostAppVersion.v2025;
|
||||
#elif AUTOCAD2024
|
||||
#elif AUTOCAD2024 || CIVIL3D2024
|
||||
HostAppVersion.v2024;
|
||||
#elif AUTOCAD2023
|
||||
#elif AUTOCAD2023|| CIVIL3D2023
|
||||
HostAppVersion.v2023;
|
||||
#elif AUTOCAD2022
|
||||
#elif AUTOCAD2022 || CIVIL3D2022
|
||||
HostAppVersion.v2022;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@ using System.Drawing;
|
||||
using Autodesk.AutoCAD.Runtime;
|
||||
using Autodesk.AutoCAD.Windows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
#if AUTOCAD
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Converters.Autocad;
|
||||
#elif CIVIL3D
|
||||
using Speckle.Converters.Civil3d;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Connectors.Civil3dShared.DependencyInjection;
|
||||
#endif
|
||||
namespace Speckle.Connectors.Autocad.Plugin;
|
||||
|
||||
@@ -30,7 +31,7 @@ public class AutocadCommand
|
||||
return;
|
||||
}
|
||||
|
||||
PaletteSet = new PaletteSet("Speckle (Beta) for Autocad", s_id)
|
||||
PaletteSet = new PaletteSet($"Speckle (Beta) for {AppUtils.App.Name}", s_id)
|
||||
{
|
||||
Size = new Size(400, 500),
|
||||
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right)
|
||||
@@ -51,7 +52,7 @@ public class AutocadCommand
|
||||
|
||||
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
|
||||
PaletteSet.AddVisual("Speckle (Beta) for Autocad WebView", panelWebView);
|
||||
PaletteSet.AddVisual($"Speckle (Beta) for {AppUtils.App.Name} WebView", panelWebView);
|
||||
|
||||
FocusPalette();
|
||||
}
|
||||
|
||||
+2
-1
@@ -13,9 +13,9 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadBasicConnectorBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBaseBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\SharedRegistration.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\AutocadConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\AutocadSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorUnpacker.cs" />
|
||||
@@ -39,6 +39,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TransactionContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\AutocadHostObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObject.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBaseBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadRibbon.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadExtensionApplication.cs" />
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2022</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2022;CIVIL3D2022_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2022\Speckle.Converters.Civil3d2022.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,390 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETFramework,Version=v4.8": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2022.0.2, )",
|
||||
"resolved": "2022.0.2",
|
||||
"contentHash": "NFHXnlkBjzM8Bau52d6eF6m0+etHddGx7qlWN8YyrfTtGyz+AmPvF8fgxcLgyjAcB3W4Wim11JeYuEoTNH1X0w=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2022.0.2, )",
|
||||
"resolved": "2022.0.2",
|
||||
"contentHash": "H36v9rA2Ynh4gDCzpBeUcWs4BQwWi3MwgTAnClM22vNbQXZlxjK85iO8i/mJsX57hh8VfqLB8EA7CUw94gBddw==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2022.0.2"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Net.WebSockets.Client.Managed": "1.0.22",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Net.WebSockets.Client.Managed": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.22",
|
||||
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2022": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2022.0.2, )",
|
||||
"Speckle.Civil3D.API": "[2022.0.2, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2023</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2023;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2023\Speckle.Converters.Civil3d2023.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,390 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETFramework,Version=v4.8": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2023.0.0, )",
|
||||
"resolved": "2023.0.0",
|
||||
"contentHash": "aNfiNw9zRW8pCl8AAQK7afEJuea4bJ4sFNsGVSDrdq1egaonZrwALU01dSyFNCE8tne86eVjlprpOGG6r0+G/A=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2023.0.0, )",
|
||||
"resolved": "2023.0.0",
|
||||
"contentHash": "URb0wfrxm4jcAApRxZ15a1dmxWDRry8WAuGmUwC7saP5+ltkJOVSOYb6WeJKYhDiJbO3UlVCesTFNnsNjMFd5A==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2022.0.2"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Net.WebSockets.Client.Managed": "1.0.22",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Net.WebSockets.Client.Managed": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.22",
|
||||
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2023": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2023.0.0, )",
|
||||
"Speckle.Civil3D.API": "[2023.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2024</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2024;CIVIL3D2024_OR_GREATER</DefineConstants>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2024;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER;CIVIL3D2024_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
@@ -22,4 +22,5 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -92,17 +100,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -131,11 +139,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -165,24 +168,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -283,8 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -318,7 +305,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -330,6 +317,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -356,31 +349,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2025</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D2025;CIVIL3D;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER;CIVIL3D2024_OR_GREATER;CIVIL3D2025_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!-- .NET Core uses this to move native dependencies into a root for runtime selection and usage for non-windows development https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#enablewindowstargeting -->
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" />
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" />
|
||||
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2025\Speckle.Converters.Civil3d2025.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
|
||||
<Import Project="..\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,359 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0-windows7.0": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2025.0.0, )",
|
||||
"resolved": "2025.0.0",
|
||||
"contentHash": "dqEgZ+bTqAG0tx0WwdnTZcbNKH2igzhOr3SMXtRYai7yIqXiz5btZ4Mf2bmfxbmxLucww3GKVpdZoI+PSZlMuQ=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2025.0.0, )",
|
||||
"resolved": "2025.0.0",
|
||||
"contentHash": "zWxdzk7M2JE1+PgIpGrCycDUwbmTqJ+YCNMaJPbjUgVKoAiI5w7Ou9ynbFgmQkRuYrkTflbL+s799Fw62PJixQ==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2025.0.0"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2025": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2025.0.0, )",
|
||||
"Speckle.Civil3d.API": "[2025.0.0, )",
|
||||
"Speckle.Connectors.DUI.WebView": "[1.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Bindings;
|
||||
|
||||
public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
{
|
||||
private readonly ICivil3dConversionSettingsFactory _civil3dConversionSettingsFactory;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public Civil3dSendBinding(
|
||||
DocumentModelStore store,
|
||||
IAutocadIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
CancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
idleManager,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
}
|
||||
|
||||
// POC: we're registering the conversion settings for autocad here because we need the autocad conversion settings to be able to use the autocad typed converters.
|
||||
// POC: We need a separate send binding for civil3d due to using a different unit converter (needed for conversion settings construction)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
|
||||
.Initialize(_civil3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Civil3dShared.Bindings;
|
||||
using Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.DependencyInjection;
|
||||
|
||||
public static class Civil3dConnectorModule
|
||||
{
|
||||
public static void AddCivil3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
serviceCollection.LoadSend();
|
||||
|
||||
// register civil specific send classes
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dSendBinding>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
|
||||
// additional classes
|
||||
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
|
||||
serviceCollection.AddScoped<CatchmentGroupHandler>();
|
||||
serviceCollection.AddScoped<PipeNetworkHandler>();
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
|
||||
public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
|
||||
private readonly CatchmentGroupHandler _catchmentGroupHandler;
|
||||
private readonly PipeNetworkHandler _pipeNetworkHandler;
|
||||
|
||||
public Civil3dRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
PropertySetDefinitionHandler propertySetDefinitionHandler,
|
||||
CatchmentGroupHandler catchmentGroupHandler,
|
||||
PipeNetworkHandler pipeNetworkHandler,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
colorUnpacker,
|
||||
groupUnpacker,
|
||||
logger,
|
||||
activityFactory
|
||||
)
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_propertySetDefinitionHandler = propertySetDefinitionHandler;
|
||||
_catchmentGroupHandler = catchmentGroupHandler;
|
||||
_pipeNetworkHandler = pipeNetworkHandler;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
|
||||
// POC: probably will need to add Network proxies as well
|
||||
public override void AddAdditionalProxiesToRoot(Collection rootObject)
|
||||
{
|
||||
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
|
||||
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
|
||||
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>55E65D72-2FE8-4E61-891C-16A4D551CCF7</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Speckle.Connectors.Civil3dShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dSendBinding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Bindings\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{EFD01520-93E8-4CCA-8E03-9CDC635F55F4}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<Import Project="Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -111,17 +119,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -150,11 +158,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -184,24 +187,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -341,6 +328,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -361,11 +354,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +369,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -111,17 +119,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -150,11 +158,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -184,24 +187,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -341,6 +328,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -361,11 +354,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +369,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -111,17 +119,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -150,11 +158,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -184,24 +187,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -341,6 +328,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -361,11 +354,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +369,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"profiles": {
|
||||
"ConnectorRevit2025": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2025\\Revit.exe"
|
||||
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2025\\Revit.exe",
|
||||
"runtime": "net8.0-windows"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,17 +104,17 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
@@ -143,11 +143,6 @@
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
@@ -177,24 +172,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -260,8 +237,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,7 +247,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.191, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -287,7 +266,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.191, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -306,6 +285,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
@@ -332,11 +317,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -347,22 +332,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.191, )",
|
||||
"resolved": "3.1.0-dev.191",
|
||||
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -13,8 +13,16 @@ public partial class CefSharpPanel : Page, Autodesk.Revit.UI.IDockablePaneProvid
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void ExecuteScriptAsyncMethod(string script) =>
|
||||
Browser.Dispatcher.Invoke(() => Browser.ExecuteScriptAsync(script), DispatcherPriority.Background);
|
||||
public Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken)
|
||||
{
|
||||
Browser.Dispatcher.Invoke(
|
||||
() => Browser.ExecuteScriptAsync(script),
|
||||
DispatcherPriority.Background,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public bool IsBrowserInitialized => Browser.IsBrowserInitialized;
|
||||
public object BrowserElement => Browser;
|
||||
|
||||
+60
-19
@@ -4,7 +4,9 @@ using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.RevitShared;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -19,12 +21,14 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ILogger<BasicConnectorBindingRevit> _logger;
|
||||
|
||||
public BasicConnectorBindingRevit(
|
||||
APIContext apiContext,
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
RevitContext revitContext,
|
||||
@@ -34,6 +38,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
{
|
||||
Name = "baseBinding";
|
||||
Parent = parent;
|
||||
_apiContext = apiContext;
|
||||
_store = store;
|
||||
_revitContext = revitContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
@@ -42,9 +47,10 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
// POC: event binding?
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
@@ -82,7 +88,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
@@ -100,10 +106,32 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
if (model is SenderModelCard senderModelCard)
|
||||
{
|
||||
elementIds = senderModelCard
|
||||
.SendFilter.NotNull()
|
||||
.GetObjectIds()
|
||||
if (senderModelCard.SendFilter is IRevitSendFilter revitFilter)
|
||||
{
|
||||
revitFilter.SetContext(_revitContext, _apiContext);
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedObjects = senderModelCard.SendFilter.NotNull().SelectedObjectIds;
|
||||
|
||||
elementIds = selectedObjects
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -112,34 +140,44 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
elementIds = receiverModelCard
|
||||
.BakedObjectIds.NotNull()
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (elementIds.Count == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(elementIds);
|
||||
await HighlightObjectsOnView(elementIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Highlights the objects from the given ids.
|
||||
/// </summary>
|
||||
/// <param name="objectIds"> UniqueId's of the DB.Elements.</param>
|
||||
public void HighlightObjects(List<string> objectIds)
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
var activeUIDoc =
|
||||
_revitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
HighlightObjectsOnView(
|
||||
objectIds.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid)).ToList()
|
||||
);
|
||||
await HighlightObjectsOnView(
|
||||
objectIds
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList()
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
;
|
||||
}
|
||||
|
||||
private void HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
private async Task HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
{
|
||||
// POC: don't know if we can rely on storing the ActiveUIDocument, hence getting it each time
|
||||
var activeUIDoc =
|
||||
@@ -147,10 +185,13 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
// UiDocument operations should be wrapped into RevitTask, otherwise doesn't work on other tasks.
|
||||
RevitTask.RunAsync(() =>
|
||||
{
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
});
|
||||
await RevitTask
|
||||
.RunAsync(() =>
|
||||
{
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Bindings;
|
||||
|
||||
public class RevitEverythingFilter : EverythingSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds()
|
||||
{
|
||||
// TODO
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RevitSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds()
|
||||
{
|
||||
return SelectedObjectIds;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds)
|
||||
{
|
||||
return SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.Sdk;
|
||||
@@ -52,10 +51,6 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1024
|
||||
public List<ICardSetting> GetReceiveSettings() => [];
|
||||
#pragma warning restore CA1024
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId)
|
||||
@@ -86,23 +81,15 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList();
|
||||
Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
conversionResults.BakedObjectIds,
|
||||
conversionResults.ConversionResults
|
||||
);
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, conversionResults.BakedObjectIds, conversionResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -113,7 +100,7 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.ExtensibleStorage;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
@@ -16,6 +17,7 @@ using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
@@ -27,6 +29,7 @@ namespace Speckle.Connectors.Revit.Bindings;
|
||||
internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
{
|
||||
private readonly IRevitIdleManager _idleManager;
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
@@ -43,11 +46,12 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
private ConcurrentDictionary<ElementId, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
public RevitSendBinding(
|
||||
IRevitIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
APIContext apiContext,
|
||||
DocumentModelStore store,
|
||||
CancellationManager cancellationManager,
|
||||
IBrowserBridge bridge,
|
||||
@@ -63,6 +67,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
: base("sendBinding", store, bridge, revitContext)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_apiContext = apiContext;
|
||||
_cancellationManager = cancellationManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
@@ -82,13 +87,16 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
revitContext.UIApplication.NotNull().Application.DocumentChanged += (_, e) =>
|
||||
topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
|
||||
});
|
||||
Store.DocumentChanged += (_, _) => topLevelExceptionHandler.CatchUnhandled(OnDocumentChanged);
|
||||
Store.DocumentChanged += (_, _) =>
|
||||
topLevelExceptionHandler.FireAndForget(async () => await OnDocumentChanged().ConfigureAwait(false));
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters()
|
||||
{
|
||||
return new List<ISendFilter> { new RevitSelectionFilter() { IsDefault = true } };
|
||||
}
|
||||
public List<ISendFilter> GetSendFilters() =>
|
||||
[
|
||||
new RevitSelectionFilter() { IsDefault = true },
|
||||
new RevitViewsFilter(RevitContext, _apiContext),
|
||||
new RevitCategoriesFilter(RevitContext, _apiContext)
|
||||
];
|
||||
|
||||
public List<ICardSetting> GetSendSettings() =>
|
||||
[
|
||||
@@ -101,10 +109,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
|
||||
public SendBindingUICommands Commands { get; }
|
||||
|
||||
// yes we know Send function calls many different namespace, we know. But currently I don't see any simplification area we can work on!
|
||||
#pragma warning disable CA1506
|
||||
public async Task Send(string modelCardId)
|
||||
#pragma warning restore CA1506
|
||||
{
|
||||
// Note: removed top level handling thing as it was confusing me
|
||||
try
|
||||
@@ -128,16 +133,10 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
)
|
||||
);
|
||||
|
||||
var activeUIDoc =
|
||||
RevitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
List<ElementId> revitObjects = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.GetObjectIds()
|
||||
.Select(uid => activeUIDoc.Document.GetElement(uid).Id)
|
||||
.ToList();
|
||||
List<Element> elements = await RefreshElementsOnSender(modelCard.NotNull()).ConfigureAwait(false);
|
||||
List<ElementId> elementIds = elements.Select(el => el.Id).ToList();
|
||||
|
||||
if (revitObjects.Count == 0)
|
||||
if (elementIds.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
@@ -146,20 +145,16 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ElementId>>()
|
||||
.Execute(
|
||||
revitObjects,
|
||||
elementIds,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -170,10 +165,48 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<Element>> RefreshElementsOnSender(SenderModelCard modelCard)
|
||||
{
|
||||
var activeUIDoc =
|
||||
RevitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
if (modelCard.SendFilter is IRevitSendFilter viewFilter)
|
||||
{
|
||||
viewFilter.SetContext(RevitContext, _apiContext);
|
||||
}
|
||||
|
||||
var selectedObjects = await _apiContext
|
||||
.Run(_ => modelCard.SendFilter.NotNull().RefreshObjectIds())
|
||||
.ConfigureAwait(false);
|
||||
|
||||
List<Element> elements = selectedObjects
|
||||
.Select(uid => activeUIDoc.Document.GetElement(uid))
|
||||
.Where(el => el is not null)
|
||||
.ToList();
|
||||
|
||||
if (modelCard.SendFilter is not null && modelCard.SendFilter.IdMap is not null)
|
||||
{
|
||||
var newSelectedObjectIds = new List<string>();
|
||||
foreach (Element element in elements)
|
||||
{
|
||||
modelCard.SendFilter.IdMap[element.Id.ToString()] = element.UniqueId;
|
||||
newSelectedObjectIds.Add(element.UniqueId);
|
||||
}
|
||||
|
||||
// We update the state on the UI SenderModelCard to prevent potential inconsistencies between hostApp IdMap in sendfilters.
|
||||
await Commands
|
||||
.SetFilterObjectIds(modelCard.ModelCardId.NotNull(), modelCard.SendFilter.IdMap, newSelectedObjectIds)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of the changed element ids as well as checks if any of them need to trigger
|
||||
/// a filter refresh (e.g., views being added).
|
||||
@@ -181,32 +214,62 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// <param name="e"></param>
|
||||
private void DocChangeHandler(Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
|
||||
{
|
||||
ICollection<ElementId> modifiedElementIds = e.GetModifiedElementIds();
|
||||
|
||||
// NOTE: Whenever we save data into file this event also trigger changes on its DataStorage.
|
||||
// On every add/remove/update model attempt triggers this handler and was causing unnecessary calls on `RunExpirationChecks`
|
||||
// Re-check it once we implement Linked Documents
|
||||
if (modifiedElementIds.Count == 1)
|
||||
{
|
||||
var doc = e.GetDocument();
|
||||
if (modifiedElementIds.All(el => doc.GetElement(el) is DataStorage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ICollection<ElementId> addedElementIds = e.GetAddedElementIds();
|
||||
ICollection<ElementId> deletedElementIds = e.GetDeletedElementIds();
|
||||
ICollection<ElementId> modifiedElementIds = e.GetModifiedElementIds();
|
||||
|
||||
foreach (ElementId elementId in addedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in deletedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in modifiedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
if (addedElementIds.Count > 0)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(PostSetObjectIds), PostSetObjectIds);
|
||||
}
|
||||
|
||||
if (HaveUnitsChanged(e.GetDocument()))
|
||||
{
|
||||
var objectIds = Store.GetSenders().SelectMany(s => s.SendFilter != null ? s.SendFilter.GetObjectIds() : []);
|
||||
var objectIds = new List<string>();
|
||||
foreach (var sender in Store.GetSenders().ToList())
|
||||
{
|
||||
if (sender.SendFilter is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var selectedObjects = sender.SendFilter.NotNull().SelectedObjectIds;
|
||||
objectIds.AddRange(selectedObjects);
|
||||
}
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds.ToList());
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RevitSendBinding), RunExpirationChecks);
|
||||
|
||||
_idleManager.SubscribeToIdle(nameof(CheckFilterExpiration), CheckFilterExpiration);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
|
||||
// Keeps track of doc and current units
|
||||
@@ -243,10 +306,38 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RunExpirationChecks()
|
||||
private async Task PostSetObjectIds()
|
||||
{
|
||||
var senders = Store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
foreach (var sender in Store.GetSenders().ToList())
|
||||
{
|
||||
await RefreshElementsOnSender(sender).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies ui if any filters need refreshing. Currently, this only applies for view filters.
|
||||
/// </summary>
|
||||
private async Task CheckFilterExpiration()
|
||||
{
|
||||
// NOTE: below code seems like more make sense in terms of performance but it causes unmanaged exception on Revit
|
||||
// using var viewCollector = new FilteredElementCollector(RevitContext.UIApplication?.ActiveUIDocument.Document);
|
||||
// var views = viewCollector.OfClass(typeof(View)).Cast<View>().Select(v => v.Id).ToList();
|
||||
// var intersection = ChangedObjectIds.Keys.Intersect(views).ToList();
|
||||
// if (intersection.Count != 0)
|
||||
// {
|
||||
// await Commands.RefreshSendFilters().ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
if (ChangedObjectIds.Keys.Any(e => RevitContext.UIApplication?.ActiveUIDocument.Document.GetElement(e) is View))
|
||||
{
|
||||
await Commands.RefreshSendFilters().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
{
|
||||
var senders = Store.GetSenders().ToList();
|
||||
// string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
var doc = RevitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
if (doc == null)
|
||||
@@ -254,20 +345,53 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: We're using unique ids as application ids in revit, so cache eviction must happen by those.
|
||||
var objUniqueIds = objectIdsList
|
||||
.Select(id => new ElementId(Convert.ToInt32(id)))
|
||||
.Select(doc.GetElement)
|
||||
.Where(el => el is not null)
|
||||
.Select(el => el.UniqueId)
|
||||
.ToList();
|
||||
_sendConversionCache.EvictObjects(objUniqueIds);
|
||||
var objUniqueIds = new List<string>();
|
||||
|
||||
foreach (var sender in senders)
|
||||
{
|
||||
// if (sender.SendFilter is null) // NOTE: RunExpirationChecks sometimes triggered unnecessarily before send and, we didn't set up yet IdMap, if so we do not need to deal with it
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
foreach (var changedElementId in ChangedObjectIds.Keys)
|
||||
{
|
||||
if (sender.SendFilter?.IdMap?.TryGetValue(changedElementId.ToString(), out var id) ?? false)
|
||||
{
|
||||
objUniqueIds.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// foreach (var changedElementId in ChangedObjectIds.Keys.ToArray())
|
||||
// {
|
||||
// foreach (var sender in senders)
|
||||
// {
|
||||
// if (sender.SendFilter.NotNull().IdMap is null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
// if (sender.SendFilter.NotNull().IdMap.NotNull().ContainsKey(changedElementId.ToString()))
|
||||
// {
|
||||
// objUniqueIds.Add(sender.SendFilter.NotNull().IdMap.NotNull()[changedElementId.ToString()]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objUniqueIds);
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
|
||||
// Note: we're doing object selection and card expiry management by old school ids
|
||||
List<string> expiredSenderIds = new();
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().GetObjectIds().Intersect(objUniqueIds).ToList();
|
||||
if (modelCard.SendFilter is IRevitSendFilter viewFilter)
|
||||
{
|
||||
viewFilter.SetContext(RevitContext, _apiContext);
|
||||
}
|
||||
|
||||
var selectedObjects = modelCard.SendFilter.NotNull().IdMap.NotNull().Values;
|
||||
var intersection = selectedObjects.Intersect(objUniqueIds).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
@@ -275,22 +399,26 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
// POC: Will be re-addressed later with better UX with host apps that are friendly on async doc operations.
|
||||
// That's why don't bother for now how to get rid of from dup logic in other bindings.
|
||||
private void OnDocumentChanged()
|
||||
private async Task OnDocumentChanged()
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
|
||||
if (_cancellationManager.NumberOfOperations > 0)
|
||||
{
|
||||
_cancellationManager.CancelAllOperations();
|
||||
Commands.SetGlobalNotification(
|
||||
ToastNotificationType.INFO,
|
||||
"Document Switch",
|
||||
"Operations cancelled because of document swap!"
|
||||
);
|
||||
await Commands
|
||||
.SetGlobalNotification(
|
||||
ToastNotificationType.INFO,
|
||||
"Document Switch",
|
||||
"Operations cancelled because of document swap!"
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -73,6 +73,9 @@ public static class ServiceRegistration
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
|
||||
// API context helps us to run functions on Revit UI Thread (main)
|
||||
serviceCollection.AddSingleton<APIContext>();
|
||||
}
|
||||
|
||||
public static void RegisterUiDependencies(IServiceCollection serviceCollection)
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Speckle.Converters.Common;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared;
|
||||
|
||||
public static class ElementIdHelper
|
||||
{
|
||||
public static ElementId GetElementIdFromUniqueId(Document doc, string uniqueId)
|
||||
public static ElementId? GetElementIdFromUniqueId(Document doc, string uniqueId)
|
||||
{
|
||||
Element element = doc.GetElement(uniqueId);
|
||||
if (element == null)
|
||||
{
|
||||
throw new SpeckleConversionException($"Cannot find element with UniqueId: {uniqueId}");
|
||||
}
|
||||
return element?.Id;
|
||||
}
|
||||
|
||||
return element.Id;
|
||||
public static ElementId? GetElementId(string elementId)
|
||||
{
|
||||
#if REVIT2024_OR_GREATER
|
||||
if (long.TryParse(elementId, out long elementIdInt))
|
||||
{
|
||||
return new ElementId(elementIdInt);
|
||||
}
|
||||
#else
|
||||
if (int.TryParse(elementId, out int elementIdInt))
|
||||
{
|
||||
return new ElementId(elementIdInt);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// This class gives access to the Revit API context from anywhere in your codebase. This is essentially a
|
||||
/// lite version of the Revit.Async package from Kennan Chan. Most of the functionality was taken from that code.
|
||||
/// The main difference is that this class does not subscribe to the applicationIdling event from revit
|
||||
/// which the docs say will impact the performance of Revit
|
||||
/// </summary>
|
||||
public sealed class APIContext : IDisposable
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||
private readonly UIControlledApplication _uiApplication;
|
||||
private readonly ExternalEventHandler<IExternalEventHandler, ExternalEvent> _factoryExternalEventHandler;
|
||||
#pragma warning disable CA2213
|
||||
private readonly ExternalEvent _factoryExternalEvent;
|
||||
#pragma warning restore CA2213
|
||||
|
||||
public APIContext(UIControlledApplication application)
|
||||
{
|
||||
_uiApplication = application;
|
||||
_factoryExternalEventHandler = new(ExternalEvent.Create);
|
||||
_factoryExternalEvent = ExternalEvent.Create(_factoryExternalEventHandler);
|
||||
}
|
||||
|
||||
public async Task<TResult> Run<TResult>(Func<UIControlledApplication, TResult> func)
|
||||
{
|
||||
await _semaphore.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var handler = new ExternalEventHandler<UIControlledApplication, TResult>(func);
|
||||
using var externalEvent = await Run(_factoryExternalEventHandler, handler, _factoryExternalEvent)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return await Run(handler, _uiApplication, externalEvent).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Run(Action<UIControlledApplication> action) =>
|
||||
await Run<object>(app =>
|
||||
{
|
||||
action(app);
|
||||
return null!;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
public async Task Run(Action action) =>
|
||||
await Run<object>(_ =>
|
||||
{
|
||||
action();
|
||||
return null!;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
private async Task<TResult> Run<TParameter, TResult>(
|
||||
ExternalEventHandler<TParameter, TResult> handler,
|
||||
TParameter parameter,
|
||||
ExternalEvent externalEvent
|
||||
)
|
||||
{
|
||||
var task = handler.GetTask(parameter);
|
||||
externalEvent.Raise();
|
||||
|
||||
return await task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_factoryExternalEvent.Dispose();
|
||||
_semaphore.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public enum HandlerStatus
|
||||
{
|
||||
NotStarted,
|
||||
Started,
|
||||
IsCompleted,
|
||||
IsFaulted,
|
||||
}
|
||||
|
||||
internal sealed class ExternalEventHandler<TParameter, TResult> : IExternalEventHandler
|
||||
{
|
||||
private TaskCompletionSource<TResult> Result { get; set; }
|
||||
|
||||
public Task<TResult> GetTask(TParameter parameter)
|
||||
{
|
||||
Parameter = parameter;
|
||||
Result = new TaskCompletionSource<TResult>();
|
||||
return Result.Task;
|
||||
}
|
||||
|
||||
private readonly Func<TParameter, TResult> _func;
|
||||
|
||||
public ExternalEventHandler(Func<TParameter, TResult> func)
|
||||
{
|
||||
this._func = func;
|
||||
}
|
||||
|
||||
public HandlerStatus Status { get; private set; } = HandlerStatus.NotStarted;
|
||||
private TParameter Parameter { get; set; }
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
||||
"Design",
|
||||
"CA1031:Do not catch general exception types",
|
||||
Justification = "This is a very generic utility method for running things in a Revit context. If the result of the Run method is awaited, then the exception caught here will be raised there."
|
||||
)]
|
||||
public void Execute(UIApplication app)
|
||||
{
|
||||
Status = HandlerStatus.Started;
|
||||
try
|
||||
{
|
||||
var r = _func(Parameter);
|
||||
Result.SetResult(r);
|
||||
Status = HandlerStatus.IsCompleted;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Status = HandlerStatus.IsFaulted;
|
||||
Result.SetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetName() => "SpeckleRevitContextEventHandler";
|
||||
}
|
||||
@@ -93,8 +93,15 @@ public class ElementUnpacker
|
||||
private List<Element> PackCurtainWallElements(List<Element> elements)
|
||||
{
|
||||
var ids = elements.Select(el => el.Id).ToArray();
|
||||
var doc = _revitContext.UIApplication?.ActiveUIDocument.Document!;
|
||||
elements.RemoveAll(element =>
|
||||
(element is Mullion m && ids.Contains(m.Host.Id)) || (element is Panel p && ids.Contains(p.Host.Id))
|
||||
(element is Mullion m && ids.Contains(m.Host.Id))
|
||||
|| (element is Panel p && ids.Contains(p.Host.Id))
|
||||
|| (
|
||||
element is FamilyInstance { Host: not null } f
|
||||
&& doc.GetElement(f.Host.Id) is Wall { CurtainGrid: not null }
|
||||
&& ids.Contains(f.Host.Id)
|
||||
)
|
||||
);
|
||||
return elements;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ using Autodesk.Revit.UI.Events;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
@@ -28,12 +28,12 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
public RevitDocumentStore(
|
||||
IRevitIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
JsonSerializerSettings serializerSettings,
|
||||
IJsonSerializer jsonSerializer,
|
||||
DocumentModelStorageSchema documentModelStorageSchema,
|
||||
IdStorageSchema idStorageSchema,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(serializerSettings, true)
|
||||
: base(jsonSerializer, true)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_revitContext = revitContext;
|
||||
|
||||
@@ -2,13 +2,11 @@ using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// <para>On receive, this class will help structure atomic objects into nested revit groups based on the hierarchy that they're coming from. Expects to be a scoped dependency per receive operation.</para>
|
||||
/// <para>How to use: during atomic object conversion, on each succesful conversion call <see cref="AddToGroupMapping"/>. Afterward, at the end of the recieve operation, call <see cref="BakeGroups"/> to actually create the groups in the revit document.</para>
|
||||
/// Bakes all objects into a single top level group and pins it.
|
||||
/// </summary>
|
||||
public class RevitGroupBaker : TraversalContextUnpacker
|
||||
{
|
||||
@@ -21,62 +19,21 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
_revitUtils = revitUtils;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the object to the correct group in preparation for <see cref="BakeGroups"/> at the end of the receive operation.
|
||||
/// </summary>
|
||||
/// <param name="traversalContext"></param>
|
||||
/// <param name="revitElement"></param>
|
||||
public void AddToGroupMapping(TraversalContext traversalContext, Element revitElement)
|
||||
private readonly List<ElementId> _elementIdsForTopLevelGroup = new();
|
||||
|
||||
public void AddToTopLevelGroup(Element revitElement) => _elementIdsForTopLevelGroup.Add(revitElement.Id);
|
||||
|
||||
public void BakeGroupForTopLevel(string baseGroupName)
|
||||
{
|
||||
var collectionPath = GetCollectionPath(traversalContext);
|
||||
var currentLayerName = string.Empty;
|
||||
FakeGroup? previousGroup = null;
|
||||
var currentDepth = 0;
|
||||
|
||||
foreach (var collection in collectionPath)
|
||||
if (_elementIdsForTopLevelGroup.Count == 0)
|
||||
// if no elements were successfully converted, instead of throwing when creating a new group, we should just return and let object conversion exceptions bubble up.
|
||||
{
|
||||
currentLayerName += collection.name + "-";
|
||||
if (_groupCache.TryGetValue(currentLayerName, out var g))
|
||||
{
|
||||
previousGroup = g;
|
||||
currentDepth++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var group = new FakeGroup()
|
||||
{
|
||||
// POC group names should be unique
|
||||
Name = _revitUtils.RemoveInvalidChars(currentLayerName[..^1]),
|
||||
Depth = currentDepth++,
|
||||
Parent = previousGroup!
|
||||
};
|
||||
_groupCache[currentLayerName] = group;
|
||||
previousGroup = group;
|
||||
return;
|
||||
}
|
||||
|
||||
previousGroup!.Ids.Add(revitElement.Id);
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, FakeGroup> _groupCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// Bakes the accumulated groups in Revit, with their objects.
|
||||
/// </summary>
|
||||
/// <param name="baseGroupName"></param>
|
||||
public void BakeGroups(string baseGroupName)
|
||||
{
|
||||
var orderedGroups = _groupCache.Values.OrderByDescending(group => group.Depth);
|
||||
Group? lastGroup = null;
|
||||
|
||||
foreach (var group in orderedGroups)
|
||||
{
|
||||
var docGroup = _converterSettings.Current.Document.Create.NewGroup(group.Ids);
|
||||
group.Parent?.Ids.Add(docGroup.Id);
|
||||
docGroup.GroupType.Name = group.Name;
|
||||
lastGroup = docGroup;
|
||||
}
|
||||
|
||||
lastGroup!.GroupType.Name = _revitUtils.RemoveInvalidChars(baseGroupName);
|
||||
var docGroup = _converterSettings.Current.Document.Create.NewGroup(_elementIdsForTopLevelGroup);
|
||||
docGroup.GroupType.Name = _revitUtils.RemoveInvalidChars(baseGroupName);
|
||||
docGroup.Pinned = true;
|
||||
}
|
||||
|
||||
public void PurgeGroups(string baseGroupName)
|
||||
@@ -86,25 +43,23 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
List<ElementId> subgroupTypeIds = new List<ElementId>();
|
||||
var subgroupTypeIds = new List<ElementId>() { group.GroupType.Id };
|
||||
CollectSubGroupTypeIds(document, group, subgroupTypeIds);
|
||||
document.Delete(subgroupTypeIds);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Group> GetGroupsByName(Autodesk.Revit.DB.Document doc, string groupName)
|
||||
private List<Group> GetGroupsByName(Document doc, string groupName)
|
||||
{
|
||||
var validGroupName = _revitUtils.RemoveInvalidChars(groupName);
|
||||
|
||||
using (var collector = new FilteredElementCollector(doc))
|
||||
{
|
||||
ICollection<Element> groupElements = collector.OfClass(typeof(Group)).ToElements();
|
||||
List<Group> groups = groupElements.Cast<Group>().Where(g => g.GroupType.Name == validGroupName).ToList();
|
||||
return groups;
|
||||
}
|
||||
using var collector = new FilteredElementCollector(doc);
|
||||
ICollection<Element> groupElements = collector.OfClass(typeof(Group)).ToElements();
|
||||
List<Group> groups = groupElements.Cast<Group>().Where(g => g.GroupType.Name == validGroupName).ToList();
|
||||
return groups;
|
||||
}
|
||||
|
||||
private void CollectSubGroupTypeIds(Autodesk.Revit.DB.Document document, Group group, List<ElementId> subGroupTypeIds)
|
||||
private void CollectSubGroupTypeIds(Document document, Group group, List<ElementId> subGroupTypeIds)
|
||||
{
|
||||
ICollection<ElementId> groupMemberIds = group.GetMemberIds();
|
||||
|
||||
@@ -119,15 +74,4 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Little intermediate data structure that helps with the operations above.
|
||||
/// </summary>
|
||||
private sealed class FakeGroup
|
||||
{
|
||||
public List<ElementId> Ids { get; set; } = new();
|
||||
public int Depth { get; set; }
|
||||
public string Name { get; set; }
|
||||
public FakeGroup Parent { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ public interface ITransactionManager : IDisposable
|
||||
void StartSubtransaction();
|
||||
|
||||
// POC improve how the error handling behaviour is selected
|
||||
void StartTransaction(bool enableFailurePreprocessor = false);
|
||||
void StartTransaction(bool enableFailurePreprocessor = false, string name = "Speckle Transaction");
|
||||
}
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Operations.Receive;
|
||||
|
||||
internal sealed class RevitContextAccessor : ISyncToThread
|
||||
{
|
||||
public Task<T> RunOnThread<T>(Func<T> func) => RevitTask.RunAsync(func);
|
||||
}
|
||||
|
||||
+141
-71
@@ -4,14 +4,22 @@ using Revit.Async;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Common.Objects;
|
||||
using Speckle.Converters.RevitShared;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Objects;
|
||||
using Speckle.Objects.Geometry;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Transform = Speckle.Objects.Other.Transform;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Operations.Receive;
|
||||
|
||||
@@ -22,10 +30,13 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
private readonly RevitToHostCacheSingleton _revitToHostCacheSingleton;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly ILocalToGlobalUnpacker _localToGlobalUnpacker;
|
||||
private readonly LocalToGlobalConverterUtils _localToGlobalConverterUtils;
|
||||
private readonly RevitGroupBaker _groupBaker;
|
||||
private readonly RevitMaterialBaker _materialBaker;
|
||||
private readonly ILogger<RevitHostObjectBuilder> _logger;
|
||||
private readonly ITypedConverter<
|
||||
(Base atomicObject, List<Matrix4x4> matrix),
|
||||
DirectShape
|
||||
> _localToGlobalDirectShapeConverter;
|
||||
|
||||
private readonly RootObjectUnpacker _rootObjectUnpacker;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
@@ -36,24 +47,24 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
ITransactionManager transactionManager,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ILocalToGlobalUnpacker localToGlobalUnpacker,
|
||||
LocalToGlobalConverterUtils localToGlobalConverterUtils,
|
||||
RevitGroupBaker groupManager,
|
||||
RevitMaterialBaker materialBaker,
|
||||
RootObjectUnpacker rootObjectUnpacker,
|
||||
ILogger<RevitHostObjectBuilder> logger,
|
||||
RevitToHostCacheSingleton revitToHostCacheSingleton
|
||||
RevitToHostCacheSingleton revitToHostCacheSingleton,
|
||||
ITypedConverter<(Base atomicObject, List<Matrix4x4> matrix), DirectShape> localToGlobalDirectShapeConverter
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_converterSettings = converterSettings;
|
||||
_transactionManager = transactionManager;
|
||||
_localToGlobalUnpacker = localToGlobalUnpacker;
|
||||
_localToGlobalConverterUtils = localToGlobalConverterUtils;
|
||||
_groupBaker = groupManager;
|
||||
_materialBaker = materialBaker;
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
_logger = logger;
|
||||
_revitToHostCacheSingleton = revitToHostCacheSingleton;
|
||||
_localToGlobalDirectShapeConverter = localToGlobalDirectShapeConverter;
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
@@ -61,7 +72,7 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
) =>
|
||||
RevitTask.RunAsync(() => BuildSync(rootObject, projectName, modelName, onOperationProgressed, cancellationToken));
|
||||
@@ -70,33 +81,29 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var baseGroupName = $"Project {projectName}: Model {modelName}"; // TODO: unify this across connectors!
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using var activity = _activityFactory.Start("Build");
|
||||
|
||||
// 0 - Clean then Rock n Roll! 🎸
|
||||
using TransactionGroup preReceiveCleanTransaction = new(_converterSettings.Current.Document, "Pre-receive clean");
|
||||
preReceiveCleanTransaction.Start();
|
||||
_transactionManager.StartTransaction(true);
|
||||
{
|
||||
_activityFactory.Start("Pre receive clean");
|
||||
_transactionManager.StartTransaction(true, "Pre receive clean");
|
||||
try
|
||||
{
|
||||
PreReceiveDeepClean(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clean up before receive in Revit");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PreReceiveDeepClean(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clean up before receive in Revit");
|
||||
}
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
{
|
||||
_transactionManager.CommitTransaction();
|
||||
preReceiveCleanTransaction.Assimilate();
|
||||
}
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
@@ -106,57 +113,56 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
unpackedRoot.ObjectsToConvert.ToList()
|
||||
);
|
||||
|
||||
using TransactionGroup transactionGroup =
|
||||
new(_converterSettings.Current.Document, $"Received data from {projectName}");
|
||||
transactionGroup.Start();
|
||||
_transactionManager.StartTransaction();
|
||||
|
||||
// 2 - Bake materials
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
_transactionManager.StartTransaction(true, "Baking materials");
|
||||
_materialBaker.MapLayersRenderMaterials(unpackedRoot);
|
||||
// NOTE: do not set _contextStack.RenderMaterialProxyCache directly, things stop working. Ogu/Dim do not know why :) not a problem as we hopefully will refactor some of these hacks out.
|
||||
var map = _materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseGroupName);
|
||||
foreach (var kvp in map)
|
||||
{
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var conversionResults = BakeObjects(localToGlobalMaps, onOperationProgressed, cancellationToken);
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
{
|
||||
_transactionManager.CommitTransaction();
|
||||
transactionGroup.Assimilate();
|
||||
}
|
||||
|
||||
using TransactionGroup createGroupTransaction = new(_converterSettings.Current.Document, "Creating group");
|
||||
createGroupTransaction.Start();
|
||||
_transactionManager.StartTransaction(true);
|
||||
|
||||
try
|
||||
{
|
||||
_groupBaker.BakeGroups(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to create group after receiving elements in Revit");
|
||||
}
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
// 3 - Bake objects
|
||||
(
|
||||
HostObjectBuilderResult builderResult,
|
||||
List<(DirectShape res, string applicationId)> postBakePaintTargets
|
||||
) conversionResults;
|
||||
{
|
||||
using var _ = _activityFactory.Start("Baking objects");
|
||||
_transactionManager.StartTransaction(true, "Baking objects");
|
||||
conversionResults = BakeObjects(localToGlobalMaps, onOperationProgressed, cancellationToken);
|
||||
_transactionManager.CommitTransaction();
|
||||
createGroupTransaction.Assimilate();
|
||||
}
|
||||
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Clear(); // Massive hack!
|
||||
// 4 - Paint solids
|
||||
{
|
||||
using var _ = _activityFactory.Start("Painting solids");
|
||||
_transactionManager.StartTransaction(true, "Painting solids");
|
||||
PostBakePaint(conversionResults.postBakePaintTargets);
|
||||
_transactionManager.CommitTransaction();
|
||||
}
|
||||
|
||||
return conversionResults;
|
||||
// 5 - Create group
|
||||
{
|
||||
using var _ = _activityFactory.Start("Grouping");
|
||||
_transactionManager.StartTransaction(true, "Grouping");
|
||||
_groupBaker.BakeGroupForTopLevel(baseGroupName);
|
||||
_transactionManager.CommitTransaction();
|
||||
}
|
||||
|
||||
return conversionResults.builderResult;
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BakeObjects(
|
||||
private (
|
||||
HostObjectBuilderResult builderResult,
|
||||
List<(DirectShape res, string applicationId)> postBakePaintTargets
|
||||
) BakeObjects(
|
||||
List<LocalToGlobalMap> localToGlobalMaps,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -165,47 +171,111 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
var bakedObjectIds = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
var postBakePaintTargets = new List<(DirectShape res, string applicationId)>();
|
||||
|
||||
foreach (LocalToGlobalMap localToGlobalMap in localToGlobalMaps)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
using var activity = _activityFactory.Start("BakeObject");
|
||||
var atomicObject = _localToGlobalConverterUtils.TransformObjects(
|
||||
localToGlobalMap.AtomicObject,
|
||||
localToGlobalMap.Matrix
|
||||
);
|
||||
var result = _converter.Convert(atomicObject);
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / localToGlobalMaps.Count);
|
||||
|
||||
// Note: our current converter always returns a DS for now
|
||||
if (result is DirectShape ds)
|
||||
// POC hack of the ages: try to pre transform curves, points and meshes before baking
|
||||
// we need to bypass the local to global converter as there we don't have access to what we want. that service will/should stop existing.
|
||||
if (
|
||||
localToGlobalMap.AtomicObject is ITransformable transformable // and ICurve
|
||||
&& localToGlobalMap.Matrix.Count > 0
|
||||
&& localToGlobalMap.AtomicObject["units"] is string units
|
||||
)
|
||||
{
|
||||
bakedObjectIds.Add(ds.UniqueId.ToString());
|
||||
_groupBaker.AddToGroupMapping(localToGlobalMap.TraversalContext, ds);
|
||||
ITransformable? newTransformable = null;
|
||||
foreach (var mat in localToGlobalMap.Matrix)
|
||||
{
|
||||
transformable.TransformTo(new Transform() { matrix = mat, units = units }, out newTransformable);
|
||||
}
|
||||
|
||||
localToGlobalMap.AtomicObject = (newTransformable as Base)!;
|
||||
localToGlobalMap.Matrix = new(); // flush out the list, as we've applied the transforms already
|
||||
}
|
||||
|
||||
// actual conversion happens here!
|
||||
var result = _converter.Convert(localToGlobalMap.AtomicObject);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / localToGlobalMaps.Count));
|
||||
if (result is DirectShapeDefinitionWrapper)
|
||||
{
|
||||
// direct shape creation happens here
|
||||
DirectShape directShapes = _localToGlobalDirectShapeConverter.Convert(
|
||||
(localToGlobalMap.AtomicObject, localToGlobalMap.Matrix)
|
||||
);
|
||||
|
||||
bakedObjectIds.Add(directShapes.UniqueId);
|
||||
_groupBaker.AddToTopLevelGroup(directShapes);
|
||||
|
||||
if (localToGlobalMap.AtomicObject is IRawEncodedObject and Base myBase)
|
||||
{
|
||||
postBakePaintTargets.Add((directShapes, myBase.applicationId ?? myBase.id));
|
||||
}
|
||||
|
||||
conversionResults.Add(
|
||||
new(Status.SUCCESS, localToGlobalMap.AtomicObject, directShapes.UniqueId, "Direct Shape")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SpeckleConversionException($"Failed to cast {result.GetType()} to Direct Shape.");
|
||||
throw new ConversionException($"Failed to cast {result.GetType()} to direct shape definition wrapper.");
|
||||
}
|
||||
conversionResults.Add(new(Status.SUCCESS, atomicObject, ds.UniqueId, "Direct Shape"));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
conversionResults.Add(new(Status.ERROR, localToGlobalMap.AtomicObject, null, null, ex));
|
||||
_logger.LogError(ex, $"Failed to convert object of type {localToGlobalMap.AtomicObject.speckle_type}");
|
||||
}
|
||||
}
|
||||
return (new(bakedObjectIds, conversionResults), postBakePaintTargets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We're using this to assign materials to solids coming via the shape importer.
|
||||
/// </summary>
|
||||
/// <param name="paintTargets"></param>
|
||||
private void PostBakePaint(List<(DirectShape res, string applicationId)> paintTargets)
|
||||
{
|
||||
foreach (var (res, applicationId) in paintTargets)
|
||||
{
|
||||
var elGeometry = res.get_Geometry(new Options() { DetailLevel = ViewDetailLevel.Undefined });
|
||||
var materialId = ElementId.InvalidElementId;
|
||||
if (_revitToHostCacheSingleton.MaterialsByObjectId.TryGetValue(applicationId, out var mappedElementId))
|
||||
{
|
||||
materialId = mappedElementId;
|
||||
}
|
||||
|
||||
if (materialId == ElementId.InvalidElementId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE: some geometries fail to convert as solids, and the api defaults back to meshes (from the shape importer). These cannot be painted, so don't bother.
|
||||
foreach (var geo in elGeometry)
|
||||
{
|
||||
if (geo is Solid s)
|
||||
{
|
||||
foreach (Face face in s.Faces)
|
||||
{
|
||||
_converterSettings.Current.Document.Paint(res.Id, face, materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(bakedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseGroupName)
|
||||
{
|
||||
DirectShapeLibrary.GetDirectShapeLibrary(_converterSettings.Current.Document).Reset(); // Note: this needs to be cleared, as it is being used in the converter
|
||||
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Clear(); // Massive hack!
|
||||
_groupBaker.PurgeGroups(baseGroupName);
|
||||
_materialBaker.PurgeMaterials(baseGroupName);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_transactionManager?.Dispose();
|
||||
}
|
||||
public void Dispose() => _transactionManager?.Dispose();
|
||||
}
|
||||
|
||||
+2
-2
@@ -30,11 +30,11 @@ public sealed class TransactionManager : ITransactionManager
|
||||
#pragma warning restore CA2213 // Disposable fields should be disposed
|
||||
|
||||
// POC find a better way to use IFailuresPreprocessor
|
||||
public void StartTransaction(bool enableFailurePreprocessor = false)
|
||||
public void StartTransaction(bool enableFailurePreprocessor = false, string name = "Speckle Transaction")
|
||||
{
|
||||
if (_transaction == null || !_transaction.IsValidObject || _transaction.GetStatus() != TransactionStatus.Started)
|
||||
{
|
||||
_transaction = new Transaction(Document, "Speckle Transaction");
|
||||
_transaction = new Transaction(Document, name);
|
||||
|
||||
if (enableFailurePreprocessor)
|
||||
{
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public interface IRevitSendFilter
|
||||
{
|
||||
public void SetContext(RevitContext revitContext, APIContext apiContext);
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public record CategoryData(string Name, string Id);
|
||||
|
||||
public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSendFilter
|
||||
{
|
||||
private RevitContext _revitContext;
|
||||
private APIContext _apiContext;
|
||||
private Document? _doc;
|
||||
public string Id { get; set; } = "revitCategories";
|
||||
public string Name { get; set; } = "Categories";
|
||||
public string? Summary { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public List<string> SelectedObjectIds { get; set; } = new();
|
||||
public Dictionary<string, string>? IdMap { get; set; }
|
||||
public List<string>? SelectedCategories { get; set; }
|
||||
public List<CategoryData>? AvailableCategories { get; set; }
|
||||
|
||||
public RevitCategoriesFilter() { }
|
||||
|
||||
public RevitCategoriesFilter(RevitContext revitContext, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
GetCategories();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Always need to run on Revit UI thread (main) because of FilteredElementCollector.
|
||||
/// Use it with APIContext.Run
|
||||
/// </summary>
|
||||
/// <exception cref="SpeckleSendFilterException">Whenever no view is found.</exception>
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
if (SelectedCategories is null)
|
||||
{
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
var elementIds = SelectedCategories.Select(c => ElementIdHelper.GetElementId(c)).Where(e => e is not null).ToList();
|
||||
|
||||
using var categoryFilter = new ElementMulticategoryFilter(elementIds);
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
var elements = collector
|
||||
.WhereElementIsNotElementType()
|
||||
.WhereElementIsViewIndependent()
|
||||
.WherePasses(categoryFilter)
|
||||
.ToList();
|
||||
objectIds = elements.Select(e => e.UniqueId).ToList();
|
||||
SelectedObjectIds = objectIds;
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
private void GetCategories()
|
||||
{
|
||||
if (_doc is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var categories = new List<CategoryData>();
|
||||
|
||||
foreach (Category category in _doc.Settings.Categories)
|
||||
{
|
||||
categories.Add(new CategoryData(category.Name, category.Id.ToString()));
|
||||
}
|
||||
|
||||
AvailableCategories = categories;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NOTE: this is needed since we need doc on `GetObjectIds()` function after it deserialized.
|
||||
/// DI doesn't help here to pass RevitContext from constructor.
|
||||
/// </summary>
|
||||
public void SetContext(RevitContext revitContext, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public class RevitSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public RevitSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override List<string> RefreshObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilter
|
||||
{
|
||||
private RevitContext _revitContext;
|
||||
private APIContext _apiContext;
|
||||
private Document? _doc;
|
||||
public string Id { get; set; } = "revitViews";
|
||||
public string Name { get; set; } = "Views";
|
||||
public string? Summary { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string? SelectedView { get; set; }
|
||||
public List<string> SelectedObjectIds { get; set; }
|
||||
public Dictionary<string, string>? IdMap { get; set; } = new();
|
||||
public List<string>? AvailableViews { get; set; }
|
||||
|
||||
public RevitViewsFilter() { }
|
||||
|
||||
public RevitViewsFilter(RevitContext revitContext, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
GetViews();
|
||||
}
|
||||
|
||||
public View? GetView()
|
||||
{
|
||||
if (SelectedView is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string[] result = SelectedView.Split(new string[] { " - " }, 2, StringSplitOptions.None);
|
||||
var viewFamilyString = result[0];
|
||||
var viewString = result[1];
|
||||
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
return collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.FirstOrDefault(v => v.ViewType.ToString().Equals(viewFamilyString) && v.Name.Equals(viewString));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Always need to run on Revit UI thread (main) because of FilteredElementCollector.
|
||||
/// Use it with APIContext.Run
|
||||
/// </summary>
|
||||
/// <exception cref="SpeckleSendFilterException">Whenever no view is found.</exception>
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
if (SelectedView is null)
|
||||
{
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
// Paşa Bilal wants it like this... (three dots = important meaning for ogu)
|
||||
string[] result = SelectedView.Split(new string[] { " - " }, 2, StringSplitOptions.None);
|
||||
var viewFamilyString = result[0];
|
||||
var viewString = result[1];
|
||||
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
View? view = collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.FirstOrDefault(v => v.ViewType.ToString().Equals(viewFamilyString) && v.Name.Equals(viewString));
|
||||
|
||||
if (view is null)
|
||||
{
|
||||
throw new SpeckleSendFilterException("View not found, please update your model send filter.");
|
||||
}
|
||||
using var viewCollector = new FilteredElementCollector(_doc, view.Id);
|
||||
List<Element> elementsInView = viewCollector.ToElements().ToList();
|
||||
objectIds = elementsInView.Select(e => e.UniqueId).ToList();
|
||||
SelectedObjectIds = objectIds;
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
private void GetViews()
|
||||
{
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
var views = collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.Where(v => !v.IsTemplate)
|
||||
.Select(v => v.ViewType.ToString() + " - " + v.Name.ToString())
|
||||
.ToList();
|
||||
AvailableViews = views;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NOTE: this is needed since we need doc on `GetObjectIds()` function after it deserialized.
|
||||
/// DI doesn't help here to pass RevitContext from constructor.
|
||||
/// </summary>
|
||||
public void SetContext(RevitContext revitContext, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
}
|
||||
}
|
||||
+23
-16
@@ -23,7 +23,6 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
// POC: SendSelection and RevitConversionContextStack should be interfaces, former needs interfaces
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
|
||||
private readonly Collection _rootObject;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
private readonly SendCollectionManager _sendCollectionManager;
|
||||
@@ -50,18 +49,19 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
_revitToSpeckleCacheSingleton = revitToSpeckleCacheSingleton;
|
||||
_logger = logger;
|
||||
_parameterDefinitionHandler = parameterDefinitionHandler;
|
||||
|
||||
_rootObject = new Collection()
|
||||
{
|
||||
name = _converterSettings.Current.Document.PathName.Split('\\').Last().Split('.').First()
|
||||
};
|
||||
_rootObject["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
}
|
||||
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ElementId> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
) => await RevitTask.RunAsync(() => BuildSync(objects, sendInfo, onOperationProgressed, ct)).ConfigureAwait(false);
|
||||
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<ElementId> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
@@ -72,6 +72,11 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
throw new SpeckleException("Family Environment documents are not supported.");
|
||||
}
|
||||
|
||||
// 0 - Init the root
|
||||
Collection rootObject =
|
||||
new() { name = _converterSettings.Current.Document.PathName.Split('\\').Last().Split('.').First() };
|
||||
rootObject["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
|
||||
var revitElements = new List<Element>();
|
||||
|
||||
// Convert ids to actual revit elements
|
||||
@@ -112,11 +117,12 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = await RevitTask.RunAsync(() => _converter.Convert(revitElement)).ConfigureAwait(false); // Could we run these batched? Is there maybe a performance penalty for running these to speckle conversions individually in revittask.runasync?
|
||||
converted = _converter.Convert(revitElement);
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
var collection = _sendCollectionManager.GetAndCreateObjectHostCollection(revitElement, _rootObject);
|
||||
var collection = _sendCollectionManager.GetAndCreateObjectHostCollection(revitElement, rootObject);
|
||||
|
||||
collection.elements.Add(converted);
|
||||
results.Add(new(Status.SUCCESS, applicationId, sourceType, converted));
|
||||
}
|
||||
@@ -126,20 +132,21 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
results.Add(new(Status.ERROR, applicationId, sourceType, null, ex));
|
||||
}
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++countProgress / atomicObjects.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++countProgress / atomicObjects.Count));
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects.");
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
var idsAndSubElementIds = _elementUnpacker.GetElementsAndSubelementIdsFromAtomicObjects(atomicObjects);
|
||||
var materialProxies = _revitToSpeckleCacheSingleton.GetRenderMaterialProxyListForObjects(idsAndSubElementIds);
|
||||
_rootObject[ProxyKeys.RENDER_MATERIAL] = materialProxies;
|
||||
// NOTE: these are currently not used anywhere, so we could even skip them (?).
|
||||
_rootObject[ProxyKeys.PARAMETER_DEFINITIONS] = _parameterDefinitionHandler.Definitions;
|
||||
rootObject[ProxyKeys.RENDER_MATERIAL] = materialProxies;
|
||||
|
||||
return new RootObjectBuilderResult(_rootObject, results);
|
||||
// NOTE: these are currently not used anywhere, we'll skip them until someone calls for it back
|
||||
// rootObject[ProxyKeys.PARAMETER_DEFINITIONS] = _parameterDefinitionHandler.Definitions;
|
||||
|
||||
return new RootObjectBuilderResult(rootObject, results);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -14,6 +14,7 @@ namespace Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
|
||||
@@ -24,11 +25,13 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public ToSpeckleSettingsManager(
|
||||
RevitContext revitContext,
|
||||
APIContext apiContext,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ElementUnpacker elementUnpacker
|
||||
)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_elementUnpacker = elementUnpacker;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
}
|
||||
@@ -104,7 +107,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.GetObjectIds() : [];
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds);
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
|
||||
@@ -2,43 +2,46 @@ using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Events;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public sealed class RevitIdleManager(RevitContext revitContext, IIdleCallManager idleCallManager) : IRevitIdleManager
|
||||
public interface IRevitIdleManager : IAppIdleManager
|
||||
{
|
||||
private readonly UIApplication _uiApplication = revitContext.UIApplication.NotNull();
|
||||
public void RunAsync(Action action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe deferred action to Idling event to run it whenever Revit becomes idle.
|
||||
/// </summary>
|
||||
/// <param name="action"> Action to call whenever Revit becomes Idle.</param>
|
||||
/// some events in host app are trigerred many times, we might get 10x per object
|
||||
/// Making this more like a deferred action, so we don't update the UI many times
|
||||
public void SubscribeToIdle(string id, Action action) =>
|
||||
idleCallManager.SubscribeToIdle(
|
||||
id,
|
||||
action,
|
||||
() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_uiApplication.Idling += RevitAppOnIdle;
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// TODO: wrap this guy in the top level exception handler (?)
|
||||
// This happens very rarely, see previous report [CNX-125: Autodesk.Revit.Exceptions.InvalidOperationException: Can not subscribe to an event during execution of that event!](https://linear.app/speckle/issue/CNX-125/autodeskrevitexceptionsinvalidoperationexception-can-not-subscribe-to)
|
||||
}
|
||||
}
|
||||
);
|
||||
public sealed class RevitIdleManager : AppIdleManager, IRevitIdleManager
|
||||
{
|
||||
private readonly UIApplication _uiApplication;
|
||||
private readonly IIdleCallManager _idleCallManager;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
private event EventHandler<IdlingEventArgs>? OnIdle;
|
||||
|
||||
public RevitIdleManager(
|
||||
RevitContext revitContext,
|
||||
IIdleCallManager idleCallManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(idleCallManager)
|
||||
{
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_uiApplication = revitContext.UIApplication.NotNull();
|
||||
_idleCallManager = idleCallManager;
|
||||
_uiApplication.Idling += (s, e) => OnIdle?.Invoke(s, e); // will be called on the main thread always and fixing the Revit exceptions on subscribing/unsubscribing Idle events
|
||||
}
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
OnIdle += RevitAppOnIdle;
|
||||
});
|
||||
}
|
||||
|
||||
private void RevitAppOnIdle(object? sender, IdlingEventArgs e) =>
|
||||
idleCallManager.AppOnIdle(() => _uiApplication.Idling -= RevitAppOnIdle);
|
||||
_idleCallManager.AppOnIdle(() => OnIdle -= RevitAppOnIdle);
|
||||
|
||||
public void RunAsync(Action action)
|
||||
{
|
||||
|
||||
+5
-2
@@ -14,12 +14,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\BasicConnectorBindingRevit.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Filters.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitBaseBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\SelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ElementIdHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\APIContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\DocumentModelStorageSchema.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Elements.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RevitMaterialBaker.cs" />
|
||||
@@ -33,9 +33,12 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SendCollectionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\ElementUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\ITransactionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\RevitContextAccessor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\RevitHostObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\TransactionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\IRevitSendFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RevitCategoriesFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RevitSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RevitViewsFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\RevitRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\SendParameterNullOrEmptyStringsSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
|
||||
public abstract class SpeckleScopedTaskCapableComponent<TInput, TOutput>(
|
||||
string name,
|
||||
string nickname,
|
||||
string description,
|
||||
string category,
|
||||
string subCategory
|
||||
) : SpeckleTaskCapableComponent<TInput, TOutput>(name, nickname, description, category, subCategory)
|
||||
{
|
||||
protected override Task<TOutput> PerformTask(TInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
/*using*/var scope = PriorityLoader.Container.CreateScope(); // NOTE: this component does not work as intended in e.g the receive component; the scope gets disposed before the task completes.
|
||||
return PerformScopedTask(input, scope, cancellationToken);
|
||||
}
|
||||
|
||||
protected abstract Task<TOutput> PerformScopedTask(
|
||||
TInput input,
|
||||
IServiceScope scope,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
|
||||
public abstract class SpeckleTaskCapableComponent<TInput, TOutput>(
|
||||
string name,
|
||||
string nickname,
|
||||
string description,
|
||||
string category,
|
||||
string subCategory
|
||||
) : GH_TaskCapableComponent<TOutput>(name, nickname, description, category, subCategory)
|
||||
{
|
||||
protected override void SolveInstance(IGH_DataAccess da)
|
||||
{
|
||||
//TODO: We're missing activity and logging here. Will enable it for all inherited classes.
|
||||
|
||||
if (InPreSolve)
|
||||
{
|
||||
// Collect the data and create the task
|
||||
try
|
||||
{
|
||||
var input = GetInput(da);
|
||||
TaskList.Add(PerformTask(input, CancelToken));
|
||||
}
|
||||
catch (SpeckleException e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetSolveResults(da, out TOutput result))
|
||||
{
|
||||
// INFO: This will run synchronously. Useful for Rhino.Compute runs, but can also be enabled by user.
|
||||
try
|
||||
{
|
||||
TInput input = GetInput(da);
|
||||
var syncResult = PerformTask(input).Result;
|
||||
result = syncResult;
|
||||
}
|
||||
catch (SpeckleException e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (result is not null)
|
||||
{
|
||||
SetOutput(da, result);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract TInput GetInput(IGH_DataAccess da);
|
||||
|
||||
protected abstract void SetOutput(IGH_DataAccess da, TOutput result);
|
||||
|
||||
protected abstract Task<TOutput> PerformTask(TInput input, CancellationToken cancellationToken = default);
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
using Speckle.Connectors.Grasshopper8.Parameters;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
|
||||
|
||||
public record CreateCollectionComponentInput(
|
||||
Collection? Collection,
|
||||
string? Name,
|
||||
List<Base>? Elements,
|
||||
List<Collection>? Collections
|
||||
);
|
||||
|
||||
public record CreateCollectionComponentOutput(Collection Collection);
|
||||
|
||||
public class CreateCollectionComponent
|
||||
: SpeckleTaskCapableComponent<CreateCollectionComponentInput, CreateCollectionComponentOutput>
|
||||
{
|
||||
public CreateCollectionComponent()
|
||||
: base("Create Collection", "CrCol", "Creates a new collection", "Speckle", "Collections") { }
|
||||
|
||||
public override Guid ComponentGuid => new("6A9EDFDE-8AC4-4E28-B455-45DF42E2172B");
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
var colIndex = pManager.AddParameter(
|
||||
new SpeckleCollectionParam(GH_ParamAccess.item),
|
||||
"collection",
|
||||
"Collection",
|
||||
"Collection",
|
||||
GH_ParamAccess.item
|
||||
);
|
||||
var nameIndex = pManager.AddTextParameter("Name", "Name", "Name of the collection", GH_ParamAccess.item);
|
||||
|
||||
var elementsIndex = pManager.AddParameter(
|
||||
new SpeckleObjectParam(GH_ParamAccess.list),
|
||||
"elements",
|
||||
"Elements",
|
||||
"Elements of the collection",
|
||||
GH_ParamAccess.list
|
||||
);
|
||||
var collectionsIndex = pManager.AddParameter(
|
||||
new SpeckleCollectionParam(GH_ParamAccess.list),
|
||||
"collections",
|
||||
"Collections",
|
||||
"Sub-collections of the collection",
|
||||
GH_ParamAccess.list
|
||||
);
|
||||
|
||||
pManager[colIndex].Optional = true;
|
||||
pManager[nameIndex].Optional = true;
|
||||
pManager[elementsIndex].Optional = true;
|
||||
pManager[collectionsIndex].Optional = true;
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
var colIndex = pManager.AddParameter(
|
||||
new SpeckleCollectionParam(GH_ParamAccess.item),
|
||||
"collection",
|
||||
"Collection",
|
||||
"Collection",
|
||||
GH_ParamAccess.item
|
||||
);
|
||||
var nameIndex = pManager.AddTextParameter("Name", "Name", "Name of the collection", GH_ParamAccess.item);
|
||||
|
||||
var elementsIndex = pManager.AddParameter(
|
||||
new SpeckleObjectParam(GH_ParamAccess.list),
|
||||
"elements",
|
||||
"Elements",
|
||||
"Elements of the collection",
|
||||
GH_ParamAccess.list
|
||||
);
|
||||
var collectionsIndex = pManager.AddParameter(
|
||||
new SpeckleCollectionParam(GH_ParamAccess.list),
|
||||
"collections",
|
||||
"Collections",
|
||||
"Sub-collections of the collection",
|
||||
GH_ParamAccess.list
|
||||
);
|
||||
|
||||
pManager[colIndex].Optional = true;
|
||||
pManager[nameIndex].Optional = true;
|
||||
pManager[elementsIndex].Optional = true;
|
||||
pManager[collectionsIndex].Optional = true;
|
||||
}
|
||||
|
||||
protected override CreateCollectionComponentInput GetInput(IGH_DataAccess da)
|
||||
{
|
||||
Collection? collection = null;
|
||||
string? name = "";
|
||||
List<Base>? elements = new List<Base>();
|
||||
List<Collection>? collections = new List<Collection>();
|
||||
|
||||
da.GetData(0, ref collection);
|
||||
da.GetData(1, ref name);
|
||||
da.GetDataList(2, elements);
|
||||
da.GetDataList(3, collections);
|
||||
|
||||
return new CreateCollectionComponentInput(collection, name, elements, collections);
|
||||
}
|
||||
|
||||
protected override void SetOutput(IGH_DataAccess da, CreateCollectionComponentOutput result)
|
||||
{
|
||||
da.SetData(0, result.Collection);
|
||||
da.SetData(1, result.Collection.name);
|
||||
da.SetDataList(2, result.Collection.elements.Where(e => e is not Collection));
|
||||
da.SetDataList(3, result.Collection.elements.Where(e => e is Collection));
|
||||
}
|
||||
|
||||
protected override Task<CreateCollectionComponentOutput> PerformTask(
|
||||
CreateCollectionComponentInput input,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
if (input.Collection is null)
|
||||
{
|
||||
// Create new collection
|
||||
if (input.Name is null)
|
||||
{
|
||||
throw new SpeckleException("New collections must have a name");
|
||||
}
|
||||
|
||||
var collection = new Collection(input.Name) { elements = input.Elements ?? new List<Base>() };
|
||||
var result = new CreateCollectionComponentOutput(collection);
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
var collection = new Collection(input.Collection.name) { elements = input.Collection.elements };
|
||||
|
||||
// Create new collection
|
||||
if (input.Name is not null && input.Name.Length != 0)
|
||||
{
|
||||
collection.name = input.Name;
|
||||
}
|
||||
var elements = new List<Base>();
|
||||
if (input.Elements is not null && input.Elements.Count != 0)
|
||||
{
|
||||
elements.AddRange(input.Elements);
|
||||
}
|
||||
else
|
||||
{
|
||||
elements.AddRange(collection.elements.Where(e => e is not Collection));
|
||||
}
|
||||
|
||||
if (input.Collections is not null && input.Collections.Count != 0)
|
||||
{
|
||||
elements.AddRange(input.Collections);
|
||||
}
|
||||
else
|
||||
{
|
||||
elements.AddRange(collection.elements.Where(e => e is Collection));
|
||||
}
|
||||
|
||||
var result = new CreateCollectionComponentOutput(collection);
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
using System.Collections;
|
||||
using Grasshopper.Kernel;
|
||||
using Grasshopper.Kernel.Parameters;
|
||||
using Rhino.Display;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Grasshopper8.HostApp;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
|
||||
|
||||
#pragma warning disable CA1711
|
||||
public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
#pragma warning restore CA1711
|
||||
{
|
||||
public override Guid ComponentGuid => new("69BC8CFB-A72F-4A83-9263-F3399DDA2E5E");
|
||||
|
||||
public ExpandCollection()
|
||||
: base("Expand Collection", "expand", "Expands a new collection", "Speckle", "Collections") { }
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager) =>
|
||||
pManager.AddGenericParameter("Collection", "C", "Collection to unpack", GH_ParamAccess.item);
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
|
||||
|
||||
private List<SpeckleGrasshopperObject> _previewObjects = new();
|
||||
|
||||
protected override void SolveInstance(IGH_DataAccess da)
|
||||
{
|
||||
Collection res = new();
|
||||
da.GetData("Collection", ref res);
|
||||
var c = res;
|
||||
|
||||
Name = c.name;
|
||||
NickName = c.name;
|
||||
|
||||
var objects = c.elements.Where(el => el is not Collection).OfType<SpeckleGrasshopperObject>().ToList();
|
||||
var collections = c.elements.Where(el => el is Collection).OfType<Collection>().ToList();
|
||||
|
||||
var outputParams = new List<OutputParamWrapper>();
|
||||
if (objects.Count != 0)
|
||||
{
|
||||
var param = new Param_GenericObject()
|
||||
{
|
||||
Name = "Inner objects",
|
||||
NickName = "OBJS",
|
||||
Description =
|
||||
"Some collections may contain a mix of objects and other collections. Here we output the atomic objects from within this collection.",
|
||||
Access = GH_ParamAccess.list // NOTE: todo check on list if it's tree path-based
|
||||
};
|
||||
|
||||
outputParams.Add(new OutputParamWrapper(param, objects));
|
||||
}
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
// skip empty
|
||||
if (collection.elements.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasInnerCollections = collection.elements.Any(el => el is Collection);
|
||||
var isPathBasedCollection = collection["treePath"] as string; // Note: this is a reminder for the future
|
||||
var nickName = collection.name;
|
||||
if (collection.name.Length > 12)
|
||||
{
|
||||
nickName = collection.name[..3];
|
||||
nickName += "..." + collection.name[^3..];
|
||||
}
|
||||
|
||||
var param = new Param_GenericObject()
|
||||
{
|
||||
Name = collection.name,
|
||||
NickName = nickName,
|
||||
Access = hasInnerCollections ? GH_ParamAccess.item : GH_ParamAccess.list // we will directly set objects out; note access can be list or tree based on whether it will be a path based collection
|
||||
};
|
||||
if (!hasInnerCollections)
|
||||
{
|
||||
_previewObjects.AddRange(collection.elements.Cast<SpeckleGrasshopperObject>());
|
||||
}
|
||||
outputParams.Add(new OutputParamWrapper(param, hasInnerCollections ? collection : collection.elements));
|
||||
}
|
||||
|
||||
if (da.Iteration == 0 && OutputMismatch(outputParams))
|
||||
{
|
||||
OnPingDocument()
|
||||
.ScheduleSolution(
|
||||
5,
|
||||
_ =>
|
||||
{
|
||||
CreateOutputs(outputParams);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
_previewObjects = new();
|
||||
|
||||
FlattenForPreview(c);
|
||||
for (int i = 0; i < outputParams.Count; i++)
|
||||
{
|
||||
var outParam = Params.Output[i];
|
||||
switch (outParam.Access)
|
||||
{
|
||||
case GH_ParamAccess.item:
|
||||
da.SetData(i, outputParams[i].Values);
|
||||
break;
|
||||
case GH_ParamAccess.list:
|
||||
da.SetDataList(i, outputParams[i].Values as IList);
|
||||
break;
|
||||
case GH_ParamAccess.tree:
|
||||
//TODO: means we need to convert the collection to a tree
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FlattenForPreview(Collection c)
|
||||
{
|
||||
foreach (var element in c.elements)
|
||||
{
|
||||
if (element is Collection subCol)
|
||||
{
|
||||
FlattenForPreview(subCol);
|
||||
}
|
||||
|
||||
if (element is SpeckleGrasshopperObject sg)
|
||||
{
|
||||
_previewObjects.Add(sg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public override void DrawViewportWires(IGH_PreviewArgs args) => base.DrawViewportWires(args);
|
||||
public override void DrawViewportMeshes(IGH_PreviewArgs args)
|
||||
{
|
||||
if (_previewObjects.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var isSelected = args.Document.SelectedObjects().Contains(this);
|
||||
|
||||
using var displayMat = new DisplayMaterial(Color.CornflowerBlue, 0.1); // note can be coming from the actual render mat
|
||||
|
||||
foreach (var elem in _previewObjects)
|
||||
{
|
||||
switch (elem.GeometryBase)
|
||||
{
|
||||
case Mesh m:
|
||||
args.Display.DrawMeshShaded(m, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
|
||||
break;
|
||||
case Brep b:
|
||||
args.Display.DrawBrepShaded(b, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
|
||||
args.Display.DrawBrepWires(
|
||||
b,
|
||||
isSelected ? args.WireColour_Selected : args.WireColour,
|
||||
args.DefaultCurveThickness
|
||||
);
|
||||
break;
|
||||
case Extrusion e:
|
||||
args.Display.DrawMeshShaded(
|
||||
e.GetMesh(MeshType.Any),
|
||||
isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial
|
||||
);
|
||||
break;
|
||||
case SubD d:
|
||||
args.Display.DrawSubDShaded(d, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
|
||||
args.Display.DrawSubDWires(
|
||||
d,
|
||||
isSelected ? args.WireColour_Selected : args.WireColour,
|
||||
args.DefaultCurveThickness
|
||||
);
|
||||
break;
|
||||
case Curve c:
|
||||
args.Display.DrawCurve(
|
||||
c,
|
||||
isSelected ? args.WireColour_Selected : args.WireColour,
|
||||
args.DefaultCurveThickness
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool OutputMismatch(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
if (Params.Output.Count != outputParams.Count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
foreach (var newParam in outputParams)
|
||||
{
|
||||
var oldParam = Params.Output[count];
|
||||
if (
|
||||
oldParam.NickName != newParam.Param.NickName
|
||||
|| oldParam.Name != newParam.Param.Name
|
||||
|| oldParam.Access != newParam.Param.Access
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CreateOutputs(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
while (Params.Output.Count > 0)
|
||||
{
|
||||
Params.UnregisterOutputParameter(Params.Output[^1]);
|
||||
}
|
||||
|
||||
foreach (var newParam in outputParams)
|
||||
{
|
||||
var param = new Param_GenericObject
|
||||
{
|
||||
Name = newParam.Param.Name,
|
||||
NickName = newParam.Param.NickName,
|
||||
MutableNickName = false,
|
||||
Access = newParam.Param.Access // count == 0 ? GH_ParamAccess.list : GH_ParamAccess.item, // TODO: objects should always be a list or a tree, depending on whether the collection is a gh collection with a path prop
|
||||
};
|
||||
Params.RegisterOutputParam(param);
|
||||
}
|
||||
|
||||
Params.OnParametersChanged();
|
||||
VariableParameterMaintenance();
|
||||
ExpireSolution(false);
|
||||
}
|
||||
|
||||
public void VariableParameterMaintenance() { }
|
||||
|
||||
public bool CanInsertParameter(GH_ParameterSide side, int index) => false;
|
||||
|
||||
public bool CanRemoveParameter(GH_ParameterSide side, int index) => false;
|
||||
|
||||
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
|
||||
{
|
||||
var myParam = new Param_GenericObject
|
||||
{
|
||||
Name = GH_ComponentParamServer.InventUniqueNickname("ABCD", Params.Input),
|
||||
MutableNickName = true,
|
||||
Optional = true
|
||||
};
|
||||
myParam.NickName = myParam.Name;
|
||||
return myParam;
|
||||
}
|
||||
|
||||
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Output;
|
||||
}
|
||||
|
||||
public record OutputParamWrapper(Param_GenericObject Param, object Values);
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Grasshopper8.HostApp;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
|
||||
|
||||
#pragma warning disable CA1711
|
||||
public class FlattenCollection : GH_Component
|
||||
#pragma warning restore CA1711
|
||||
{
|
||||
public override Guid ComponentGuid => new Guid("720ED4BE-BA4B-4E85-8220-412B3DA1D2B7");
|
||||
|
||||
public FlattenCollection()
|
||||
: base("Flatten Collection", "flatten", "Flattens a collection into objects and paths", "Speckle", "Collections")
|
||||
{ }
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddGenericParameter("Collection", "C", "Collection to unpack", GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddGenericParameter("Objects", "O", "Objects", GH_ParamAccess.list);
|
||||
pManager.AddGenericParameter("Paths", "P", "Collection paths", GH_ParamAccess.list);
|
||||
}
|
||||
|
||||
protected override void SolveInstance(IGH_DataAccess dataAccess)
|
||||
{
|
||||
Collection res = new();
|
||||
dataAccess.GetData("Collection", ref res);
|
||||
|
||||
_sgos = new();
|
||||
Flatten(res);
|
||||
var paths = new List<string>();
|
||||
var objs = new List<GeometryBase>();
|
||||
foreach (var sg in _sgos)
|
||||
{
|
||||
var path = string.Join("::", sg.Path.Select(c => c.name));
|
||||
paths.Add(path);
|
||||
objs.Add(sg.GeometryBase);
|
||||
}
|
||||
|
||||
dataAccess.SetDataList(0, objs);
|
||||
dataAccess.SetDataList(1, paths);
|
||||
}
|
||||
|
||||
private List<SpeckleGrasshopperObject> _sgos = new();
|
||||
|
||||
public void Flatten(Collection c)
|
||||
{
|
||||
foreach (var element in c.elements)
|
||||
{
|
||||
if (element is Collection subCol)
|
||||
{
|
||||
Flatten(subCol);
|
||||
}
|
||||
|
||||
if (element is SpeckleGrasshopperObject sg)
|
||||
{
|
||||
_sgos.Add(sg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
using Speckle.Connectors.Grasshopper8.Parameters;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
|
||||
|
||||
public record UnpackRootObjectComponentInput(Base RootObject) { }
|
||||
|
||||
public record UnpackRootObjectComponentOutput(
|
||||
List<Base> Elements,
|
||||
List<string> ElementPaths,
|
||||
List<IInstanceComponent> Instances,
|
||||
List<string> InstancePaths
|
||||
) { }
|
||||
|
||||
public class UnpackRootObjectComponent
|
||||
: SpeckleScopedTaskCapableComponent<UnpackRootObjectComponentInput, UnpackRootObjectComponentOutput>
|
||||
{
|
||||
public UnpackRootObjectComponent()
|
||||
: base("Unpack Root Object", "SURO", "Unpacks the root object from a receive operation", "Speckle", "Collections")
|
||||
{ }
|
||||
|
||||
public override Guid ComponentGuid => new Guid("3C770686-20D5-434C-99E3-BDE735E8267F");
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(new SpeckleObjectParam(GH_ParamAccess.item));
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddTextParameter("Element Paths", "EP", "Path to the element in the collection tree", GH_ParamAccess.list);
|
||||
pManager.AddParameter(new SpeckleObjectParam(), "Elements", "E", "Elements", GH_ParamAccess.list);
|
||||
pManager.AddTextParameter(
|
||||
"Instance Paths",
|
||||
"IP",
|
||||
"Path to the instance in the collection tree",
|
||||
GH_ParamAccess.list
|
||||
);
|
||||
pManager.AddParameter(new SpeckleObjectParam(), "Instances", "I", "Instances", GH_ParamAccess.list);
|
||||
}
|
||||
|
||||
protected override UnpackRootObjectComponentInput GetInput(IGH_DataAccess da)
|
||||
{
|
||||
Base? baseObject = null;
|
||||
da.GetData(0, ref baseObject);
|
||||
if (baseObject == null)
|
||||
{
|
||||
throw new SpeckleException("No base object provided");
|
||||
}
|
||||
return new UnpackRootObjectComponentInput(baseObject);
|
||||
}
|
||||
|
||||
protected override void SetOutput(IGH_DataAccess da, UnpackRootObjectComponentOutput result)
|
||||
{
|
||||
da.SetDataList(0, result.ElementPaths);
|
||||
da.SetDataList(1, result.Elements);
|
||||
da.SetDataList(2, result.InstancePaths);
|
||||
da.SetDataList(3, result.Instances);
|
||||
}
|
||||
|
||||
protected override async Task<UnpackRootObjectComponentOutput> PerformScopedTask(
|
||||
UnpackRootObjectComponentInput input,
|
||||
IServiceScope scope,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var rootObjectUnpacker = scope.ServiceProvider.GetRequiredService<RootObjectUnpacker>();
|
||||
var contextUnpacker = scope.ServiceProvider.GetRequiredService<TraversalContextUnpacker>();
|
||||
|
||||
var unpackedRoot = rootObjectUnpacker.Unpack(input.RootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
);
|
||||
|
||||
var atomicObjectsWithPath = contextUnpacker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = contextUnpacker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
|
||||
// 2.1 - these are not captured by traversal, so we need to re-add them here
|
||||
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
|
||||
{
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
var applicationIdMap = new Dictionary<string, Base>();
|
||||
atomicObjectsWithPath.ForEach(a => applicationIdMap.Add(a.current.applicationId ?? a.current.id, a.current));
|
||||
|
||||
var instanceResult = await ProcessInstances(instanceComponentsWithPath, applicationIdMap).ConfigureAwait(false);
|
||||
|
||||
foreach (string objId in instanceResult.ConsumedObjectIds)
|
||||
{
|
||||
var indexAtomic = atomicObjectsWithPath.FindIndex(o => o.current.id == objId);
|
||||
if (indexAtomic != -1)
|
||||
{
|
||||
atomicObjectsWithPath.RemoveAt(indexAtomic);
|
||||
}
|
||||
// HACK: Why is instancecomponent not ISpeckleObject?
|
||||
var indexInstance = instanceComponentsWithPath.FindIndex(o => ((Base)o.instance).id == objId);
|
||||
if (indexInstance != -1)
|
||||
{
|
||||
instanceComponentsWithPath.RemoveAt(indexInstance);
|
||||
}
|
||||
}
|
||||
|
||||
var elements = new List<Base>();
|
||||
var instances = new List<IInstanceComponent>();
|
||||
var elementPaths = new List<string>();
|
||||
var instancePaths = new List<string>();
|
||||
|
||||
atomicObjectsWithPath.ForEach(atomicObj =>
|
||||
{
|
||||
var names = atomicObj.path.Select(p => p.name);
|
||||
elements.Add(atomicObj.current);
|
||||
elementPaths.Add(string.Join("::", names));
|
||||
});
|
||||
|
||||
instanceComponentsWithPath.ForEach(instanceObj =>
|
||||
{
|
||||
var names = instanceObj.path.Select(p => p.name);
|
||||
instances.Add(instanceObj.instance);
|
||||
instancePaths.Add(string.Join("::", names));
|
||||
});
|
||||
|
||||
var output = new UnpackRootObjectComponentOutput(elements, elementPaths, instances, instancePaths);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public Task<BakeResult> ProcessInstances(
|
||||
IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
Dictionary<string, Base> applicationIdMap
|
||||
)
|
||||
{
|
||||
var sortedInstanceComponents = instanceComponents
|
||||
.OrderByDescending(x => x.obj.maxDepth) // Sort by max depth, so we start baking from the deepest element first
|
||||
.ThenBy(x => x.obj is InstanceDefinitionProxy ? 0 : 1) // Ensure we bake the deepest definition first, then any instances that depend on it
|
||||
.ToList();
|
||||
|
||||
var definitionObjectsMap = new Dictionary<string, (InstanceDefinitionProxy, List<Base>)>();
|
||||
|
||||
var consumedObjectIds = new List<string>();
|
||||
foreach (var (layerCollection, instanceOrDefinition) in sortedInstanceComponents)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (instanceOrDefinition is InstanceDefinitionProxy definitionProxy)
|
||||
{
|
||||
var currentSpeckleObjects = definitionProxy
|
||||
.objects.Where(applicationIdMap.ContainsKey)
|
||||
.Select(x => applicationIdMap[x])
|
||||
.ToList();
|
||||
|
||||
definitionObjectsMap.Add(
|
||||
definitionProxy.applicationId ?? definitionProxy.id,
|
||||
(definitionProxy, currentSpeckleObjects)
|
||||
);
|
||||
|
||||
consumedObjectIds.AddRange(currentSpeckleObjects.Select(o => o.id));
|
||||
consumedObjectIds.Add(definitionProxy.id);
|
||||
}
|
||||
|
||||
if (
|
||||
instanceOrDefinition is InstanceProxy instanceProxy
|
||||
&& definitionObjectsMap.TryGetValue(instanceProxy.definitionId, out var definition)
|
||||
)
|
||||
{
|
||||
instanceProxy["__geometry"] = definition.Item2;
|
||||
instanceProxy["__definition"] = definition.Item1;
|
||||
applicationIdMap[instanceProxy.applicationId ?? instanceProxy.id] = instanceProxy;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
//_logger.LogError(ex, "Failed to create an instance from proxy");
|
||||
}
|
||||
}
|
||||
|
||||
//await Task.Yield();
|
||||
BakeResult processInstances = new(new List<string>(), consumedObjectIds, new List<ReceiveConversionResult>());
|
||||
return Task.FromResult(processInstances);
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Rhino;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
using Speckle.Connectors.Grasshopper8.Parameters;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Conversion;
|
||||
|
||||
public static class RhinoUnitsExtension
|
||||
{
|
||||
public static string ToSpeckleString(this UnitSystem unitSystem)
|
||||
{
|
||||
switch (unitSystem)
|
||||
{
|
||||
case UnitSystem.None:
|
||||
return Units.Meters;
|
||||
case UnitSystem.Millimeters:
|
||||
return Units.Millimeters;
|
||||
case UnitSystem.Centimeters:
|
||||
return Units.Centimeters;
|
||||
case UnitSystem.Meters:
|
||||
return Units.Meters;
|
||||
case UnitSystem.Kilometers:
|
||||
return Units.Kilometers;
|
||||
case UnitSystem.Inches:
|
||||
return Units.Inches;
|
||||
case UnitSystem.Feet:
|
||||
return Units.Feet;
|
||||
case UnitSystem.Yards:
|
||||
return Units.Yards;
|
||||
case UnitSystem.Miles:
|
||||
return Units.Miles;
|
||||
case UnitSystem.Unset:
|
||||
return Units.Meters;
|
||||
default:
|
||||
throw new UnitNotSupportedException($"The Unit System \"{unitSystem}\" is unsupported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ToNativeConversion()
|
||||
: SpeckleScopedTaskCapableComponent<Base, List<GeometryBase>>(
|
||||
"ToNativeConversion",
|
||||
"STN",
|
||||
"Converts a speckle object to rhino",
|
||||
"Speckle",
|
||||
"Conversion"
|
||||
)
|
||||
{
|
||||
public override Guid ComponentGuid => new Guid("38BAB10C-4D80-4E0C-8235-A87C3E66F55F");
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(new SpeckleObjectParam(GH_ParamAccess.item));
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddGeometryParameter("Geometry", "Geometry", "Geometry", GH_ParamAccess.list);
|
||||
}
|
||||
|
||||
protected override Base GetInput(IGH_DataAccess da)
|
||||
{
|
||||
Base? input = null;
|
||||
if (!da.GetData(0, ref input) || input is null)
|
||||
{
|
||||
throw new SpeckleException("Input is not valid");
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
protected override void SetOutput(IGH_DataAccess da, List<GeometryBase> result)
|
||||
{
|
||||
da.SetDataList(0, result);
|
||||
}
|
||||
|
||||
protected override Task<List<GeometryBase>> PerformScopedTask(
|
||||
Base input,
|
||||
IServiceScope scope,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
|
||||
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
|
||||
|
||||
var rootConverter = scope.ServiceProvider.GetRequiredService<IRootToHostConverter>();
|
||||
|
||||
if (input is InstanceProxy proxy)
|
||||
{
|
||||
var geometries = proxy["__geometry"] as List<Base>;
|
||||
var converted = geometries.SelectMany(g => Convert(g, rootConverter)).ToList();
|
||||
var transform = MatrixToTransform(proxy.transform, proxy.units);
|
||||
converted.ForEach(c => c.Transform(transform));
|
||||
return Task.FromResult(converted);
|
||||
}
|
||||
|
||||
return Task.FromResult(Convert(input, rootConverter));
|
||||
}
|
||||
|
||||
private List<GeometryBase> Convert(Base input, IRootToHostConverter rootConverter)
|
||||
{
|
||||
var result = rootConverter.Convert(input);
|
||||
|
||||
if (result is GeometryBase geometry)
|
||||
{
|
||||
return new List<GeometryBase> { geometry };
|
||||
}
|
||||
else if (result is List<GeometryBase> geometryList)
|
||||
{
|
||||
return geometryList;
|
||||
}
|
||||
|
||||
throw new SpeckleException("Failed to convert input to rhino");
|
||||
}
|
||||
|
||||
private Transform MatrixToTransform(Matrix4x4 matrix, string units)
|
||||
{
|
||||
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
|
||||
var conversionFactor = Units.GetConversionFactor(units, currentDoc.ModelUnitSystem.ToSpeckleString());
|
||||
|
||||
var t = Transform.Identity;
|
||||
t.M00 = matrix.M11;
|
||||
t.M01 = matrix.M12;
|
||||
t.M02 = matrix.M13;
|
||||
t.M03 = matrix.M14 * conversionFactor;
|
||||
|
||||
t.M10 = matrix.M21;
|
||||
t.M11 = matrix.M22;
|
||||
t.M12 = matrix.M23;
|
||||
t.M13 = matrix.M24 * conversionFactor;
|
||||
|
||||
t.M20 = matrix.M31;
|
||||
t.M21 = matrix.M32;
|
||||
t.M22 = matrix.M33;
|
||||
t.M23 = matrix.M34 * conversionFactor;
|
||||
|
||||
t.M30 = matrix.M41;
|
||||
t.M31 = matrix.M42;
|
||||
t.M32 = matrix.M43;
|
||||
t.M33 = matrix.M44;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Rhino;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
using Speckle.Connectors.Grasshopper8.Components.Operations.Conversion;
|
||||
using Speckle.Connectors.Grasshopper8.HostApp;
|
||||
using Speckle.Connectors.Grasshopper8.Parameters;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Api;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Credentials;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Receive;
|
||||
|
||||
public class ReceiveComponentOutput
|
||||
{
|
||||
public Collection RootObject { get; set; }
|
||||
}
|
||||
|
||||
public class ReceiveComponent : SpeckleScopedTaskCapableComponent<SpeckleUrlModelResource, ReceiveComponentOutput>
|
||||
{
|
||||
public ReceiveComponent()
|
||||
: base("Receive from Speckle", "RFS", "Receive objects from speckle", "Speckle", "Operations") { }
|
||||
|
||||
public override Guid ComponentGuid => new("74954F59-B1B7-41FD-97DE-4C6B005F2801");
|
||||
protected override Bitmap Icon => BitmapBuilder.CreateSquareIconBitmap("R");
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(new SpeckleUrlModelResourceParam(GH_ParamAccess.item));
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(
|
||||
new SpeckleObjectParam(GH_ParamAccess.item),
|
||||
"Model",
|
||||
"model",
|
||||
"The model object for the received version",
|
||||
GH_ParamAccess.item
|
||||
);
|
||||
}
|
||||
|
||||
protected override SpeckleUrlModelResource GetInput(IGH_DataAccess da)
|
||||
{
|
||||
SpeckleUrlModelResource? url = null;
|
||||
da.GetData(0, ref url);
|
||||
if (url is null)
|
||||
{
|
||||
throw new SpeckleException("Speckle url is null");
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
protected override void SetOutput(IGH_DataAccess da, ReceiveComponentOutput result)
|
||||
{
|
||||
da.SetData(0, result.RootObject);
|
||||
Message = "Done";
|
||||
}
|
||||
|
||||
protected override async Task<ReceiveComponentOutput> PerformScopedTask(
|
||||
SpeckleUrlModelResource input,
|
||||
IServiceScope scope,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
// TODO: Resolving dependencies here may be overkill in most cases. Must re-evaluate.
|
||||
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
|
||||
|
||||
var rootConverter = scope.ServiceProvider.GetService<IRootToHostConverter>();
|
||||
|
||||
var accountManager = scope.ServiceProvider.GetRequiredService<AccountService>();
|
||||
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
|
||||
var receiveOperation = scope.ServiceProvider.GetRequiredService<GrasshopperReceiveOperation>();
|
||||
|
||||
// Do the thing 👇🏼
|
||||
|
||||
// TODO: Get any account for this server, as we don't have a mechanism yet to pass accountIds through
|
||||
var account = accountManager.GetAccountWithServerUrlFallback("", new Uri(input.Server));
|
||||
|
||||
if (account is null)
|
||||
{
|
||||
throw new SpeckleAccountManagerException($"No default account was found");
|
||||
}
|
||||
|
||||
using var client = clientFactory.Create(account);
|
||||
var receiveInfo = await input.GetReceiveInfo(client, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var progress = new Progress<CardProgress>(_ =>
|
||||
{
|
||||
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
|
||||
// Message = $"{progress.Status}: {progress.Progress}";
|
||||
});
|
||||
|
||||
var root = await receiveOperation
|
||||
.ReceiveCommitObject(receiveInfo, progress, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We need to rething these lovely unpackers, there's a bit too many of 'em
|
||||
var rootObjectUnpacker = scope.ServiceProvider.GetService<RootObjectUnpacker>();
|
||||
var localToGlobalUnpacker = new LocalToGlobalUnpacker();
|
||||
var traversalContextUnpacker = new TraversalContextUnpacker();
|
||||
|
||||
var unpackedRoot = rootObjectUnpacker.Unpack(root);
|
||||
var localToGlobalMaps = localToGlobalUnpacker.Unpack(
|
||||
unpackedRoot.DefinitionProxies,
|
||||
unpackedRoot.ObjectsToConvert.ToList()
|
||||
);
|
||||
|
||||
var collGen = new CollectionRebuilder((root as Collection) ?? new Collection() { name = "unnamed" });
|
||||
var results = new List<SpeckleGrasshopperObject>();
|
||||
foreach (var map in localToGlobalMaps)
|
||||
{
|
||||
try
|
||||
{
|
||||
var converted = Convert(map.AtomicObject, rootConverter);
|
||||
var path = traversalContextUnpacker.GetCollectionPath(map.TraversalContext).ToList();
|
||||
|
||||
foreach (var matrix in map.Matrix)
|
||||
{
|
||||
var mat = MatrixToTransform(matrix, "meters");
|
||||
converted.ForEach(res => res.Transform(mat));
|
||||
}
|
||||
|
||||
foreach (var geometryBase in converted)
|
||||
{
|
||||
var gh = new SpeckleGrasshopperObject()
|
||||
{
|
||||
OriginalObject = map.AtomicObject,
|
||||
Path = path,
|
||||
GeometryBase = geometryBase
|
||||
};
|
||||
collGen.AppendSpeckleGrasshopperObject(gh);
|
||||
}
|
||||
}
|
||||
catch (ConversionException)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// var x = new SpeckleCollectionGoo { Value = collGen.RootCollection };
|
||||
return new ReceiveComponentOutput { RootObject = collGen.RootCollection };
|
||||
}
|
||||
|
||||
private List<GeometryBase> Convert(Base input, IRootToHostConverter rootConverter)
|
||||
{
|
||||
var result = rootConverter.Convert(input);
|
||||
|
||||
if (result is GeometryBase geometry)
|
||||
{
|
||||
return new List<GeometryBase> { geometry };
|
||||
}
|
||||
else if (result is List<GeometryBase> geometryList)
|
||||
{
|
||||
return geometryList;
|
||||
}
|
||||
else if (result is IEnumerable<(object, Base)> fallbackConversionResult)
|
||||
{
|
||||
// note special handling for proxying render materials OR we don't care about revit
|
||||
return fallbackConversionResult.Select(t => t.Item1).Cast<GeometryBase>().ToList();
|
||||
}
|
||||
|
||||
throw new SpeckleException("Failed to convert input to rhino");
|
||||
}
|
||||
|
||||
private Transform MatrixToTransform(Matrix4x4 matrix, string units)
|
||||
{
|
||||
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
|
||||
var conversionFactor = Units.GetConversionFactor(units, currentDoc.ModelUnitSystem.ToSpeckleString());
|
||||
|
||||
var t = Transform.Identity;
|
||||
t.M00 = matrix.M11;
|
||||
t.M01 = matrix.M12;
|
||||
t.M02 = matrix.M13;
|
||||
t.M03 = matrix.M14 * conversionFactor;
|
||||
|
||||
t.M10 = matrix.M21;
|
||||
t.M11 = matrix.M22;
|
||||
t.M12 = matrix.M23;
|
||||
t.M13 = matrix.M24 * conversionFactor;
|
||||
|
||||
t.M20 = matrix.M31;
|
||||
t.M21 = matrix.M32;
|
||||
t.M22 = matrix.M33;
|
||||
t.M23 = matrix.M34 * conversionFactor;
|
||||
|
||||
t.M30 = matrix.M41;
|
||||
t.M31 = matrix.M42;
|
||||
t.M32 = matrix.M43;
|
||||
t.M33 = matrix.M44;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: We will need GrasshopperCollections (with an extra path element)
|
||||
// these will need to be handled now
|
||||
public class CollectionRebuilder
|
||||
{
|
||||
public Collection RootCollection { get; }
|
||||
|
||||
private readonly Dictionary<string, Collection> _cache = new();
|
||||
|
||||
public CollectionRebuilder(Collection baseCollection)
|
||||
{
|
||||
RootCollection = new Collection() { name = baseCollection.name, applicationId = baseCollection.applicationId };
|
||||
}
|
||||
|
||||
public void AppendSpeckleGrasshopperObject(SpeckleGrasshopperObject speckleGrasshopperObject)
|
||||
{
|
||||
// TODO
|
||||
var collection = GetOrCreateCollectionFromPath(speckleGrasshopperObject.Path);
|
||||
collection.elements.Add(speckleGrasshopperObject);
|
||||
}
|
||||
|
||||
public Collection GetOrCreateCollectionFromPath(IEnumerable<Collection> path)
|
||||
{
|
||||
// TODO - this flows but it can be optimised (ie, concat path first, check cache, iterate only if not in cache)
|
||||
var currentLayerName = "";
|
||||
Collection previousCollection = RootCollection;
|
||||
foreach (var collection in path)
|
||||
{
|
||||
currentLayerName += collection.name;
|
||||
if (_cache.TryGetValue(currentLayerName, out Collection col))
|
||||
{
|
||||
previousCollection = col;
|
||||
continue;
|
||||
}
|
||||
|
||||
var newCollection = new Collection() { name = collection.name };
|
||||
_cache[currentLayerName] = newCollection;
|
||||
previousCollection.elements.Add(newCollection);
|
||||
|
||||
previousCollection = newCollection;
|
||||
}
|
||||
|
||||
return previousCollection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Rhino;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Grasshopper8.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Credentials;
|
||||
using Speckle.Sdk.Models;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components;
|
||||
|
||||
public class SpeckleFirstComponent : GH_TaskCapableComponent<List<object?>>
|
||||
{
|
||||
private readonly AccountManager _accountManager;
|
||||
|
||||
/// <summary>
|
||||
/// Each implementation of GH_Component must provide a public
|
||||
/// constructor without any arguments.
|
||||
/// Category represents the Tab in which the component will appear,
|
||||
/// Subcategory the panel. If you use non-existing tab or panel names,
|
||||
/// new tabs/panels will automatically be created.
|
||||
/// </summary>
|
||||
public SpeckleFirstComponent()
|
||||
: base("First Speckle Component", "STP", "Sends objects to speckle", "Speckle", "Other")
|
||||
{
|
||||
_accountManager = PriorityLoader.Container.NotNull().GetRequiredService<AccountManager>();
|
||||
}
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddTextParameter("Model/Version URL", "url", "The model or version url to receive", GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddGenericParameter("Result", "R", "Result", GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
protected override void SolveInstance(IGH_DataAccess da)
|
||||
{
|
||||
if (InPreSolve)
|
||||
{
|
||||
// Collect the data and create the task
|
||||
string url = GetInput(da);
|
||||
Message = "Receiving...";
|
||||
TaskList.Add(PerformReceiveOperation(url, CancelToken));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetSolveResults(da, out List<object?> result))
|
||||
{
|
||||
// INFO: This will run synchronously. Useful for Rhino.Compute runs, but can also be enabled by user.
|
||||
string url = GetInput(da);
|
||||
var syncResult = PerformReceiveOperation(url).Result;
|
||||
SetOutput(da, syncResult);
|
||||
}
|
||||
|
||||
if (result is not null)
|
||||
{
|
||||
SetOutput(da, result);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetOutput(IGH_DataAccess da, List<object?> result)
|
||||
{
|
||||
da.SetDataList(0, result);
|
||||
Message = "Done";
|
||||
}
|
||||
|
||||
private string GetInput(IGH_DataAccess da)
|
||||
{
|
||||
string url = "";
|
||||
da.GetData(0, ref url);
|
||||
return url;
|
||||
}
|
||||
|
||||
private async Task<List<object?>> PerformReceiveOperation(string url, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// TODO: URL Parsing must be done here
|
||||
Console.WriteLine($"Receiving from fake url, skipping input: {url}");
|
||||
|
||||
var account = _accountManager.GetDefaultAccount();
|
||||
if (account is null)
|
||||
{
|
||||
throw new SpeckleAccountManagerException($"No default account was found");
|
||||
}
|
||||
|
||||
var receiveInfo = new ReceiveInfo(
|
||||
account.id,
|
||||
new Uri(account.serverInfo.url),
|
||||
"2295cb26a0",
|
||||
"",
|
||||
"bd1fd98086",
|
||||
"",
|
||||
"832e036b91",
|
||||
""
|
||||
);
|
||||
|
||||
var progress = new Progress<CardProgress>(progress =>
|
||||
{
|
||||
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
|
||||
// Message = $"{progress.Status}: {progress.Progress}";
|
||||
});
|
||||
|
||||
using var scope = PriorityLoader.Container.CreateScope();
|
||||
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory =
|
||||
scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
|
||||
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
|
||||
|
||||
var receiveOperation = scope.ServiceProvider.GetRequiredService<ReceiveOperation>();
|
||||
var result = await receiveOperation.Execute(receiveInfo, progress, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
List<object?> results = new();
|
||||
// HACK: GrashhopperHostObjectBuilder returns a specific subclass that contains the result object as well.
|
||||
foreach (var conversionResult in result.ConversionResults)
|
||||
{
|
||||
if (conversionResult is not GrasshopperReceiveConversionResult ghConversionResult)
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported conversion result type: {conversionResult}");
|
||||
}
|
||||
|
||||
//results.Add(ghConversionResult.Source);
|
||||
if (ghConversionResult.Result is GeometryBase geometryBase)
|
||||
{
|
||||
results.Add(geometryBase);
|
||||
}
|
||||
else if (ghConversionResult.Result is List<GeometryBase> geometryBases) // one to many raw encoding case
|
||||
{
|
||||
results.AddRange(geometryBases);
|
||||
}
|
||||
else if (ghConversionResult.Result is IEnumerable<(object, Base)> fallbackConversionResult) // one to many fallback conversion
|
||||
{
|
||||
results.AddRange(fallbackConversionResult.Select(o => o.Item1));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public override Guid ComponentGuid => new Guid("c123402d-6b40-4619-bb3b-88eb3fc8bb7a");
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using Grasshopper.Kernel;
|
||||
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
|
||||
using Speckle.Connectors.Grasshopper8.HostApp;
|
||||
using Speckle.Connectors.Grasshopper8.Parameters;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.Components;
|
||||
|
||||
public class SpeckleResourceFromUrlComponent : SpeckleTaskCapableComponent<string, SpeckleUrlModelResource[]>
|
||||
{
|
||||
public SpeckleResourceFromUrlComponent()
|
||||
: base("Speckle Resource From Url", "spcklUrl", "Speckle resource from url", "Speckle", "Resources") { }
|
||||
|
||||
public override Guid ComponentGuid => new("A55C74C6-D955-4822-84BB-2266A2B965EE");
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddTextParameter("URL", "URL", "URL to send to resource", GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(new SpeckleUrlModelResourceParam(GH_ParamAccess.list));
|
||||
}
|
||||
|
||||
protected override string GetInput(IGH_DataAccess da)
|
||||
{
|
||||
string url = string.Empty;
|
||||
da.GetData(0, ref url);
|
||||
return url;
|
||||
}
|
||||
|
||||
protected override void SetOutput(IGH_DataAccess da, SpeckleUrlModelResource[] result)
|
||||
{
|
||||
da.SetDataList(0, result);
|
||||
}
|
||||
|
||||
protected override Task<SpeckleUrlModelResource[]> PerformTask(
|
||||
string input,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var resources = SpeckleResourceBuilder.FromUrlString(input);
|
||||
|
||||
// TODO: Here's where we can validate the resources and throw or not?
|
||||
|
||||
return Task.FromResult(resources);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Speckle.Connectors.Grasshopper8.HostApp;
|
||||
|
||||
public static class BitmapBuilder
|
||||
{
|
||||
public static Bitmap CreateSquareIconBitmap(string text, int width = 24, int height = 24)
|
||||
{
|
||||
Bitmap bitmap = new(width, height);
|
||||
using Graphics graphics = Graphics.FromImage(bitmap);
|
||||
|
||||
// Enable high-quality rendering
|
||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
// Set background to transparent
|
||||
graphics.Clear(Color.Transparent);
|
||||
|
||||
// Rectangle with a 1px offset
|
||||
Rectangle squareRect = new(1, 1, width - 2, height - 2);
|
||||
|
||||
using (Brush blueBrush = new SolidBrush(Color.Blue))
|
||||
{
|
||||
graphics.FillRectangle(blueBrush, squareRect);
|
||||
}
|
||||
|
||||
// Draw white letters in the center
|
||||
using (Font font = new("Arial", 8, FontStyle.Bold, GraphicsUnit.Pixel))
|
||||
using (Brush whiteBrush = new SolidBrush(Color.White))
|
||||
{
|
||||
StringFormat format = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
|
||||
|
||||
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
|
||||
graphics.DrawString(text, font, whiteBrush, new RectangleF(1, 1, width - 2, height - 2), format);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap CreateHexagonalBitmap(string text, int width = 24, int height = 24)
|
||||
{
|
||||
Bitmap bitmap = new(width, height);
|
||||
using Graphics graphics = Graphics.FromImage(bitmap);
|
||||
|
||||
// Enable high-quality rendering
|
||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
// Set background to transparent
|
||||
graphics.Clear(Color.Transparent);
|
||||
|
||||
// Calculate hexagon points centered within the bitmap
|
||||
float side = (width - 2) / 2.236f; // 2.236f approximates 4 / √3 for regular hex dimensions
|
||||
float h = side * (float)Math.Sqrt(3) / 2;
|
||||
float centerX = width / 2f;
|
||||
float centerY = height / 2f;
|
||||
|
||||
Point[] hexagonPoints =
|
||||
[
|
||||
new((int)(centerX - side / 2), (int)(centerY - h)),
|
||||
new((int)(centerX + side / 2), (int)(centerY - h)),
|
||||
new((int)(centerX + side), (int)centerY),
|
||||
new((int)(centerX + side / 2), (int)(centerY + h)),
|
||||
new((int)(centerX - side / 2), (int)(centerY + h)),
|
||||
new((int)(centerX - side), (int)centerY)
|
||||
];
|
||||
|
||||
using (Brush blueBrush = new SolidBrush(Color.Blue))
|
||||
{
|
||||
graphics.FillPolygon(blueBrush, hexagonPoints);
|
||||
}
|
||||
|
||||
// Draw white letters in the center
|
||||
using Font font = new("Monospace", 10, FontStyle.Bold, GraphicsUnit.Pixel);
|
||||
using Brush whiteBrush = new SolidBrush(Color.White);
|
||||
StringFormat format = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
|
||||
|
||||
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
|
||||
graphics.DrawString(text, font, whiteBrush, new RectangleF(0, 1, width, height), format);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user