Compare commits
479 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b591e82804 | |||
| 0585b531d5 | |||
| b49884e211 | |||
| 1b9640954e | |||
| 3d24a7b16b | |||
| 9f3a333beb | |||
| 3bb0860d14 | |||
| 6c2a98c1d4 | |||
| 4cbf5628b1 | |||
| 0441cf7e3c | |||
| 7860c44f4e | |||
| 38b9415e81 | |||
| a1f392a33b | |||
| 24442ab0a9 | |||
| 47344e0af3 | |||
| 0d09ea5158 | |||
| 3be24d5b15 | |||
| 8bbb9b893e | |||
| 85b2b21294 | |||
| 63d6d1a52b | |||
| 6e3eab30a4 | |||
| 4d94cd76b6 | |||
| faae9bac62 | |||
| eca1dab265 | |||
| 8a3249d3db | |||
| c08c9559c7 | |||
| a59f3179f1 | |||
| e4f4a5533d | |||
| 259b6a59f1 | |||
| a4a2655a2a | |||
| 9dd6397b01 | |||
| 2a04c02cba | |||
| 0670c1866f | |||
| 60bb160a0d | |||
| 9127284774 | |||
| 0ea495e698 | |||
| 8673879e48 | |||
| 8d04c9f9c8 | |||
| d73ac2446a | |||
| 3edc877466 | |||
| 9a3d41db3d | |||
| eb166c0931 | |||
| cb15106ca7 | |||
| 3768157efe | |||
| ab0ebd5f46 | |||
| c51a0fda53 | |||
| 4fdc522e42 | |||
| 5290859bf0 | |||
| f65bafde78 | |||
| f37eef7dc0 | |||
| b08ceb3f66 | |||
| a0e23e6acd | |||
| 920f3b3032 | |||
| 94eca4e031 | |||
| 389204a0d1 | |||
| cd30370654 | |||
| 9b9c383128 | |||
| e87eebefd1 | |||
| c5deaf4844 | |||
| 882358e22a | |||
| 532adb855f | |||
| 40d91649af | |||
| 1d8e19293d | |||
| be6cd69d16 | |||
| 5a554e7cf7 | |||
| d773c1fff4 | |||
| a26d06434f | |||
| a07b6f6d94 | |||
| b06fcc484e | |||
| db205024cc | |||
| fa8e4d2528 | |||
| 31c2d8d5b3 | |||
| e22527f85e | |||
| f082cf6723 | |||
| c4184f2662 | |||
| c0b38f0e12 | |||
| 4a88380fd2 | |||
| 04132e88ac | |||
| 3e3003827b | |||
| e3bd4f6365 | |||
| 6e6d52509c | |||
| 637ffbfc54 | |||
| 32b26f8c86 | |||
| c41c57544a | |||
| 6687383ce4 | |||
| f08d52e080 | |||
| 4dcf9910a5 | |||
| 9a61ded43e | |||
| 5acb0b80ab | |||
| ba41ceca2f | |||
| 8474088e5b | |||
| fe042d7a1c | |||
| d681c63a05 | |||
| bdc0e2b5bd | |||
| 6dc1726536 | |||
| 46198934ec | |||
| b4191d1d65 | |||
| f007e28565 | |||
| d05667dac8 | |||
| c922976bcd | |||
| c3aa44dfc2 | |||
| e1a64189c8 | |||
| b0e0669cab | |||
| b2a14e055c | |||
| 74f4525ff2 | |||
| bb57b31ae4 | |||
| d33a6ca358 | |||
| a8cc4cebc7 | |||
| 678ba417d2 | |||
| bc9fbe3cf7 | |||
| b09f085f07 | |||
| 539ae1fc78 | |||
| cc47dfaac6 | |||
| 691235a7ac | |||
| deff607bcb | |||
| cfb8aba55f | |||
| 4bcc0d83a9 | |||
| 605d6faf42 | |||
| 28c5f1276a | |||
| e80fe30acb | |||
| 034e1dcef8 | |||
| dd34625acb | |||
| 3090b5f5bb | |||
| 7c609c93ae | |||
| 36a6572483 | |||
| ce04d2fd55 | |||
| 4dbe4dd9a0 | |||
| 6f72402b76 | |||
| a7b3ae8780 | |||
| 5da534aeb7 | |||
| 93ede98135 | |||
| 03cffcdf4c | |||
| c533d0922a | |||
| c24fb7eaa0 | |||
| 0b246cf95c | |||
| 003e310089 | |||
| 5917530761 | |||
| 349009314b | |||
| 659a29a294 | |||
| 1ffeddbc2c | |||
| 9d9a27d9cb | |||
| b2a885c193 | |||
| 60c1811fa6 | |||
| 5365809172 | |||
| 3876f7d220 | |||
| d4ee1f2a55 | |||
| 4f960cc670 | |||
| 1f63c1f8b3 | |||
| 2ed9ffbca7 | |||
| d87b862e2b | |||
| 3ad3ad2f01 | |||
| 6db7e46401 | |||
| 13fc24c7c7 | |||
| cf86158b83 | |||
| 25eb955636 | |||
| 7862a858ae | |||
| bc18d3b494 | |||
| fd34f22028 | |||
| 958c9e5e94 | |||
| 7c7260c603 | |||
| bae9e3e0f1 | |||
| 26b0394613 | |||
| 689ef0bcbe | |||
| 461585b782 | |||
| ea33f35a7d | |||
| 7427f1a2f3 | |||
| b7984bf97e | |||
| 9b24a45b6e | |||
| 4ace81a422 | |||
| a60790c92c | |||
| fd0d00cac3 | |||
| 498396e611 | |||
| 5444377398 | |||
| 9d981f9800 | |||
| 14e17fb67d | |||
| 0ffa7685fd | |||
| dc7d4671e4 | |||
| 10cb5cd66f | |||
| cb15d9f77a | |||
| da74faef9b | |||
| 4368833c7e | |||
| a20df41316 | |||
| ccf48dbad1 | |||
| 6700aa27bc | |||
| df525eab63 | |||
| 275901626f | |||
| fac0dc31b2 | |||
| 8696eca1f0 | |||
| d647c71cf5 | |||
| 9b218dd808 | |||
| 9f39dc521d | |||
| 112093f914 | |||
| d174597770 | |||
| d9289787b7 | |||
| 77c1c3b511 | |||
| 5a1c542832 | |||
| 091d7cc897 | |||
| 21f4fb52a8 | |||
| 656ed709f3 | |||
| 868ca8db66 | |||
| a9360e5fac | |||
| 3414599f72 | |||
| 84e92aa8a8 | |||
| edd842763f | |||
| 867ee0f928 | |||
| 29ee648d7f | |||
| 5b9c610856 | |||
| 769ddf6407 | |||
| dd7205f855 | |||
| 30ee410309 | |||
| 2d0b1a3a24 | |||
| 2cdf036172 | |||
| c14aa28e76 | |||
| 0e7d2554f8 | |||
| cdfc618bab | |||
| 1005edb609 | |||
| 3b4da8de52 | |||
| 58c6370cda | |||
| 0e72adba36 | |||
| d5084dc334 | |||
| 0aeecfd00a | |||
| 9ceb5621bc | |||
| 94c1d4921e | |||
| a4ff20106c | |||
| 289e25be6c | |||
| edebc8e98f | |||
| 8c21e2362b | |||
| 5d40645aef | |||
| b5ad4ac32f | |||
| 2a2801eced | |||
| 6289565f66 | |||
| 8ed6eebc2c | |||
| 58afaecce2 | |||
| 93c6df41fd | |||
| f3bcb55d8a | |||
| 0f32cb3c6d | |||
| f948417e31 | |||
| 2ddd96ebea | |||
| 06fd46a7e3 | |||
| 333ef4bb71 | |||
| 2c13c4ff79 | |||
| 4bf7fc9ce1 | |||
| 7e0014bdcc | |||
| b695a95032 | |||
| fa1a6d0ac2 | |||
| a42c8bd825 | |||
| 9ef3768845 | |||
| 94f04c9aeb | |||
| 0dcd9b2626 | |||
| 475a76f765 | |||
| b79c547027 | |||
| f09e60fe02 | |||
| b708d2d265 | |||
| 66302f5ab3 | |||
| 7f343596fc | |||
| 3f74a7aa3e | |||
| d63b6604fc | |||
| 66c73e17bf | |||
| f03c4c00a3 | |||
| 607c5dc58d | |||
| dc94724800 | |||
| 62835613e6 | |||
| 6f88da92bb | |||
| 083548b33c | |||
| 20bc675ad2 | |||
| fe3d4e5544 | |||
| ff5cdf47df | |||
| c04cdacef9 | |||
| ee32f320ee | |||
| 57ede4cabd | |||
| dc575a9f78 | |||
| 41e1faf655 | |||
| e4b26c92fd | |||
| 12ea8a4597 | |||
| 0023ab1622 | |||
| c5a6208f7e | |||
| 35a185c65f | |||
| 1796cacee6 | |||
| 9f99cb593f | |||
| df4c065dfe | |||
| edb022f7c5 | |||
| 27a7d72de3 | |||
| 678f113d05 | |||
| 92da66bbbb | |||
| 79a5228899 | |||
| 4d9411de42 | |||
| 3780747992 | |||
| 4514b1b831 | |||
| 2bbbbf6204 | |||
| e1b5dea3f7 | |||
| 2d2c274030 | |||
| 81dd72a281 | |||
| b82349478c | |||
| 7d0690f7a0 | |||
| 62a0cb895d | |||
| f28ce73d33 | |||
| 15425c5328 | |||
| 7c645e3c51 | |||
| 795d068175 | |||
| 90c2bd2873 | |||
| bd7a3c7c43 | |||
| ea976309bc | |||
| 1b5787274a | |||
| 7e595deabc | |||
| 66091b2b73 | |||
| 4f8d8d4f07 | |||
| 4fba12f966 | |||
| 348975c33d | |||
| cd6888868e | |||
| f2d4e64005 | |||
| a92b88f6d3 | |||
| abfdbdeffa | |||
| efe66e7e98 | |||
| c3fa1bb0dc | |||
| e487981e5b | |||
| 9a6dda629b | |||
| 46e7d6e432 | |||
| b9f4845fa7 | |||
| 36863efc5a | |||
| a0ce883a3f | |||
| bc0fe17d08 | |||
| 2e52409db6 | |||
| f434cde7b3 | |||
| 3e596cac29 | |||
| 876d5c1bfe | |||
| 3424de9130 | |||
| 279e900105 | |||
| ac7398be49 | |||
| 0bfeef637b | |||
| 0b5984b410 | |||
| ad1b6fd74c | |||
| f1f17eea3d | |||
| 642607acad | |||
| 7f3b23e71e | |||
| d2ed8d3ea9 | |||
| 1d8f9dd97f | |||
| a7c82c4958 | |||
| 81555d1657 | |||
| 9b0a6c3202 | |||
| 2aee54e8c7 | |||
| e3248efeb4 | |||
| 35bbf2d6c9 | |||
| 4129b1a579 | |||
| ef90a94c34 | |||
| 71df86750c | |||
| 7f2649a5dd | |||
| de662e4a2b | |||
| 2cb7211734 | |||
| 82c84bee97 | |||
| 3e6ceb3546 | |||
| 2d13849b2c | |||
| 952d95851a | |||
| 84fc2801ef | |||
| 07f272f453 | |||
| 8085065027 | |||
| 31e26ca9d0 | |||
| 088cbb3b97 | |||
| 57fd7de027 | |||
| 85fc828036 | |||
| c288ea0088 | |||
| 81924e2027 | |||
| c9b637b92e | |||
| 4779d406b8 | |||
| a945e35a2a | |||
| 509d3275af | |||
| c562190973 | |||
| e7ee172f90 | |||
| d49b1eea33 | |||
| d8afd74171 | |||
| b88f50ced6 | |||
| e130045930 | |||
| ae72cc3adb | |||
| 816539ce18 | |||
| c6cdb0d893 | |||
| dd026e24a3 | |||
| 76015ed30c | |||
| b9fbf60df5 | |||
| 50d69a0f0e | |||
| 2f8477e072 | |||
| 973a91ac5a | |||
| 60a39b775c | |||
| f84b5e7c90 | |||
| 5e93f23d06 | |||
| 471613a77f | |||
| 778ddf4b47 | |||
| 180c1d8345 | |||
| ae847d8625 | |||
| a4ba43a632 | |||
| b7d23aea8d | |||
| bb8634f650 | |||
| 34c56e7c41 | |||
| a92986c1ce | |||
| 831e5c0a82 | |||
| 2adfee6f49 | |||
| 4bb67318a8 | |||
| dadf07a3c3 | |||
| 7f6c8bb1a3 | |||
| eb8db87d9f | |||
| bf91a8d6a3 | |||
| bce949951c | |||
| 744b185cfe | |||
| 8919ba2491 | |||
| fc82dda558 | |||
| d70fe9df73 | |||
| d2c78695fe | |||
| 4aa087e38d | |||
| a3cbb1bcb6 | |||
| 60823dda97 | |||
| 40650bfed2 | |||
| b0423af14b | |||
| 636af5c7c2 | |||
| efc532fce0 | |||
| 4bf54550aa | |||
| 43773c63eb | |||
| d34d615c3b | |||
| 9be0cd8c6e | |||
| a7e323b026 | |||
| 42529443bd | |||
| 16b1f8317c | |||
| abe0105095 | |||
| 1b2b3e6718 | |||
| cb2916ae39 | |||
| 993555b72c | |||
| ddac586795 | |||
| f92c01e34c | |||
| 69e63cc815 | |||
| 81ad00c4d6 | |||
| ca498889dc | |||
| 6ad3606091 | |||
| aae52bdddd | |||
| 5e6d1ce5bc | |||
| 9fe28fccd2 | |||
| e7e148497d | |||
| 2d2fd086d5 | |||
| 067c1440d1 | |||
| 70e189fa1f | |||
| d91b24d645 | |||
| 538abbcb3c | |||
| 6a99a38b2a | |||
| afbeeef32f | |||
| 315db9e19c | |||
| 183e150466 | |||
| 39735ca0cb | |||
| 9d6d56ca2a | |||
| 22c6b23d7a | |||
| 21b70ec241 | |||
| 72cfc8289a | |||
| 75117aa8d3 | |||
| 0361e5ea10 | |||
| cfac52801f | |||
| 39a6fb3c50 | |||
| 6a39635162 | |||
| c671b151b4 | |||
| 44d2419042 | |||
| 3cb50a7187 | |||
| 600c361d9a | |||
| 90d83eee41 | |||
| e8cff89433 | |||
| 2a4647a1b7 | |||
| bf97d8c029 | |||
| 8f51f4832d | |||
| c496bbe817 | |||
| 6584163911 | |||
| b670510da4 | |||
| 73927de454 | |||
| a65cf42ccf | |||
| 679f5bafb7 | |||
| 1f35ee0101 | |||
| 63c99d3086 | |||
| 7a0acd6c07 | |||
| 6853fa79e8 | |||
| 94c04f67b0 | |||
| f15612034e | |||
| 7c5a3cba60 | |||
| 0cec4095e2 | |||
| 46ab7d6110 | |||
| 169cfd6123 | |||
| 83b7280758 | |||
| 30ea9858c6 |
@@ -3,14 +3,14 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"csharpier": {
|
||||
"version": "0.28.2",
|
||||
"version": "1.2.6",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
"csharpier"
|
||||
],
|
||||
"rollForward": false
|
||||
},
|
||||
"dotnet-affected": {
|
||||
"version": "5.0.0",
|
||||
"version": "6.2.0",
|
||||
"commands": [
|
||||
"dotnet-affected"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
Directory.Build.targets
|
||||
Directory.Build.props
|
||||
Directory.Packages.props
|
||||
|
||||
*.slnx
|
||||
|
||||
**/bin/*
|
||||
**/obj/*
|
||||
_ReSharper.SharpCompress/
|
||||
bin/
|
||||
*.suo
|
||||
*.user
|
||||
TestArchives/Scratch/
|
||||
TestArchives/Scratch2/
|
||||
TestResults/
|
||||
*.nupkg
|
||||
packages/*/
|
||||
project.lock.json
|
||||
tests/TestArchives/Scratch
|
||||
.vs
|
||||
tools
|
||||
.vscode
|
||||
.idea/
|
||||
|
||||
.DS_Store
|
||||
*.snupkg
|
||||
coverage.xml
|
||||
|
||||
*.received.*
|
||||
@@ -1,7 +1,7 @@
|
||||
printWidth: 120
|
||||
useTabs: false
|
||||
tabWidth: 2
|
||||
indentSize: 2
|
||||
preprocessorSymbolSets:
|
||||
- ""
|
||||
- "DEBUG"
|
||||
- "DEBUG,CODE_STYLE"
|
||||
- ""
|
||||
- "DEBUG"
|
||||
- "DEBUG,CODE_STYLE"
|
||||
@@ -6,34 +6,34 @@
|
||||
|
||||
# Connectors
|
||||
|
||||
/Connectors/ArcGIS/* @KatKatKateryna
|
||||
/Connectors/Autocad/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Autocad/* @oguzhankoral @JR-Morgan @dogukankaratas
|
||||
/Connectors/Civil3d/* @oguzhankoral @JR-Morgan @dogukankaratas
|
||||
/Connectors/CSi/* @bjoernsteinhagen @dogukankaratas
|
||||
/Connectors/Navisworks/* @jsdbroughton
|
||||
/Connectors/Revit/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Rhino/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Revit/* @oguzhankoral
|
||||
/Connectors/Rhino/* @oguzhankoral @JR-Morgan
|
||||
/Connectors/Tekla/* @bjoernsteinhagen @dogukankaratas
|
||||
|
||||
# Converters
|
||||
/Convertors/ArcGIS/* @KatKatKateryna
|
||||
/Convertors/Autocad/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Autocad/* @oguzhankoral @JR-Morgan @dogukankaratas
|
||||
/Convertors/Civil3d/* @oguzhankoral @JR-Morgan @dogukankaratas
|
||||
/Convertors/CSi/* @bjoernsteinhagen @dogukankaratas
|
||||
/Convertors/Navisworks/* @jsdbroughton
|
||||
/Convertors/Revit/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Rhino/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Revit/* @oguzhankoral
|
||||
/Convertors/Rhino/* @oguzhankoral @JR-Morgan
|
||||
/Convertors/Tekla/* @bjoernsteinhagen @dogukankaratas
|
||||
|
||||
# DUI
|
||||
|
||||
/DUI3/* @clairekuang @oguzhankoral @didimitrie
|
||||
/DUI3/* @oguzhankoral
|
||||
|
||||
# Importers
|
||||
/Importers/* @JR-Morgan @didimitrie @oguzhankoral @adamhathcock
|
||||
/Importers/* @JR-Morgan @oguzhankoral
|
||||
|
||||
# SDK
|
||||
/SDK/* @JR-Morgan @clairekuang @didimitrie @oguzhankoral @adamhathcock
|
||||
/SDK/* @JR-Morgan @oguzhankoral
|
||||
|
||||
# Build
|
||||
/Build/* @JR-Morgan @oguzhankoral @adamhathcock
|
||||
/Build/* @JR-Morgan @oguzhankoral
|
||||
/.github/* @JR-Morgan @oguzhankoral
|
||||
/.config/* @JR-Morgan @oguzhankoral
|
||||
|
||||
@@ -1,56 +1,42 @@
|
||||
name: .NET Build
|
||||
name: .NET Test
|
||||
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run build
|
||||
run: ./build.ps1 test
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run Build on Linux
|
||||
run: ./build.sh build-linux
|
||||
|
||||
- name: ⚒️ Run tests
|
||||
run: ./build.sh test-only
|
||||
- name: ⚒️ Run Test
|
||||
run: ./build.sh test-and-pack
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
files: Converters/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
# Disabling this code for now, since we no longer need to publish nugets from this repo
|
||||
# But keeping it around incase we ever need in the future.
|
||||
# Ideally, I'd also like to move the nuget token to be an environment secret, and to have tight package scopes
|
||||
# - name: Push to nuget.org
|
||||
# if: ${{ inputs.deployNugets }}
|
||||
# run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{ secrets.CONNECTORS_NUGET_TOKEN }}
|
||||
|
||||
@@ -6,8 +6,8 @@ on:
|
||||
tags: ["v3.*.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
build-connectors:
|
||||
runs-on: windows-latest # Keeping on windows for now, for cross platform building of exe projects, we need to use dotnet publish
|
||||
env:
|
||||
SEMVER: "unset"
|
||||
FILE_VERSION: "unset"
|
||||
@@ -16,26 +16,26 @@ jobs:
|
||||
file_version: ${{ steps.set-version.outputs.file_version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run build on Windows
|
||||
- name: ⚒️ Run build and zip connectors
|
||||
run: ./build.ps1 zip
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: output-${{ env.SEMVER }}
|
||||
path: output/*.*
|
||||
@@ -51,65 +51,29 @@ jobs:
|
||||
|
||||
deploy-installers:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-windows
|
||||
needs: build-connectors
|
||||
env:
|
||||
IS_PUBLIC_RELEASE: ${{ github.ref_type == 'tag' }}
|
||||
steps:
|
||||
- name: 🔫 Trigger Build Installers
|
||||
uses: the-actions-org/workflow-dispatch@v4.0.0
|
||||
uses: benc-uk/workflow-dispatch@v1
|
||||
with:
|
||||
workflow: Build Installers
|
||||
repo: specklesystems/connector-installers
|
||||
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
|
||||
inputs: '{
|
||||
"run_id": "${{ github.run_id }}",
|
||||
"semver": "${{ needs.build-windows.outputs.semver }}",
|
||||
"file_version": "${{ needs.build-windows.outputs.file_version }}",
|
||||
"semver": "${{ needs.build-connectors.outputs.semver }}",
|
||||
"file_version": "${{ needs.build-connectors.outputs.file_version }}",
|
||||
"repo": "${{ github.repository }}",
|
||||
"is_public_release": ${{ env.IS_PUBLIC_RELEASE }}
|
||||
}'
|
||||
ref: main
|
||||
wait-for-completion: true
|
||||
wait-for-completion-interval: 10s
|
||||
wait-for-completion-timeout: 10m
|
||||
display-workflow-run-url: true
|
||||
display-workflow-run-url-interval: 10s
|
||||
sync-status: true
|
||||
timeout-minutes: 15
|
||||
|
||||
- uses: geekyeggo/delete-artifact@v5
|
||||
# Allows us to inspect the artifacts of failed builds, since this below step will be skipped if the above step fails
|
||||
- uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: output-*
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
|
||||
|
||||
- name: Cache Nuget
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run tests on Linux
|
||||
run: ./build.sh test-only
|
||||
|
||||
- name: ⚒️ Run Build and Pack on Linux
|
||||
run: ./build.sh build-linux
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: Converters/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Push to nuget.org
|
||||
if: (github.ref_type == 'tag')
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
|
||||
|
||||
@@ -21,3 +21,5 @@ tools
|
||||
coverage.xml
|
||||
output/
|
||||
Images/Thumbs.db
|
||||
|
||||
.claude/
|
||||
|
||||
@@ -1,424 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35027.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{85A13E25-EB29-4F31-8853-B9EE83275B3D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.csharpierrc.yaml = .csharpierrc.yaml
|
||||
.editorconfig = .editorconfig
|
||||
codecov.yml = codecov.yml
|
||||
Directory.Build.props = Directory.Build.props
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
global.json = global.json
|
||||
README.md = README.md
|
||||
CodeMetricsConfig.txt = CodeMetricsConfig.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DUI3", "DUI3", "{FD4D6594-D81E-456F-8F2E-35B09E04A755}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Revit", "Revit", "{D92751C8-1039-4005-90B2-913E55E0B8BD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{2E00592E-558D-492D-88F9-3ECEE4C0C7DA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2023", "Connectors\Revit\Speckle.Connectors.Revit2023\Speckle.Connectors.Revit2023.csproj", "{01F98733-7352-47AD-A594-537D979DE3DE}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.RevitShared", "Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.shproj", "{DC570FFF-6FE5-47BD-8BC1-B471A6067786}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared", "Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.shproj", "{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2023.DependencyInjection\Speckle.Converters.Revit2023.DependencyInjection.csproj", "{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023", "Converters\Revit\Speckle.Converters.Revit2023\Speckle.Converters.Revit2023.csproj", "{26391930-F86F-47E0-A5F6-B89919E38CE1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.DUI", "DUI3\Speckle.Connectors.DUI\Speckle.Connectors.DUI.csproj", "{D81C0B87-F0C1-4297-A147-02F001FB7E1E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Autofac", "Sdk\Speckle.Autofac\Speckle.Autofac.csproj", "{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Utils", "Sdk\Speckle.Connectors.Utils\Speckle.Connectors.Utils.csproj", "{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Common", "Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj", "{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Rhino", "Rhino", "{9584AEE5-CD59-46E6-93E6-2DC2B5285B75}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Rhino7", "Connectors\Rhino\Speckle.Connectors.Rhino7\Speckle.Connectors.Rhino7.csproj", "{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7", "Converters\Rhino\Speckle.Converters.Rhino7\Speckle.Converters.Rhino7.csproj", "{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7.DependencyInjection", "Converters\Rhino\Speckle.Converters.Rhino7.DependencyInjection\Speckle.Converters.Rhino7.DependencyInjection.csproj", "{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.ArcGIS3", "Connectors\ArcGIS\Speckle.Connectors.ArcGIS3\Speckle.Connectors.ArcGIS3.csproj", "{A97F7177-86C7-4B38-A6ED-DA51BF762471}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.ArcGIS3", "Converters\ArcGIS\Speckle.Converters.ArcGIS3\Speckle.Converters.ArcGIS3.csproj", "{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.ArcGIS3.DependencyInjection", "Converters\ArcGIS\Speckle.Converters.ArcGIS3.DependencyInjection\Speckle.Converters.ArcGIS3.DependencyInjection.csproj", "{7DFF1591-237D-499E-A767-EE37B93FB958}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ArcGIS", "ArcGIS", "{CCF48B65-33D1-4E8B-A57B-E03394730B21}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Autocad2023", "Connectors\Autocad\Speckle.Connectors.Autocad2023\Speckle.Connectors.Autocad2023.csproj", "{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.AutocadShared", "Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.shproj", "{41BC679F-887F-44CF-971D-A5502EE87DB0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Common.DependencyInjection", "Sdk\Speckle.Converters.Common.DependencyInjection\Speckle.Converters.Common.DependencyInjection.csproj", "{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Autocad", "Autocad", "{804E065F-914C-414A-AF84-009312C3CFF6}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.AutocadShared", "Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.shproj", "{9ADD1B7A-6401-4202-8613-F668E2FBC0A4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2023", "Converters\Autocad\Speckle.Converters.Autocad2023\Speckle.Converters.Autocad2023.csproj", "{631C295A-7CCF-4B42-8686-7034E31469E7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2023.DependencyInjection", "Converters\Autocad\Speckle.Converters.Autocad2023.DependencyInjection\Speckle.Converters.Autocad2023.DependencyInjection.csproj", "{D940853C-003A-482C-BDB0-665367F274A0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.DUI.WebView", "DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj", "{7420652C-3046-4F38-BE64-9B9E69D76FA2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "Build\Build.csproj", "{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HostApps", "HostApps", "{42826721-9A18-4762-8BA9-F1429DD5C5B1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{59E8E8F3-4E42-4E92-83B3-B1C2AB901D18}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.github\workflows\ci.yml = .github\workflows\ci.yml
|
||||
.github\workflows\main.yml = .github\workflows\main.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Civil3d2024", "Connectors\Autocad\Speckle.Connectors.Civil3d2024\Speckle.Connectors.Civil3d2024.csproj", "{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.Civil3dShared", "Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.shproj", "{35175682-DA83-4C0A-A49D-B191F5885D8E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Civil3d2024.DependencyInjection", "Converters\Civil3d\Speckle.Converters.Civil3d2024.DependencyInjection\Speckle.Converters.Civil3d2024.DependencyInjection.csproj", "{80F965C4-E2A8-4F54-985D-73D06E45F9CE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2024", "Converters\Autocad\Speckle.Converters.Autocad2024\Speckle.Converters.Autocad2024.csproj", "{C2DE264A-AA87-4012-B954-17E3F403A237}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2024.DependencyInjection", "Converters\Autocad\Speckle.Converters.Autocad2024.DependencyInjection\Speckle.Converters.Autocad2024.DependencyInjection.csproj", "{AF507D61-6766-4C20-9F58-23DC29508219}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Civil3d2024", "Converters\Civil3d\Speckle.Converters.Civil3d2024\Speckle.Converters.Civil3d2024.csproj", "{25172C49-7AA4-4739-BB07-69785094C379}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RhinoShared", "Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.shproj", "{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7.Tests", "Converters\Rhino\Speckle.Converters.Rhino7.Tests\Speckle.Converters.Rhino7.Tests.csproj", "{AC2DB416-F05C-4296-9040-56D6AD4FCD27}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023.Tests", "Converters\Revit\Speckle.Converters.Revit2023.Tests\Speckle.Converters.Revit2023.Tests.csproj", "{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Testing", "Sdk\Speckle.Testing\Speckle.Testing.csproj", "{A3869243-B462-4986-914B-94E407D8D20F}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared.DependencyInjection", "Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.shproj", "{6067BA60-D279-4156-8AE1-6B44E2D19187}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2024", "Connectors\Revit\Speckle.Connectors.Revit2024\Speckle.Connectors.Revit2024.csproj", "{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024", "Converters\Revit\Speckle.Converters.Revit2024\Speckle.Converters.Revit2024.csproj", "{67B888D9-C6C4-49F1-883C-5B964151D889}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2024.DependencyInjection\Speckle.Converters.Revit2024.DependencyInjection.csproj", "{7F3055BA-70AA-424C-8748-345AF35127E9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2024", "2024", "{57F59C0C-5687-4AF9-AE1C-1933B539F0E4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{FC224610-32D3-454E-9BC1-1219FE8ACD5F}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared.Tests", "Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.shproj", "{E1C43415-3202-45F4-8BF9-A4DD7D7F2ED6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024.Tests", "Converters\Revit\Speckle.Converters.Revit2024.Tests\Speckle.Converters.Revit2024.Tests.csproj", "{C32274D9-1B66-4D5C-82F9-EB3F10F46752}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.RevitShared.Cef", "Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.shproj", "{6A40CBE4-ECAB-4CED-9917-5C64CBF75DA6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2025", "2025", "{8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2025", "Connectors\Revit\Speckle.Connectors.Revit2025\Speckle.Connectors.Revit2025.csproj", "{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2025", "Converters\Revit\Speckle.Converters.Revit2025\Speckle.Converters.Revit2025.csproj", "{4D40A101-07E6-4FF2-8934-83434932591D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2025.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2025.DependencyInjection\Speckle.Converters.Revit2025.DependencyInjection.csproj", "{20751904-0DFC-4126-BF2A-834B53841010}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2022", "Connectors\Revit\Speckle.Connectors.Revit2022\Speckle.Connectors.Revit2022.csproj", "{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022", "Converters\Revit\Speckle.Converters.Revit2022\Speckle.Converters.Revit2022.csproj", "{19424B55-058C-4E9C-B86F-700AEF9EAEC3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2022.DependencyInjection\Speckle.Converters.Revit2022.DependencyInjection.csproj", "{881D71A3-D276-4108-98C6-0FFD32129B9C}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2022", "2022", "{0AF38BA3-65A0-481B-8CBB-B82E406E1575}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.DUI.Tests", "DUI3\Speckle.Connectors.DUI.Tests\Speckle.Connectors.DUI.Tests.csproj", "{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022.Tests", "Converters\Revit\Speckle.Converters.Revit2022.Tests\Speckle.Converters.Revit2022.Tests.csproj", "{D8069A23-AD2E-4C9E-8574-7E8C45296A46}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{2D5AE63D-85C0-43D1-84BF-04418ED93F63}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2024", "2024", "{2F45036E-D817-41E9-B82F-DBE013EC95D0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Civil3d", "Civil3d", "{91D70DE1-DC8E-4AE1-B100-0671D6263FC5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{4721AA15-AF6E-4A62-A2C3-65564DC563E6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{01F98733-7352-47AD-A594-537D979DE3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{01F98733-7352-47AD-A594-537D979DE3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{01F98733-7352-47AD-A594-537D979DE3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{01F98733-7352-47AD-A594-537D979DE3DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7DFF1591-237D-499E-A767-EE37B93FB958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DFF1591-237D-499E-A767-EE37B93FB958}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DFF1591-237D-499E-A767-EE37B93FB958}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DFF1591-237D-499E-A767-EE37B93FB958}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{631C295A-7CCF-4B42-8686-7034E31469E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{631C295A-7CCF-4B42-8686-7034E31469E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{631C295A-7CCF-4B42-8686-7034E31469E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{631C295A-7CCF-4B42-8686-7034E31469E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D940853C-003A-482C-BDB0-665367F274A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D940853C-003A-482C-BDB0-665367F274A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D940853C-003A-482C-BDB0-665367F274A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D940853C-003A-482C-BDB0-665367F274A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2DE264A-AA87-4012-B954-17E3F403A237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2DE264A-AA87-4012-B954-17E3F403A237}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2DE264A-AA87-4012-B954-17E3F403A237}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2DE264A-AA87-4012-B954-17E3F403A237}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AF507D61-6766-4C20-9F58-23DC29508219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AF507D61-6766-4C20-9F58-23DC29508219}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AF507D61-6766-4C20-9F58-23DC29508219}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF507D61-6766-4C20-9F58-23DC29508219}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{25172C49-7AA4-4739-BB07-69785094C379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{25172C49-7AA4-4739-BB07-69785094C379}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{25172C49-7AA4-4739-BB07-69785094C379}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{25172C49-7AA4-4739-BB07-69785094C379}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A3869243-B462-4986-914B-94E407D8D20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A3869243-B462-4986-914B-94E407D8D20F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A3869243-B462-4986-914B-94E407D8D20F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A3869243-B462-4986-914B-94E407D8D20F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{67B888D9-C6C4-49F1-883C-5B964151D889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{67B888D9-C6C4-49F1-883C-5B964151D889}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{67B888D9-C6C4-49F1-883C-5B964151D889}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67B888D9-C6C4-49F1-883C-5B964151D889}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F3055BA-70AA-424C-8748-345AF35127E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F3055BA-70AA-424C-8748-345AF35127E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F3055BA-70AA-424C-8748-345AF35127E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F3055BA-70AA-424C-8748-345AF35127E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4D40A101-07E6-4FF2-8934-83434932591D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4D40A101-07E6-4FF2-8934-83434932591D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D40A101-07E6-4FF2-8934-83434932591D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D40A101-07E6-4FF2-8934-83434932591D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{20751904-0DFC-4126-BF2A-834B53841010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{20751904-0DFC-4126-BF2A-834B53841010}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{20751904-0DFC-4126-BF2A-834B53841010}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{20751904-0DFC-4126-BF2A-834B53841010}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Release|Any CPU.ActiveCfg = Debug|x64
|
||||
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Release|Any CPU.Build.0 = Debug|x64
|
||||
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{D92751C8-1039-4005-90B2-913E55E0B8BD} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
|
||||
{01F98733-7352-47AD-A594-537D979DE3DE} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
|
||||
{DC570FFF-6FE5-47BD-8BC1-B471A6067786} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
|
||||
{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
|
||||
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
|
||||
{26391930-F86F-47E0-A5F6-B89919E38CE1} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
|
||||
{D81C0B87-F0C1-4297-A147-02F001FB7E1E} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
|
||||
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
|
||||
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
|
||||
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
|
||||
{9584AEE5-CD59-46E6-93E6-2DC2B5285B75} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
|
||||
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
|
||||
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
|
||||
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
|
||||
{A97F7177-86C7-4B38-A6ED-DA51BF762471} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
|
||||
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
|
||||
{7DFF1591-237D-499E-A767-EE37B93FB958} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
|
||||
{CCF48B65-33D1-4E8B-A57B-E03394730B21} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
|
||||
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
|
||||
{804E065F-914C-414A-AF84-009312C3CFF6} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
|
||||
{7420652C-3046-4F38-BE64-9B9E69D76FA2} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
|
||||
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89} = {59E8E8F3-4E42-4E92-83B3-B1C2AB901D18}
|
||||
{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED9} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
|
||||
{AC2DB416-F05C-4296-9040-56D6AD4FCD27} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
|
||||
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
|
||||
{A3869243-B462-4986-914B-94E407D8D20F} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
|
||||
{6067BA60-D279-4156-8AE1-6B44E2D19187} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
|
||||
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
|
||||
{67B888D9-C6C4-49F1-883C-5B964151D889} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
|
||||
{7F3055BA-70AA-424C-8748-345AF35127E9} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
|
||||
{E9DEBA00-50A4-485D-BA65-D8AB3E3467AB} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
|
||||
{57F59C0C-5687-4AF9-AE1C-1933B539F0E4} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
|
||||
{FC224610-32D3-454E-9BC1-1219FE8ACD5F} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
|
||||
{E1C43415-3202-45F4-8BF9-A4DD7D7F2ED6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
|
||||
{C32274D9-1B66-4D5C-82F9-EB3F10F46752} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
|
||||
{6A40CBE4-ECAB-4CED-9917-5C64CBF75DA6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
|
||||
{8AC2AD6D-6C74-4B24-8DF6-42717FC9B804} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
|
||||
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
|
||||
{4D40A101-07E6-4FF2-8934-83434932591D} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
|
||||
{20751904-0DFC-4126-BF2A-834B53841010} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
|
||||
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
|
||||
{19424B55-058C-4E9C-B86F-700AEF9EAEC3} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
|
||||
{881D71A3-D276-4108-98C6-0FFD32129B9C} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
|
||||
{0AF38BA3-65A0-481B-8CBB-B82E406E1575} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
|
||||
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
|
||||
{D8069A23-AD2E-4C9E-8574-7E8C45296A46} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
|
||||
{2D5AE63D-85C0-43D1-84BF-04418ED93F63} = {804E065F-914C-414A-AF84-009312C3CFF6}
|
||||
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
|
||||
{631C295A-7CCF-4B42-8686-7034E31469E7} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
|
||||
{D940853C-003A-482C-BDB0-665367F274A0} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
|
||||
{2F45036E-D817-41E9-B82F-DBE013EC95D0} = {804E065F-914C-414A-AF84-009312C3CFF6}
|
||||
{C2DE264A-AA87-4012-B954-17E3F403A237} = {2F45036E-D817-41E9-B82F-DBE013EC95D0}
|
||||
{AF507D61-6766-4C20-9F58-23DC29508219} = {2F45036E-D817-41E9-B82F-DBE013EC95D0}
|
||||
{91D70DE1-DC8E-4AE1-B100-0671D6263FC5} = {804E065F-914C-414A-AF84-009312C3CFF6}
|
||||
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
|
||||
{25172C49-7AA4-4739-BB07-69785094C379} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
|
||||
{80F965C4-E2A8-4F54-985D-73D06E45F9CE} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
|
||||
{35175682-DA83-4C0A-A49D-B191F5885D8E} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
|
||||
{4721AA15-AF6E-4A62-A2C3-65564DC563E6} = {804E065F-914C-414A-AF84-009312C3CFF6}
|
||||
{41BC679F-887F-44CF-971D-A5502EE87DB0} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6}
|
||||
{9ADD1B7A-6401-4202-8613-F668E2FBC0A4} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8}
|
||||
EndGlobalSection
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{01f98733-7352-47ad-a594-537d979de3de}*SharedItemsImports = 5
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{01f98733-7352-47ad-a594-537d979de3de}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{19424b55-058c-4e9c-b86f-700aef9eaec3}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{20751904-0dfc-4126-bf2a-834b53841010}*SharedItemsImports = 5
|
||||
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{25172c49-7aa4-4739-bb07-69785094c379}*SharedItemsImports = 5
|
||||
Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.projitems*{25172c49-7aa4-4739-bb07-69785094c379}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{26391930-f86f-47e0-a5f6-b89919e38ce1}*SharedItemsImports = 5
|
||||
Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.projitems*{35175682-da83-4c0a-a49d-b191f5885d8e}*SharedItemsImports = 13
|
||||
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{41bc679f-887f-44cf-971d-a5502ee87db0}*SharedItemsImports = 13
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{4d40a101-07e6-4ff2-8934-83434932591d}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{6067ba60-d279-4156-8ae1-6b44e2d19187}*SharedItemsImports = 13
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{617bd3c7-87d9-4d28-8ac9-4910945bb9fc}*SharedItemsImports = 5
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{617bd3c7-87d9-4d28-8ac9-4910945bb9fc}*SharedItemsImports = 5
|
||||
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{631c295a-7ccf-4b42-8686-7034e31469e7}*SharedItemsImports = 5
|
||||
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{65a2f556-f14a-49f3-8a92-7f2e1e7ed3b5}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{67b888d9-c6c4-49f1-883c-5b964151d889}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{68cf9bdf-94ac-4d2d-a7bd-d1c064f97051}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{68cf9bdf-94ac-4d2d-a7bd-d1c064f97051}*SharedItemsImports = 5
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{6a40cbe4-ecab-4ced-9917-5c64cbf75da6}*SharedItemsImports = 13
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{7f1fdcf2-0ce8-4119-b3c1-f2cc6d7e1c36}*SharedItemsImports = 5
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{7f1fdcf2-0ce8-4119-b3c1-f2cc6d7e1c36}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{7f3055ba-70aa-424c-8748-345af35127e9}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{83ead6f0-3cb3-456a-ad81-072127d0de0e}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{881d71a3-d276-4108-98c6-0ffd32129b9c}*SharedItemsImports = 5
|
||||
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{89c4cbc7-1606-40de-b6da-fbe3aac98395}*SharedItemsImports = 5
|
||||
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{9add1b7a-6401-4202-8613-f668e2fbc0a4}*SharedItemsImports = 13
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{a6de3da0-b242-4f49-aef0-4e26af92d16c}*SharedItemsImports = 5
|
||||
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{ac2db416-f05c-4296-9040-56d6ad4fcd27}*SharedItemsImports = 5
|
||||
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{c2de264a-aa87-4012-b954-17e3f403a237}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{c32274d9-1b66-4d5c-82f9-eb3f10f46752}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{c32274d9-1b66-4d5c-82f9-eb3f10f46752}*SharedItemsImports = 5
|
||||
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{ca8eae01-ab9f-4ec1-b6f3-73721487e9e1}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{d8069a23-ad2e-4c9e-8574-7e8c45296a46}*SharedItemsImports = 5
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{d8069a23-ad2e-4c9e-8574-7e8c45296a46}*SharedItemsImports = 5
|
||||
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{dc570fff-6fe5-47bd-8bc1-b471a6067786}*SharedItemsImports = 13
|
||||
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{e1c43415-3200-45f4-8bf9-a4dd7d7f2ed6}*SharedItemsImports = 13
|
||||
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{e1c43415-3200-45f4-8bf9-a4dd7d7f2ed9}*SharedItemsImports = 13
|
||||
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{e1c43415-3202-45f4-8bf9-a4dd7d7f2ed6}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,5 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
||||
@@ -6,7 +6,6 @@ public static class Consts
|
||||
|
||||
public static readonly ProjectGroup[] ProjectGroups =
|
||||
{
|
||||
new("arcgis", [new("Connectors/ArcGIS/Speckle.Connectors.ArcGIS3", "net6.0-windows")]),
|
||||
new(
|
||||
"rhino",
|
||||
[
|
||||
@@ -21,7 +20,7 @@ public static class Consts
|
||||
new("Connectors/Revit/Speckle.Connectors.Revit2023", "net48"),
|
||||
new("Connectors/Revit/Speckle.Connectors.Revit2024", "net48"),
|
||||
new("Connectors/Revit/Speckle.Connectors.Revit2025", "net8.0-windows"),
|
||||
new("Connectors/Revit/Speckle.Connectors.Revit2026", "net8.0-windows")
|
||||
new("Connectors/Revit/Speckle.Connectors.Revit2026", "net8.0-windows"),
|
||||
]
|
||||
),
|
||||
new(
|
||||
@@ -31,7 +30,7 @@ public static class Consts
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2023", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2025", "net8.0-windows"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2026", "net8.0-windows")
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2026", "net8.0-windows"),
|
||||
]
|
||||
),
|
||||
new(
|
||||
@@ -41,9 +40,10 @@ public static class Consts
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2023", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2025", "net8.0-windows"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2026", "net8.0-windows")
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2026", "net8.0-windows"),
|
||||
]
|
||||
),
|
||||
new("plant3d", [new("Connectors/Autocad/Speckle.Connectors.Plant3d2026", "net8.0-windows")]),
|
||||
new(
|
||||
"navisworks",
|
||||
[
|
||||
@@ -53,7 +53,7 @@ public static class Consts
|
||||
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2023", "net48"),
|
||||
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2024", "net48"),
|
||||
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2025", "net48"),
|
||||
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2026", "net48")
|
||||
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2026", "net48"),
|
||||
]
|
||||
),
|
||||
new(
|
||||
@@ -61,7 +61,7 @@ public static class Consts
|
||||
[
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2025", "net48")
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2025", "net48"),
|
||||
]
|
||||
),
|
||||
new(
|
||||
@@ -70,7 +70,8 @@ public static class Consts
|
||||
new("Connectors/CSi/Speckle.Connectors.ETABS21", "net48"),
|
||||
new("Connectors/CSi/Speckle.Connectors.ETABS22", "net8.0-windows"),
|
||||
]
|
||||
)
|
||||
),
|
||||
new("rhino-importer", [new("Importers/Rhino/Speckle.Importers.JobProcessor", "net8.0-windows")]),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ public static class Github
|
||||
{
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("application/vnd.github+json") },
|
||||
Authorization = new AuthenticationHeaderValue("Bearer", token),
|
||||
UserAgent = { new ProductInfoHeaderValue("Speckle.build", "3.0.0") }
|
||||
UserAgent = { new ProductInfoHeaderValue("Speckle.build", "3.0.0") },
|
||||
},
|
||||
Content = content
|
||||
Content = content,
|
||||
};
|
||||
request.Headers.Add("X-GitHub-Api-Version", "2022-11-28");
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
@@ -7,9 +7,9 @@ using static SimpleExec.Command;
|
||||
const string CLEAN = "clean";
|
||||
const string RESTORE = "restore";
|
||||
const string BUILD = "build";
|
||||
const string BUILD_LINUX = "build-linux";
|
||||
const string PACK = "pack";
|
||||
const string TEST_AFFECTED = "test-affected";
|
||||
const string TEST = "test";
|
||||
const string TEST_ONLY = "test-only";
|
||||
const string FORMAT = "format";
|
||||
const string ZIP = "zip";
|
||||
const string RESTORE_TOOLS = "restore-tools";
|
||||
@@ -19,6 +19,7 @@ const string GEN_SOLUTIONS = "generate-solutions";
|
||||
const string DEEP_CLEAN = "deep-clean";
|
||||
const string DEEP_CLEAN_LOCAL = "deep-clean-local";
|
||||
const string DETECT_AFFECTED = "detect-affected";
|
||||
const string TEST_AND_PACK = "test-and-pack";
|
||||
|
||||
//need to pass arguments
|
||||
/*var arguments = new List<string>();
|
||||
@@ -144,13 +145,13 @@ Target(
|
||||
DependsOn(RESTORE_TOOLS),
|
||||
() =>
|
||||
{
|
||||
Run("dotnet", "csharpier --check .");
|
||||
Run("dotnet", "csharpier check ./");
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
RESTORE,
|
||||
DependsOn(FORMAT, DETECT_AFFECTED),
|
||||
DependsOn(FORMAT),
|
||||
Consts.Solutions,
|
||||
async s =>
|
||||
{
|
||||
@@ -181,8 +182,8 @@ Target(CHECK_SOLUTIONS, Solutions.CompareConnectorsToLocal);
|
||||
Target(GEN_SOLUTIONS, Solutions.GenerateSolutions);
|
||||
|
||||
Target(
|
||||
TEST,
|
||||
DependsOn(BUILD, CHECK_SOLUTIONS),
|
||||
TEST_AFFECTED,
|
||||
DependsOn(DETECT_AFFECTED, BUILD, CHECK_SOLUTIONS),
|
||||
async () =>
|
||||
{
|
||||
foreach (var s in await Affected.GetTestProjects())
|
||||
@@ -192,14 +193,12 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
//all tests on purpose
|
||||
Target(
|
||||
TEST_ONLY,
|
||||
DependsOn(FORMAT),
|
||||
TEST,
|
||||
DependsOn(BUILD, CHECK_SOLUTIONS),
|
||||
Glob.Files(".", "**/*.Tests.csproj"),
|
||||
file =>
|
||||
{
|
||||
Run("dotnet", $"build \"{file}\" -c Release --no-incremental");
|
||||
Run(
|
||||
"dotnet",
|
||||
$"test \"{file}\" -c Release --no-build --verbosity=minimal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage /p:AltCoverVerbosity=Warning"
|
||||
@@ -207,31 +206,28 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
Target(TEST_AND_PACK, DependsOn(TEST, PACK));
|
||||
|
||||
Target(
|
||||
BUILD_LINUX,
|
||||
DependsOn(FORMAT),
|
||||
Glob.Files(".", "**/Speckle.Importers.Ifc.csproj"),
|
||||
async file =>
|
||||
PACK,
|
||||
DependsOn(BUILD),
|
||||
Consts.Solutions,
|
||||
async solution =>
|
||||
{
|
||||
await RunAsync("dotnet", $"restore \"{file}\" --locked-mode");
|
||||
var version = await Versions.ComputeVersion();
|
||||
var fileVersion = await Versions.ComputeFileVersion();
|
||||
Console.WriteLine($"Version: {version} & {fileVersion}");
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"build \"{file}\" -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"pack \"{file}\" -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
$"pack \"{solution}\" -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
ZIP,
|
||||
DependsOn(TEST),
|
||||
DependsOn(TEST_AFFECTED),
|
||||
async () =>
|
||||
{
|
||||
var version = await Versions.ComputeVersion();
|
||||
@@ -282,6 +278,6 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
Target("default", DependsOn(TEST), () => Console.WriteLine("Done!"));
|
||||
Target("default", DependsOn(TEST_AFFECTED), () => Console.WriteLine("Done!"));
|
||||
|
||||
await RunTargetsAndExitAsync(args).ConfigureAwait(true);
|
||||
|
||||
@@ -1,48 +1,49 @@
|
||||
using Microsoft.Build.Construction;
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Model;
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Model;
|
||||
using Microsoft.VisualStudio.SolutionPersistence.Serializer;
|
||||
|
||||
namespace Build;
|
||||
|
||||
public static class Solutions
|
||||
{
|
||||
private static bool ValidProjects(KeyValuePair<string, ProjectInSolution> projectInSolution) =>
|
||||
projectInSolution.Value.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat;
|
||||
|
||||
public static void CompareConnectorsToLocal()
|
||||
#pragma warning disable CA1802
|
||||
#pragma warning disable IDE1006
|
||||
private static readonly string DIRECTORY = Environment.CurrentDirectory;
|
||||
#pragma warning restore IDE1006
|
||||
#pragma warning restore CA1802
|
||||
public static async Task CompareConnectorsToLocal()
|
||||
{
|
||||
var localSln = SolutionFile.Parse(Path.Combine(Environment.CurrentDirectory, "Local.sln"));
|
||||
var connectorsSln = SolutionFile.Parse(Path.Combine(Environment.CurrentDirectory, "Speckle.Connectors.sln"));
|
||||
var localProjects = localSln.ProjectsByGuid.Where(ValidProjects).ToDictionary();
|
||||
var localSln = await GetSolution("Local.sln");
|
||||
var connectorsSln = await GetSolution("Speckle.Connectors.sln");
|
||||
var localProjects = localSln.SolutionProjects.ToList();
|
||||
|
||||
foreach ((string? _, ProjectInSolution? value) in connectorsSln.ProjectsByGuid.Where(ValidProjects))
|
||||
foreach (var value in connectorsSln.SolutionProjects)
|
||||
{
|
||||
var localProject = localProjects.Values.FirstOrDefault(x => x.ProjectName == value.ProjectName);
|
||||
var localProject = localProjects.FirstOrDefault(x => x.ActualDisplayName == value.ActualDisplayName);
|
||||
if (localProject is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find in LOCAL solution: {value.ProjectName}");
|
||||
throw new InvalidOperationException($"Could not find in LOCAL solution: {value.ActualDisplayName}");
|
||||
}
|
||||
|
||||
if (value.ProjectName != localProject.ProjectName)
|
||||
if (value.ActualDisplayName != localProject.ActualDisplayName)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Projects with different names have same Guid in solution: "
|
||||
+ value.ProjectName
|
||||
+ value.ActualDisplayName
|
||||
+ " and "
|
||||
+ localProject.ProjectName
|
||||
+ localProject.ActualDisplayName
|
||||
);
|
||||
}
|
||||
localProjects.Remove(localProjects.Single(x => x.Value.ProjectName == value.ProjectName).Key);
|
||||
localProjects.Remove(localProjects.Single(x => x.ActualDisplayName == value.ActualDisplayName));
|
||||
}
|
||||
|
||||
void CheckAndRemoveKnown(string projectName)
|
||||
{
|
||||
var localProject = localProjects.Values.FirstOrDefault(x => x.ProjectName == projectName);
|
||||
var localProject = localProjects.FirstOrDefault(x => x.ActualDisplayName == projectName);
|
||||
if (localProject is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find in LOCAL solution: {projectName}");
|
||||
}
|
||||
localProjects.Remove(localProjects.Single(x => x.Value.ProjectName == projectName).Key);
|
||||
localProjects.Remove(localProjects.Single(x => x.ActualDisplayName == projectName));
|
||||
}
|
||||
|
||||
CheckAndRemoveKnown("Speckle.Objects");
|
||||
@@ -51,7 +52,7 @@ public static class Solutions
|
||||
if (localProjects.Count != 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Could not find in CONNECTOR solution: " + localProjects.First().Value.ProjectName
|
||||
"Could not find in CONNECTOR solution: " + localProjects.First().ActualDisplayName
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -61,9 +62,9 @@ public static class Solutions
|
||||
await GenerateLocalSlnx();
|
||||
foreach (var group in Consts.ProjectGroups)
|
||||
{
|
||||
var path = group.Projects[0].ProjectPath.Split('/');
|
||||
var folder = $"/{path[0]}/{path[1]}/";
|
||||
await GenerateConnector(group.HostAppSlug, folder);
|
||||
var connectors = await GetFullSlnx();
|
||||
var slug = group.HostAppSlug;
|
||||
await GenerateConnector(connectors, group, string.Concat(slug[0].ToString().ToUpper(), slug.AsSpan(1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,16 +74,19 @@ public static class Solutions
|
||||
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Objects\\Speckle.Objects.csproj");
|
||||
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Sdk\\Speckle.Sdk.csproj");
|
||||
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Sdk.Dependencies\\Speckle.Sdk.Dependencies.csproj");
|
||||
var sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Local.slnx");
|
||||
var sln = Path.Combine(DIRECTORY, "Local.slnx");
|
||||
await SolutionSerializers.SlnXml.SaveAsync(sln, connectors, default);
|
||||
sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Local.sln");
|
||||
sln = Path.Combine(DIRECTORY, "Local.sln");
|
||||
await SolutionSerializers.SlnFileV12.SaveAsync(sln, connectors, default);
|
||||
|
||||
var revit = Consts.ProjectGroups.Single(x => x.HostAppSlug.Equals("revit"));
|
||||
await GenerateConnector(connectors, revit, "Revit.Local");
|
||||
}
|
||||
|
||||
public static async Task GenerateConnector(string slug, string folder)
|
||||
public static async Task GenerateConnector(SolutionModel connectors, ProjectGroup group, string? name)
|
||||
{
|
||||
slug = string.Concat(slug[0].ToString().ToUpper(), slug.AsSpan(1));
|
||||
var connectors = await GetFullSlnx();
|
||||
var path = group.Projects[0].ProjectPath.Split('/');
|
||||
var folder = $"/{path[0]}/{path[1]}/";
|
||||
var foldersToRemove = connectors
|
||||
.SolutionFolders.Where(x =>
|
||||
//need base folder
|
||||
@@ -95,13 +99,19 @@ public static class Solutions
|
||||
{
|
||||
connectors.RemoveFolder(folderToRemove);
|
||||
}
|
||||
var sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", $"Speckle.{slug}.slnx");
|
||||
var sln = Path.Combine(DIRECTORY, $"Speckle.{name}.slnx");
|
||||
await SolutionSerializers.SlnXml.SaveAsync(sln, connectors, default);
|
||||
}
|
||||
|
||||
public static async Task<SolutionModel> GetFullSlnx()
|
||||
{
|
||||
var connectorsSln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Speckle.Connectors.slnx");
|
||||
var connectorsSln = Path.Combine(DIRECTORY, "Speckle.Connectors.slnx");
|
||||
return await SolutionSerializers.SlnXml.OpenAsync(connectorsSln, default);
|
||||
}
|
||||
|
||||
public static async Task<SolutionModel> GetSolution(string solutionName)
|
||||
{
|
||||
var connectorsSln = Path.Combine(DIRECTORY, solutionName);
|
||||
return await SolutionSerializers.SlnFileV12.OpenAsync(connectorsSln, default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
},
|
||||
"Microsoft.Build": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.11.4, )",
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "UMC7DfeFEHY2GGHHaghybUuUlLaByFHEFudR2PehMgDBuRuLAUePp1iaa4eFtVzepRzMtIbeSCVJCzzX3NV2Gg==",
|
||||
"requested": "[17.11.48, )",
|
||||
"resolved": "17.11.48",
|
||||
"contentHash": "g8Kn575mNAKcuFotV3C7xvF+IbxuHennl67LH2shL2au1U6UqwReTDygCHyU04+koc2Yn7fHIbVQaC08HqEWow==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Framework": "17.11.4",
|
||||
"Microsoft.NET.StringTools": "17.11.4",
|
||||
"Microsoft.Build.Framework": "17.11.48",
|
||||
"Microsoft.NET.StringTools": "17.11.48",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Configuration.ConfigurationManager": "8.0.0",
|
||||
"System.Reflection.Metadata": "8.0.0",
|
||||
@@ -82,8 +82,8 @@
|
||||
},
|
||||
"Microsoft.Build.Framework": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "u28uDihlqxtt8h2dL1ZJOZ7TRkxBK+HGr+3FgQpILVo7Q7gErkw8mYW9R+RM5PtxvZTdYb/4MWDL66vdIsANBQ=="
|
||||
"resolved": "17.11.48",
|
||||
"contentHash": "C3WIMt2wBl4++NX3jSEpTq5KXBhvAV154R4JrYHkfy9JSBcXWiL0mkgpspk5xSdOj+fS/uz7zluIy6bMM1fkkQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
@@ -97,8 +97,8 @@
|
||||
},
|
||||
"Microsoft.NET.StringTools": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "mudqUHhNpeqIdJoUx2YDWZO/I9uEDYVowan89R6wsomfnUJQk6HteoQTlNjZDixhT2B4IXMkMtgZtoceIjLRmA=="
|
||||
"resolved": "17.11.48",
|
||||
"contentHash": "0IQo089IGBEC4jgtishauZMVr9ZxOWNiGKeDvyzZlvw7p2r253lJh6IJCLLFWXvZnVrVO5mnsYIPamxFPzM08w=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
|
||||
"type": "Transitive",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CA1502: 25
|
||||
CA1501: 5
|
||||
CA1506(Method): 50
|
||||
CA1506(Method): 60
|
||||
CA1506(Type): 95
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Converters.ArcGIS3;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Bindings;
|
||||
|
||||
public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
{
|
||||
public string Name { get; } = "receiveBinding";
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<ArcGISReceiveBinding> _logger;
|
||||
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
|
||||
|
||||
private ReceiveBindingUICommands Commands { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public ArcGISReceiveBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISReceiveBinding> logger,
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_cancellationManager = cancellationManager;
|
||||
Parent = parent;
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
_serviceProvider = serviceProvider;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
}
|
||||
|
||||
public async Task Receive(string modelCardId)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get receiver card
|
||||
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No download model card was found.");
|
||||
}
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
// Receive host objects
|
||||
var receiveOperationResults = await scope
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.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);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
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,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
Parent = parent;
|
||||
|
||||
// example: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Authoring/QueryBuilderControl/DefinitionQueryDockPaneViewModel.cs
|
||||
// MapViewEventArgs args = new(MapView.Active);
|
||||
TOCSelectionChangedEvent.Subscribe(_ => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged), true);
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
SelectionInfo selInfo = GetSelection();
|
||||
Parent.Send(SelectionBindingEvents.SET_SELECTION, selInfo);
|
||||
}
|
||||
|
||||
private void GetLayersFromGroup(GroupLayer group, List<MapMember> nestedLayers)
|
||||
{
|
||||
nestedLayers.Add(group);
|
||||
foreach (MapMember member in group.Layers)
|
||||
{
|
||||
if (member is GroupLayer subGroup)
|
||||
{
|
||||
GetLayersFromGroup(subGroup, nestedLayers);
|
||||
}
|
||||
else
|
||||
{
|
||||
nestedLayers.Add(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection()
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
List<MapMember> selectedMembers = new();
|
||||
selectedMembers.AddRange(mapView.GetSelectedLayers());
|
||||
selectedMembers.AddRange(mapView.GetSelectedStandaloneTables());
|
||||
|
||||
List<MapMember> allNestedMembers = new();
|
||||
var layerMapMembers = _mapMemberUtils.UnpackMapLayers(selectedMembers);
|
||||
allNestedMembers.AddRange(layerMapMembers);
|
||||
|
||||
List<string> objectTypes = allNestedMembers
|
||||
.Select(o => o.GetType().ToString().Split(".").Last())
|
||||
.Distinct()
|
||||
.ToList();
|
||||
return new SelectionInfo(
|
||||
allNestedMembers.Select(x => x.URI).ToList(),
|
||||
$"{allNestedMembers.Count} layers ({string.Join(", ", objectTypes)})"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,483 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Editing.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
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;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
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.ArcGIS3;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Bindings;
|
||||
|
||||
public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
public string Name => "sendBinding";
|
||||
public SendBindingUICommands Commands { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<ArcGISSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
/// [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();
|
||||
|
||||
private List<FeatureLayer> SubscribedLayers { get; set; } = new();
|
||||
private List<StandaloneTable> SubscribedTables { get; set; } = new();
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
public ArcGISSendBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
ICancellationManager cancellationManager,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISSendBinding> logger,
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
IThreadContext threadContext,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
_threadContext = threadContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
SubscribeToArcGISEvents();
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
}
|
||||
|
||||
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
|
||||
|
||||
private void SubscribeToArcGISEvents()
|
||||
{
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
|
||||
ActiveMapViewChangedEvent.Subscribe(
|
||||
_ =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
|
||||
}),
|
||||
true
|
||||
);
|
||||
|
||||
/*
|
||||
LayersAddedEvent.Subscribe(a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForLayersAddedEvent(a)), true);
|
||||
|
||||
StandaloneTablesAddedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForStandaloneTablesAddedEvent(a)),
|
||||
true
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
private void SubscribeToMapMembersDataSourceChange()
|
||||
{
|
||||
if (MapView.Active == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// subscribe to layers
|
||||
foreach (Layer layer in MapView.Active.Map.Layers)
|
||||
{
|
||||
if (layer is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
}
|
||||
// subscribe to tables
|
||||
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToFeatureLayerDataSourceChange(FeatureLayer layer)
|
||||
{
|
||||
if (SubscribedLayers.Contains(layer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Table layerTable = layer.GetTable();
|
||||
if (layerTable != null)
|
||||
{
|
||||
SubscribeToAnyDataSourceChange(layerTable);
|
||||
SubscribedLayers.Add(layer);
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToTableDataSourceChange(StandaloneTable table)
|
||||
{
|
||||
if (SubscribedTables.Contains(table))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Table layerTable = table.GetTable();
|
||||
if (layerTable != null)
|
||||
{
|
||||
SubscribeToAnyDataSourceChange(layerTable);
|
||||
SubscribedTables.Add(table);
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToAnyDataSourceChange(Table layerTable)
|
||||
{
|
||||
RowCreatedEvent.Subscribe(
|
||||
(args) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowChangedEvent.Subscribe(
|
||||
(args) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowDeletedEvent.Subscribe(
|
||||
(args) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
}
|
||||
|
||||
private async Task OnRowChanged(RowChangedEventArgs args)
|
||||
{
|
||||
if (args == null || MapView.Active == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get the path of the edited dataset
|
||||
Uri datasetPath = args.Row.GetTable().GetPath();
|
||||
|
||||
foreach (Layer layer in MapView.Active.Map.Layers)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (layer.GetPath() == datasetPath)
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
}
|
||||
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
|
||||
{
|
||||
// ignore layers with invalid source URI
|
||||
}
|
||||
}
|
||||
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (table.GetPath() == datasetPath)
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
}
|
||||
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
|
||||
{
|
||||
// ignore layers with invalid source URI
|
||||
}
|
||||
}
|
||||
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
|
||||
private async Task GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
{
|
||||
foreach (Layer layer in args.Layers)
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(true);
|
||||
}
|
||||
|
||||
private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
{
|
||||
foreach (StandaloneTable table in args.Tables)
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(true);
|
||||
}
|
||||
|
||||
private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
{
|
||||
foreach (Map map in args.Maps)
|
||||
{
|
||||
List<MapMember> allMapMembers = _mapMemberUtils.GetAllMapMembers(map);
|
||||
foreach (MapMember member in allMapMembers)
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersAddedEvent(LayerEventsArgs args)
|
||||
{
|
||||
foreach (Layer layer in args.Layers)
|
||||
{
|
||||
if (layer is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetIdsForStandaloneTablesAddedEvent(StandaloneTableEventArgs args)
|
||||
{
|
||||
foreach (StandaloneTable table in args.Tables)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
|
||||
{
|
||||
// don't subscribe to all events (e.g. expanding group, changing visibility etc.)
|
||||
bool validEvent = false;
|
||||
foreach (var hint in args.EventHints)
|
||||
{
|
||||
if (
|
||||
hint == MapMemberEventHint.DataSource
|
||||
|| hint == MapMemberEventHint.DefinitionQuery
|
||||
|| hint == MapMemberEventHint.LabelClasses
|
||||
|| hint == MapMemberEventHint.LabelVisibility
|
||||
|| hint == MapMemberEventHint.Name
|
||||
|| hint == MapMemberEventHint.Renderer
|
||||
|| hint == MapMemberEventHint.SceneLayerType
|
||||
|| hint == MapMemberEventHint.URL
|
||||
)
|
||||
{
|
||||
validEvent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (validEvent)
|
||||
{
|
||||
foreach (MapMember member in args.MapMembers)
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
[SuppressMessage(
|
||||
"Maintainability",
|
||||
"CA1506:Avoid excessive class coupling",
|
||||
Justification = "Being refactored on in parallel, muting this issue so CI can pass initially."
|
||||
)]
|
||||
public async Task Send(string modelCardId)
|
||||
{
|
||||
//poc: dupe code between connectors
|
||||
|
||||
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 cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
List<MapMember> mapMembers = await QueuedTask.Run(() =>
|
||||
{
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
|
||||
return modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
});
|
||||
|
||||
if (mapMembers.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
await QueuedTask.Run(() =>
|
||||
{
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
{
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await 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);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any sender model cards contain any of the changed objects. If so, also updates the changed objects hashset for each model card - this last part is important for on send change detection.
|
||||
/// </summary>
|
||||
private async Task RunExpirationChecks(bool idsDeleted)
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
List<string> expiredSenderIds = new();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
|
||||
foreach (SenderModelCard sender in senders)
|
||||
{
|
||||
var objIds = sender.SendFilter.NotNull().RefreshObjectIds();
|
||||
var intersection = objIds.Intersect(objectIdsList).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(sender.ModelCardId.NotNull());
|
||||
|
||||
// Update the model card object Ids
|
||||
if (idsDeleted && sender.SendFilter is ArcGISSelectionFilter filter)
|
||||
{
|
||||
List<string> remainingObjIds = objIds.SkipWhile(x => intersection.Contains(x)).ToList();
|
||||
filter.SelectedObjectIds = remainingObjIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using ArcProject = ArcGIS.Desktop.Core.Project;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Bindings;
|
||||
|
||||
//poc: dupe code between connectors
|
||||
public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
{
|
||||
public string Name => "baseBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public BasicConnectorBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
}
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
|
||||
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public DocumentInfo? GetDocumentInfo()
|
||||
{
|
||||
if (MapView.Active is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DocumentInfo(ArcProject.Current.URI, MapView.Active.Map.Name, MapView.Active.Map.URI);
|
||||
}
|
||||
|
||||
public DocumentModelStore GetDocumentState() => _store;
|
||||
|
||||
public void AddModel(ModelCard model) => _store.AddModel(model);
|
||||
|
||||
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
}
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
if (model is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var objectIds = new List<ObjectID>();
|
||||
|
||||
if (model is SenderModelCard senderModelCard)
|
||||
{
|
||||
objectIds = senderModelCard.SendFilter.NotNull().RefreshObjectIds().Select(x => new ObjectID(x)).ToList();
|
||||
}
|
||||
|
||||
if (model is ReceiverModelCard receiverModelCard)
|
||||
{
|
||||
objectIds = receiverModelCard.BakedObjectIds.NotNull().Select(x => new ObjectID(x)).ToList();
|
||||
}
|
||||
|
||||
if (objectIds is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await HighlightObjectsOnView(objectIds);
|
||||
}
|
||||
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
await QueuedTask.Run(() =>
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
foreach (ObjectID objectId in objectIds)
|
||||
{
|
||||
MapMember mapMember = mapView.Map.FindLayer(objectId.MappedLayerURI, true);
|
||||
if (mapMember is null)
|
||||
{
|
||||
mapMember = mapView.Map.FindStandaloneTable(objectId.MappedLayerURI);
|
||||
}
|
||||
if (mapMember is not null)
|
||||
{
|
||||
MapMemberFeature mapMembersFeat = new(mapMember, objectId.FeatureId);
|
||||
mapMembersFeatures.Add(mapMembersFeat);
|
||||
}
|
||||
}
|
||||
return mapMembersFeatures;
|
||||
}
|
||||
|
||||
private void ClearSelection()
|
||||
{
|
||||
List<Layer> mapMembers = MapView.Active.Map.GetLayersAsFlattenedList().ToList();
|
||||
foreach (var member in mapMembers)
|
||||
{
|
||||
if (member is FeatureLayer featureLayer)
|
||||
{
|
||||
featureLayer.ClearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearSelectionInTOC()
|
||||
{
|
||||
MapView.Active.ClearTOCSelection();
|
||||
}
|
||||
|
||||
private void SelectMapMembersAndFeatures(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
|
||||
{
|
||||
MapMember member = mapMemberFeat.MapMember;
|
||||
if (member is FeatureLayer layer)
|
||||
{
|
||||
if (mapMemberFeat.FeatureId == null)
|
||||
{
|
||||
// select full layer if featureID not specified
|
||||
layer.Select();
|
||||
}
|
||||
else
|
||||
{
|
||||
// query features by ID
|
||||
var objectIDfield = layer.GetFeatureClass().GetDefinition().GetObjectIDField();
|
||||
|
||||
// FeatureID range starts from 0, but auto-assigned IDs in the layer start from 1
|
||||
QueryFilter anotherQueryFilter = new() { WhereClause = $"{objectIDfield} = {mapMemberFeat.FeatureId + 1}" };
|
||||
using (Selection onlyOneSelection = layer.Select(anotherQueryFilter, SelectionCombinationMethod.New)) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
List<Layer> layers = new();
|
||||
List<StandaloneTable> tables = new();
|
||||
|
||||
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
|
||||
{
|
||||
MapMember member = mapMemberFeat.MapMember;
|
||||
if (member is Layer layer)
|
||||
{
|
||||
if (member is not GroupLayer) // group layer selection clears other layers selection
|
||||
{
|
||||
layers.Add(layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
layer.SetExpanded(true);
|
||||
}
|
||||
}
|
||||
else if (member is StandaloneTable table)
|
||||
{
|
||||
tables.Add(table);
|
||||
}
|
||||
}
|
||||
MapView.Active.SelectLayers(layers);
|
||||
|
||||
// this step clears previous selection, not clear how to ADD selection instead
|
||||
// this is why, activating it only if no layers are selected
|
||||
if (layers.Count == 0)
|
||||
{
|
||||
MapView.Active.SelectStandaloneTables(tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2022 Esri
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<ArcGIS defaultAssembly="Speckle.Connectors.ArcGIS3.dll" defaultNamespace="Speckle.Connectors.ArcGIS" xmlns="http://schemas.esri.com/DADF/Registry" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.esri.com/DADF/Registry file:///C:/Program%20Files/ArcGIS/Pro/bin/ArcGIS.Desktop.Framework.xsd">
|
||||
<AddInInfo id="{6CB1D25C-B8BF-4A33-9099-C1F8D1B32EFC}" version="1.0" desktopVersion="3.0.34047">
|
||||
<Name>Speckle</Name>
|
||||
<Description>Next Gen Speckle Connector (Beta) for ArcGIS</Description>
|
||||
<Image>Images\AddinDesktop32.png</Image>
|
||||
<Author>Speckle Systems</Author>
|
||||
<Company>Speckle Systems</Company>
|
||||
<Date>8/5/2021 12:24:21 PM</Date>
|
||||
<Subject>Framework</Subject>
|
||||
<!-- Note subject can be one or more of these topics:
|
||||
Content, Framework, Editing, Geodatabase, Geometry, Geoprocessing, Layouts, Map Authoring, Map Exploration -->
|
||||
</AddInInfo>
|
||||
<modules>
|
||||
<insertModule id="ConnectorArcGIS_Module" className="SpeckleModule" autoLoad="false" caption="SpeckleModule">
|
||||
<!-- uncomment to have the control hosted on a separate tab-->
|
||||
<tabs>
|
||||
<tab id="Speckle_Tab1" caption="Speckle">
|
||||
<group refID="Speckle_Group1"/>
|
||||
</tab>
|
||||
</tabs>
|
||||
<groups>
|
||||
<!-- comment this out if you have no controls on the Addin tab to avoid
|
||||
an empty group. change appearsOnAddinTab to "True" if control is to be in the addin tab-->
|
||||
<group id="Speckle_Group1" caption="Speckle" appearsOnAddInTab="false" keytip="G1">
|
||||
<!-- host controls within groups -->
|
||||
<button refID="SpeckleDUI3_SpeckleDUI3OpenButton" size="large" />
|
||||
</group>
|
||||
</groups>
|
||||
<controls>
|
||||
<!-- add your controls here -->
|
||||
<button id="SpeckleDUI3_SpeckleDUI3OpenButton" caption="Speckle (Beta)"
|
||||
className="SpeckleDUI3OpenButton" loadOnClick="true"
|
||||
keytip="B1"
|
||||
smallImage="Images/s2logo_16.png"
|
||||
largeImage="Images/s2logo_32.png">
|
||||
<tooltip heading="Speckle Connector for ArcGIS">
|
||||
<disabledText />
|
||||
</tooltip>
|
||||
</button>
|
||||
</controls>
|
||||
|
||||
<dockPanes>
|
||||
<dockPane id="SpeckleDUI3_SpeckleDUI3" caption="Speckle (Beta)" className="SpeckleDUI3ViewModel" keytip="DockPane" initiallyVisible="true" dock="group" dockWith="esri_core_projectDockPane">
|
||||
<content className="SpeckleDUI3Wrapper" />
|
||||
</dockPane>
|
||||
</dockPanes>
|
||||
|
||||
</insertModule>
|
||||
</modules>
|
||||
</ArcGIS>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 714 B |
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,66 +0,0 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.ArcGIS.Bindings;
|
||||
using Speckle.Connectors.ArcGIS.Filters;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Operations.Receive;
|
||||
using Speckle.Connectors.ArcGis.Operations.Send;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
|
||||
// POC: This is a temp reference to root object senders to tweak CI failing after having generic interfaces into common project.
|
||||
// This should go whenever it is aligned.
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.DependencyInjection;
|
||||
|
||||
public static class ArcGISConnectorModule
|
||||
{
|
||||
public static void AddArcGIS(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddConnectors();
|
||||
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
serviceCollection.AddSingleton<IBinding, TestBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, ConfigBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, AccountBinding>();
|
||||
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
|
||||
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBinding>();
|
||||
|
||||
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());
|
||||
|
||||
// register send operation and dependencies
|
||||
serviceCollection.AddSingleton<IBinding, ArcGISSendBinding>();
|
||||
serviceCollection.AddScoped<SendOperation<MapMember>>();
|
||||
serviceCollection.AddSingleton<IBinding, ArcGISSelectionBinding>();
|
||||
serviceCollection.AddTransient<ISendFilter, ArcGISSelectionFilter>();
|
||||
serviceCollection.AddScoped<ArcGISRootObjectBuilder>();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<MapMember>, ArcGISRootObjectBuilder>();
|
||||
serviceCollection.AddScoped<ArcGISLayerUnpacker>();
|
||||
serviceCollection.AddScoped<ArcGISColorUnpacker>();
|
||||
// register send conversion cache
|
||||
serviceCollection.AddSingleton<ISendConversionCache, SendConversionCache>();
|
||||
|
||||
// register receive operation and dependencies
|
||||
// serviceCollection.AddSingleton<IBinding, ArcGISReceiveBinding>(); // POC: disabled until receive code is refactored
|
||||
serviceCollection.AddScoped<LocalToGlobalConverterUtils>();
|
||||
serviceCollection.AddScoped<ArcGISColorManager>();
|
||||
serviceCollection.AddScoped<IHostObjectBuilder, ArcGISHostObjectBuilder>();
|
||||
|
||||
serviceCollection.AddScoped<MapMembersUtils>();
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
}
|
||||
}
|
||||
@@ -1,356 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project>
|
||||
<!-- Code to zip up the files-->
|
||||
|
||||
<UsingTask TaskName="PackageAddIn" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||
<ParameterGroup>
|
||||
<ZipIntermediatePath ParameterType="System.String" Required="true" />
|
||||
<PackageType ParameterType="System.String" Required="true" />
|
||||
<TargetFolder ParameterType="System.String" Required="true" />
|
||||
<TargetFileName ParameterType="System.String" Required="true" />
|
||||
<RootNamespace ParameterType="System.String" Required="true" />
|
||||
<PackageOutputPath ParameterType="System.String" Output="true"/>
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<!-- <Reference Include="System.IO.Compression.FileSystem"/>-->
|
||||
<!-- <Reference Include="System.Xml.Linq"/>-->
|
||||
<!-- <Reference Include="System.Xml"/>-->
|
||||
<Using Namespace="System"/>
|
||||
<Using Namespace="System.IO"/>
|
||||
<Using Namespace="System.Xml.Linq"/>
|
||||
<Using Namespace="System.Linq"/>
|
||||
<Using Namespace="System.IO.Compression"/>
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
Success = false;
|
||||
string ConfigNotFound = "{0} was not found. File must be present in the root of the project and its build action set to AddInContent.";
|
||||
string ZipIntermediatePathNotFound = "{0} was not found.";
|
||||
string DefaultAssemblyDoesNotMatch = "Your value of '{0}' for the '{1}' attribute in the {2} does not match the assembly name '{3}' set for your project.";
|
||||
string DefaultNSDoesNotMatch = "Your value of '{0}' for the '{1}' attribute in the {2} does not match the default namespace '{3}' set for your project.";
|
||||
//Create the name of the Config File and extension
|
||||
string extension = "";
|
||||
string config = "";
|
||||
string attrib_asm = "";
|
||||
string attrib_ns = "";
|
||||
var assemblyValMissing = "";
|
||||
var nsValMissing = "";
|
||||
if (PackageType.ToLower() == "plugin")
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "This is an plugin");
|
||||
config = "Config.xml";
|
||||
extension = ".esriPlugin";
|
||||
attrib_asm = "library";
|
||||
attrib_ns = "namespace";
|
||||
assemblyValMissing = "AddIn element 'library' attribute not found";
|
||||
nsValMissing = "AddIn element 'namespace' attribute not found";
|
||||
}
|
||||
else if (PackageType.ToLower() == "configuration")
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "This is an configuration");
|
||||
config = "Config.daml";
|
||||
extension = ".proConfigX";
|
||||
attrib_asm = "defaultAssembly";
|
||||
attrib_ns = "defaultNamespace";
|
||||
assemblyValMissing = "ArcGIS element 'defaultAssembly' attribute not found";
|
||||
nsValMissing = "ArcGIS element 'defaultNamespace' attribute not found";
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "This is an addin");
|
||||
config = "Config.daml";
|
||||
bool proSDKProject = File.Exists(Path.Combine(ZipIntermediatePath, config));
|
||||
if (!proSDKProject) //This might be a class library that uses the Pro references only
|
||||
return true;
|
||||
extension = ".esriAddinX";
|
||||
attrib_asm = "defaultAssembly";
|
||||
attrib_ns = "defaultNamespace";
|
||||
assemblyValMissing = "ArcGIS element 'defaultAssembly' attribute not found";
|
||||
nsValMissing = "ArcGIS element 'defaultNamespace' attribute not found";
|
||||
}
|
||||
// Check if Config.daml exists in ZipFolder
|
||||
ZipIntermediatePath = Path.GetFullPath(ZipIntermediatePath);
|
||||
if (!Directory.Exists(ZipIntermediatePath))
|
||||
{
|
||||
Log.LogError(ZipIntermediatePathNotFound, ZipIntermediatePath);
|
||||
return false;
|
||||
}
|
||||
var addInXML = Path.Combine(ZipIntermediatePath, config);
|
||||
Log.LogMessage(MessageImportance.Low, "addInXML: " + addInXML);
|
||||
Log.LogMessage(MessageImportance.High, "PackageType: " + PackageType);
|
||||
if (!File.Exists(addInXML))
|
||||
{
|
||||
Log.LogError(ConfigNotFound, config);
|
||||
return false;
|
||||
}
|
||||
//Verfiy that an assembly with the name defined in the Config.daml
|
||||
//matches the default assembly set in the project. Ditto for the
|
||||
//namespace
|
||||
string DefaultAssembly = "";
|
||||
string DefaultNamespace = "";
|
||||
XDocument xdoc = XDocument.Load(addInXML);
|
||||
XNamespace DefaultNS = "http://schemas.esri.com/DADF/Registry";
|
||||
if (PackageType.ToLower() == "plugin")
|
||||
{
|
||||
var addin = xdoc.Root.Element(DefaultNS + "AddIn");
|
||||
if (addin != null)
|
||||
{
|
||||
var val = addin.Attribute("library");
|
||||
if (val != null)
|
||||
DefaultAssembly = val.Value;
|
||||
val = addin.Attribute("namespace");
|
||||
if (val != null)
|
||||
DefaultNamespace = val.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var val = xdoc.Root.Attribute("defaultAssembly");
|
||||
if (val != null)
|
||||
DefaultAssembly = val.Value;
|
||||
val = xdoc.Root.Attribute("defaultNamespace");
|
||||
if (val != null)
|
||||
DefaultNamespace = val.Value;
|
||||
}
|
||||
if (string.IsNullOrEmpty(DefaultAssembly))
|
||||
{
|
||||
Log.LogError(assemblyValMissing);
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(DefaultNamespace))
|
||||
{
|
||||
Log.LogError(nsValMissing);
|
||||
return false;
|
||||
}
|
||||
|
||||
//check that the addin assembly and default assembly names match
|
||||
if (DefaultAssembly.ToLower() != TargetFileName.ToLower())
|
||||
{
|
||||
Log.LogWarning(DefaultAssemblyDoesNotMatch, DefaultAssembly, attrib_asm, config, TargetFileName);
|
||||
}
|
||||
//Ditto for namespace
|
||||
if (DefaultNamespace.ToLower() != RootNamespace.ToLower())
|
||||
{
|
||||
Log.LogWarning(DefaultNSDoesNotMatch, DefaultNamespace, attrib_ns, config, RootNamespace);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(TargetFolder))
|
||||
{
|
||||
Directory.CreateDirectory(TargetFolder);
|
||||
}
|
||||
|
||||
string addInAssembly = System.IO.Path.GetFileNameWithoutExtension(DefaultAssembly);
|
||||
string archiveName = addInAssembly + extension;
|
||||
try
|
||||
{
|
||||
string file = Path.Combine(TargetFolder, archiveName);
|
||||
if (File.Exists(file))
|
||||
File.Delete(file);
|
||||
System.IO.Compression.ZipFile.CreateFromDirectory(ZipIntermediatePath, file);
|
||||
PackageOutputPath = Path.GetFullPath(file);
|
||||
Success = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
<!-- Code to find relative path-->
|
||||
<UsingTask TaskName="ConvertToRelativePath" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||
<ParameterGroup>
|
||||
<RelativeTo ParameterType="System.String" Required="true"/>
|
||||
<Paths ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
|
||||
<RelativePaths ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true"/>
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Using Namespace="System"/>
|
||||
<Using Namespace="System.IO"/>
|
||||
<Using Namespace="System.Linq"/>
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
var result = new List<ITaskItem>();
|
||||
System.Uri relativeTo = new Uri(this.RelativeTo);
|
||||
foreach (var i in Paths) {
|
||||
try {
|
||||
System.Uri itemFullPath = new Uri(i.GetMetadata("FullPath"));
|
||||
var relativeUri = relativeTo.MakeRelativeUri(itemFullPath);
|
||||
|
||||
result.Add(new TaskItem(Uri.UnescapeDataString(relativeUri.ToString())));
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
RelativePaths = result.ToArray();
|
||||
foreach (var i in RelativePaths)
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, "RelativePaths: " + i.ToString());
|
||||
}
|
||||
Success = true;
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
<UsingTask TaskName="CleanAddIn" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||
<ParameterGroup>
|
||||
<ProjectDir ParameterType="System.String" Required="true"/>
|
||||
<AssemblyName ParameterType="System.String" Required="true"/>
|
||||
<PackageType ParameterType="System.String" Required="true"/>
|
||||
<!--<ArcGISFolder ParameterType="System.String" Output="true" /> -->
|
||||
<CleanInfo ParameterType="System.String" Output="true"/>
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<!-- <Reference Include="System.Xml.Linq"/>-->
|
||||
<!-- <Reference Include="System.Xml"/>-->
|
||||
<Using Namespace="System"/>
|
||||
<Using Namespace="System.IO"/>
|
||||
<Using Namespace="System.Xml.Linq"/>
|
||||
<Using Namespace="System.Linq"/>
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
Success = false;
|
||||
string ConfigNotFound = "{0} was not found. File must be present in the root of the project and its build action set to AddInContent.";
|
||||
|
||||
//Create the name of the Config File and extension
|
||||
string extension = "";
|
||||
string config = "";
|
||||
|
||||
if (PackageType.ToLower() == "plugin")
|
||||
{
|
||||
config = "Config.xml";
|
||||
extension = ".esriPlugin";
|
||||
}
|
||||
else if (PackageType.ToLower() == "configuration")
|
||||
{
|
||||
config = "Config.daml";
|
||||
extension = ".proConfigX";
|
||||
}
|
||||
else
|
||||
{
|
||||
config = "Config.daml";
|
||||
bool proSDKProject = File.Exists(Path.Combine(ProjectDir, config));
|
||||
if (!proSDKProject) //This might be a class library that uses the Pro references only
|
||||
return true;
|
||||
extension = ".esriAddinX";
|
||||
}
|
||||
|
||||
var addInXML = Path.Combine(ProjectDir, config);
|
||||
if (!File.Exists(addInXML))
|
||||
{
|
||||
Log.LogError(ConfigNotFound, config);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get the add-in id
|
||||
XDocument xdoc = XDocument.Load(addInXML);
|
||||
XNamespace DefaultNS = "http://schemas.esri.com/DADF/Registry";
|
||||
if (PackageType.ToLower() == "plugin")
|
||||
{
|
||||
Log.LogMessage("process plugin");
|
||||
var addInID = xdoc.Root.Element(DefaultNS + "AddInID");
|
||||
CleanInfo = addInID.Value;//let it error if it's missing
|
||||
}
|
||||
else if (PackageType.ToLower() == "addin")
|
||||
{
|
||||
Log.LogMessage("process addin");
|
||||
var addinInfo = xdoc.Root.Element(DefaultNS + "AddInInfo");
|
||||
CleanInfo = addinInfo.Attribute("id").Value;//let it error if it's missing
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage("process configuration");
|
||||
CleanInfo = AssemblyName + extension;
|
||||
}
|
||||
Success = true;
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
<!-- Define additional BuildAction option -->
|
||||
<!-- Set up default zip properties -->
|
||||
<PropertyGroup>
|
||||
<PackageType Condition="'$(PackageType)' == ''">Addin</PackageType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ArcGISFolder>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\ESRI\ArcGISPro', 'InstallDir', null, RegistryView.Registry64))\bin</ArcGISFolder>
|
||||
<ArcGISFolder Condition="'$(ArcGISFolder)' == ''">$(registry:HKEY_CURRENT_USER\SOFTWARE\ESRI\ArcGISPro@InstallDir)\bin</ArcGISFolder>
|
||||
<ArcGISFolder Condition="'$(ArcGISFolder)' == '' Or !Exists('$(ArcGISFolder)\RegisterAddIn.exe')">$(ProgramData)\EsriProCommon\</ArcGISFolder>
|
||||
</PropertyGroup>
|
||||
<Target Name="ArcGISInstallOutput" AfterTargets="Build">
|
||||
<Message Text="IntermediateOutputPath Name: $(IntermediateOutputPath)..." Importance="High"/>
|
||||
<Message Text="CleanFile Name: $(CleanFile)..." Importance="High"/>
|
||||
<Message Text="ProjectDir Name: $(ProjectDir)..." Importance="High"/>
|
||||
<Message Text="AssemblyName Name: $(AssemblyName)..." Importance="High"/>
|
||||
<Message Text="TargetFileName Name: $(TargetFileName)..." Importance="High"/>
|
||||
<Message Text="RootNamespace: $(RootNamespace)..." Importance="High"/>
|
||||
<Message Text="TargetFolder Name: $(OutDir)..." Importance="High"/>
|
||||
<Message Text="PackageType Name: $(PackageType)..." Importance="High"/>
|
||||
<Message Text="Install dir: $(ArcGISFolder)" Importance="High"/>
|
||||
<!-- Get a list of project outputs from the cache file and FileWritesXXX item,
|
||||
excluding those in intermediate output directory -->
|
||||
<!-- Note clean file may miss listing CopyLocal reference -->
|
||||
<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
|
||||
<Output TaskParameter="Lines" ItemName="CacheOutputFiles" />
|
||||
</ReadLinesFromFile>
|
||||
<FindUnderPath Files="@(CacheOutputFiles)" Path="$(OutDir)">
|
||||
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
|
||||
</FindUnderPath>
|
||||
<FindUnderPath Files="@(FileWrites->'%(FullPath)')" Path="$(OutDir)">
|
||||
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
|
||||
</FindUnderPath>
|
||||
<FindUnderPath Files="@(FileWritesShareable->'%(FullPath)')" Path="$(OutDir)">
|
||||
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
|
||||
</FindUnderPath>
|
||||
<RemoveDuplicates Inputs="@(PackageOutputFiles)">
|
||||
<Output TaskParameter="Filtered" ItemName="FilteredPackageOutputFiles" />
|
||||
</RemoveDuplicates>
|
||||
<ConvertToRelativePath Paths="@(FilteredPackageOutputFiles)" RelativeTo="$(TargetDir)">
|
||||
<Output TaskParameter="RelativePaths" ItemName="ConfigBinaries" />
|
||||
</ConvertToRelativePath>
|
||||
<Message Text="ConvertToRelativePath Task, TargetDir: $(TargetDir) " Importance="High"/>
|
||||
</Target>
|
||||
<Target Name="PackageArcGISContents" AfterTargets="ArcGISInstallOutput">
|
||||
<Message Text="Running PackageArcGISContents..." Importance="High"/>
|
||||
<RemoveDir Condition="Exists('$(ZipIntermediatePath)')" Directories="$(ZipIntermediatePath)" />
|
||||
<Message Text="ZipIntermediatePath: $(ZipIntermediatePath)Install..." Importance="High"/>
|
||||
<!-- Copy project output files, preserving folder structure -->
|
||||
<Copy SourceFiles="@(ConfigBinaries->'$(OutDir)%(Identity)')" ContinueOnError="true" DestinationFolder="$(IntermediateOutputPath)temp_archive\Install\%(RelativeDir)" />
|
||||
<!-- Copy items marked with Content as BuildAction, preserving folder structure & handling linked items -->
|
||||
<!-- Only include items that have CopyToOutputDirectory as Never -->
|
||||
<Copy SourceFiles="@(Content)" Condition="'%(Content.Link)' == '' And ('%(Content.CopyToOutputDirectory)' == 'Never' Or '%(Content.CopyToOutputDirectory)' == '')" DestinationFolder="$(IntermediateOutputPath)temp_archive\%(RelativeDir)" ContinueOnError="true" />
|
||||
<Copy SourceFiles="@(Content)" Condition="'%(Content.Link)' != '' And ('%(Content.CopyToOutputDirectory)' == 'Never' Or '%(Content.CopyToOutputDirectory)' == '')" DestinationFiles="$(IntermediateOutputPath)temp_archive\%(Content.Link)" ContinueOnError="true"/>
|
||||
<!-- Zipping up add-in resources -->
|
||||
<PackageAddIn ZipIntermediatePath="$(IntermediateOutputPath)temp_archive\"
|
||||
PackageType="$(PackageType)"
|
||||
TargetFolder="$(OutDir)"
|
||||
TargetFileName="$(TargetFileName)"
|
||||
RootNamespace="$(RootNamespace)">
|
||||
<Output TaskParameter="PackageOutputPath" PropertyName="PackageFile" />
|
||||
</PackageAddIn>
|
||||
<!-- Shell out to RegisterAddIn.exe to install the package -->
|
||||
<Message Text="Deploying $(PackageType)..." Importance="High"/>
|
||||
<Message Text="ArcGISFolder Name: $(ArcGISFolder)..." Importance="High"/>
|
||||
<Message Text="Unable to execute RegisterAddIn.exe. ArcGIS Pro is not installed." Importance="High" Condition="!Exists('$(ArcGISFolder)')"/>
|
||||
<Message Text="Execute RegisterAddIn.exe "$(PackageFile)" /s..." Importance="High" Condition="Exists('$(ArcGISFolder)')"/>
|
||||
<Exec IgnoreExitCode="true" WorkingDirectory="$(ArcGISFolder)" Command="RegisterAddIn.exe "$(PackageFile)" /s" Condition="Exists('$(ArcGISFolder)') AND $(PackageFile) != '' ">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ESRIRegAddinExitCode" />
|
||||
</Exec>
|
||||
<RemoveDir Condition="Exists('$(ZipIntermediatePath)')" Directories="$(ZipIntermediatePath)" />
|
||||
</Target>
|
||||
<Target Name="CleanArcGISContents" AfterTargets="Clean">
|
||||
<CleanAddIn ProjectDir="$(ProjectDir)"
|
||||
AssemblyName="$(AssemblyName)"
|
||||
PackageType="$(PackageType)">
|
||||
<Output TaskParameter="CleanInfo" PropertyName="CleanInfo" />
|
||||
</CleanAddIn>
|
||||
<Message Text="Clean $(PackageType).$(ArcGISFolder).." Importance="High"/>
|
||||
<Message Text="Execute RegisterAddIn.exe "$(CleanInfo)" /u..." Importance="High" Condition="Exists('$(ArcGISFolder)')"/>
|
||||
<Message Text="Unable to execute RegisterAddIn.exe. ArcGIS Pro is not installed." Importance="High" Condition="!Exists('$(ArcGISFolder)')"/>
|
||||
<Exec IgnoreExitCode="true" WorkingDirectory="$(ArcGISFolder)" Command="RegisterAddIn.exe "$(CleanInfo)" /u /s" Condition="Exists('$(ArcGISFolder)') AND $(CleanInfo) != ''">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ESRIRegAddinExitCode" />
|
||||
</Exec>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,13 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Filters;
|
||||
|
||||
public class ArcGISSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public ArcGISSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override List<string> RefreshObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
global using AC = ArcGIS.Core;
|
||||
global using ACD = ArcGIS.Core.Data;
|
||||
global using ADM = ArcGIS.Desktop.Mapping;
|
||||
@@ -1,265 +0,0 @@
|
||||
using System.Drawing;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Objects;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Extensions;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// TODO: definitely need to refactor this, probably will collect colors during layer iteration in the root object builder.
|
||||
/// </summary>
|
||||
public class ArcGISColorManager
|
||||
{
|
||||
public Dictionary<string, Color> ObjectColorsIdMap { get; set; } = new();
|
||||
public Dictionary<string, Color> ObjectMaterialsIdMap { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Parse Color Proxies and stores in ObjectColorsIdMap the relationship between object ids and colors
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void 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.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value);
|
||||
ObjectColorsIdMap.TryAdd(objectId, convertedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse Color renderMaterials and stores in ObjectMaterialsIdMap the relationship between object ids and colors
|
||||
/// </summary>
|
||||
/// <param name="materialProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void 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.Report(new("Converting materials", (double)++count / materialProxies.Count));
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value.diffuse);
|
||||
ObjectMaterialsIdMap.TryAdd(objectId, convertedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CIMColorToInt(CIMColor color)
|
||||
{
|
||||
return (255 << 24)
|
||||
| ((int)Math.Round(color.Values[0]) << 16)
|
||||
| ((int)Math.Round(color.Values[1]) << 8)
|
||||
| (int)Math.Round(color.Values[2]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new CIMUniqueValueClass for UniqueRenderer per each object ID
|
||||
/// </summary>
|
||||
/// <param name="tc"></param>
|
||||
/// <param name="speckleGeometryType"></param>
|
||||
private CIMUniqueValueClass CreateColorCategory(
|
||||
TraversalContext tc,
|
||||
esriGeometryType speckleGeometryType,
|
||||
string uniqueLabel
|
||||
)
|
||||
{
|
||||
// declare default white color
|
||||
Color color = Color.FromArgb(255, 255, 255, 255);
|
||||
bool colorFound = false;
|
||||
|
||||
// get color moving upwards from the object
|
||||
foreach (var parent in tc.GetAscendants())
|
||||
{
|
||||
if (parent.applicationId is string appId)
|
||||
{
|
||||
if (ObjectMaterialsIdMap.TryGetValue(appId, out Color objColorMaterial))
|
||||
{
|
||||
color = objColorMaterial;
|
||||
colorFound = true;
|
||||
break;
|
||||
}
|
||||
if (ObjectColorsIdMap.TryGetValue(appId, out Color objColor))
|
||||
{
|
||||
color = objColor;
|
||||
colorFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handling Revit case, where child objects have separate colors/materials
|
||||
if (!colorFound && tc.Current is IDataObject)
|
||||
{
|
||||
var displayable = tc.Current.TryGetDisplayValue();
|
||||
if (displayable != null)
|
||||
{
|
||||
foreach (var childObj in displayable)
|
||||
{
|
||||
if (childObj.applicationId is string appId)
|
||||
{
|
||||
if (ObjectMaterialsIdMap.TryGetValue(appId, out Color objColorMaterial))
|
||||
{
|
||||
color = objColorMaterial;
|
||||
break;
|
||||
}
|
||||
if (ObjectColorsIdMap.TryGetValue(appId, out Color objColor))
|
||||
{
|
||||
color = objColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CIMSymbolReference symbol = CreateSymbol(speckleGeometryType, color);
|
||||
|
||||
// First create a "CIMUniqueValueClass"
|
||||
List<CIMUniqueValue> listUniqueValues = new() { new CIMUniqueValue { FieldValues = new string[] { uniqueLabel } } };
|
||||
|
||||
CIMUniqueValueClass newUniqueValueClass =
|
||||
new()
|
||||
{
|
||||
Editable = true,
|
||||
Label = uniqueLabel,
|
||||
Patch = PatchShape.Default,
|
||||
Symbol = symbol,
|
||||
Visible = true,
|
||||
Values = listUniqueValues.ToArray()
|
||||
};
|
||||
return newUniqueValueClass;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Symbol from GeometryType and Color
|
||||
/// </summary>
|
||||
/// <param name="speckleGeometryType"></param>
|
||||
/// <param name="color"></param>
|
||||
private CIMSymbolReference CreateSymbol(esriGeometryType speckleGeometryType, Color color)
|
||||
{
|
||||
var symbol = SymbolFactory
|
||||
.Instance.ConstructPointSymbol(ColorFactory.Instance.CreateColor(color))
|
||||
.MakeSymbolReference();
|
||||
|
||||
switch (speckleGeometryType)
|
||||
{
|
||||
case esriGeometryType.esriGeometryLine:
|
||||
case esriGeometryType.esriGeometryPolyline:
|
||||
symbol = SymbolFactory
|
||||
.Instance.ConstructLineSymbol(ColorFactory.Instance.CreateColor(color))
|
||||
.MakeSymbolReference();
|
||||
break;
|
||||
case esriGeometryType.esriGeometryPolygon:
|
||||
case esriGeometryType.esriGeometryMultiPatch:
|
||||
symbol = SymbolFactory
|
||||
.Instance.ConstructPolygonSymbol(ColorFactory.Instance.CreateColor(color))
|
||||
.MakeSymbolReference();
|
||||
break;
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add CIMUniqueValueClass to Layer Renderer (if exists); apply Renderer to Layer (again)
|
||||
/// </summary>
|
||||
/// <param name="tc"></param>
|
||||
/// <param name="trackerItem"></param>
|
||||
public CIMUniqueValueRenderer? CreateOrEditLayerRenderer(
|
||||
TraversalContext tc,
|
||||
ObjectConversionTracker trackerItem,
|
||||
CIMRenderer? existingRenderer
|
||||
)
|
||||
{
|
||||
if (trackerItem.HostAppMapMember is not FeatureLayer fLayer)
|
||||
{
|
||||
// do nothing with non-feature layers
|
||||
return null;
|
||||
}
|
||||
|
||||
// declare default grey color, create default symbol for the given layer geometry type
|
||||
var color = Color.FromArgb(CIMColorToInt(ColorFactory.Instance.GreyRGB));
|
||||
CIMSymbolReference defaultSymbol = CreateSymbol(fLayer.ShapeType, color);
|
||||
|
||||
// get existing renderer classes
|
||||
List<CIMUniqueValueClass> listUniqueValueClasses = new() { };
|
||||
if (existingRenderer is CIMUniqueValueRenderer uniqueRenderer)
|
||||
{
|
||||
if (uniqueRenderer.Groups[0].Classes != null)
|
||||
{
|
||||
listUniqueValueClasses.AddRange(uniqueRenderer.Groups[0].Classes.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
// Add new CIMUniqueValueClass (or multiple, if it's a Collection with elements, e.g. VectorLayer)
|
||||
List<TraversalContext> traversalContexts = new();
|
||||
if (tc.Current is Collection collection)
|
||||
{
|
||||
foreach (var element in collection.elements)
|
||||
{
|
||||
TraversalContext newTc = new(element, "elements", tc);
|
||||
traversalContexts.Add(newTc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
traversalContexts.Add(tc);
|
||||
}
|
||||
|
||||
foreach (var tContext in traversalContexts)
|
||||
{
|
||||
// get unique label
|
||||
string? uniqueLabel = tContext.Current?.id;
|
||||
|
||||
// remove any GIS-specific classes for now
|
||||
/*
|
||||
if (tContext.Current is IGisFeature gisFeat)
|
||||
{
|
||||
var existingLabel = gisFeat.attributes["Speckle_ID"];
|
||||
if (existingLabel is string stringLabel)
|
||||
{
|
||||
uniqueLabel = stringLabel;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (uniqueLabel is not null && !listUniqueValueClasses.Select(x => x.Label).Contains(uniqueLabel))
|
||||
{
|
||||
CIMUniqueValueClass newUniqueValueClass = CreateColorCategory(tContext, fLayer.ShapeType, uniqueLabel);
|
||||
listUniqueValueClasses.Add(newUniqueValueClass);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a list of CIMUniqueValueGroup
|
||||
CIMUniqueValueGroup uvg = new() { Classes = listUniqueValueClasses.ToArray(), Heading = "Speckle_ID" };
|
||||
List<CIMUniqueValueGroup> listUniqueValueGroups = new() { uvg };
|
||||
// Create the CIMUniqueValueRenderer
|
||||
CIMUniqueValueRenderer uvr =
|
||||
new()
|
||||
{
|
||||
UseDefaultSymbol = true,
|
||||
DefaultLabel = "all other values",
|
||||
DefaultSymbol = defaultSymbol,
|
||||
Groups = listUniqueValueGroups.ToArray(),
|
||||
Fields = new string[] { "Speckle_ID" }
|
||||
};
|
||||
return uvr;
|
||||
}
|
||||
}
|
||||
@@ -1,461 +0,0 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp;
|
||||
|
||||
public class ArcGISColorUnpacker
|
||||
{
|
||||
/// <summary>
|
||||
/// Cache of all color proxies for converted features. Key is the Color proxy argb value.
|
||||
/// </summary>
|
||||
public Dictionary<int, ColorProxy> ColorProxyCache { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Stores the current renderer (determined by mapMember)
|
||||
/// </summary>
|
||||
private AC.CIM.CIMRenderer? StoredRenderer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores the current renderer (determined by tin mapmember)
|
||||
/// </summary>
|
||||
private AC.CIM.CIMTinRenderer? StoredTinRenderer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores the used renderer fields from the layer
|
||||
/// </summary>
|
||||
private List<string> StoredRendererFields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores an already processed color for current mapMember, to dbe used by all mapMember objects. Only applies to simple type renderers
|
||||
/// </summary>
|
||||
private int? StoredColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores a feature layer renderer to be used by <see cref="ProcessFeatureLayerColor"/> in <see cref="StoredRenderer"/>, any fields used by the renderer from the layer, and resets the <see cref="StoredColor"/> and <see cref="StoredRendererFields"/>
|
||||
/// </summary>
|
||||
/// <param name="featureLayer"></param>
|
||||
/// <exception cref="AC.CalledOnWrongThreadException">Must be called on MCT.</exception>
|
||||
public void StoreRendererAndFields(ADM.FeatureLayer featureLayer)
|
||||
{
|
||||
// field names are unique, but often their alias is used instead by renderer headings
|
||||
// so we are storing both names and alias in this dictionary for fast lookup
|
||||
// POC: adding aliases are not optimal, because they do not need to be unique && they can be the same as the name of another field
|
||||
Dictionary<string, string> layerFieldDictionary = new();
|
||||
foreach (ADM.FieldDescription field in featureLayer.GetFieldDescriptions())
|
||||
{
|
||||
layerFieldDictionary.TryAdd(field.Name, field.Name);
|
||||
layerFieldDictionary.TryAdd(field.Alias, field.Name);
|
||||
}
|
||||
|
||||
// clear stored values
|
||||
StoredRendererFields = new();
|
||||
StoredColor = null;
|
||||
StoredRenderer = null;
|
||||
|
||||
AC.CIM.CIMRenderer layerRenderer = featureLayer.GetRenderer();
|
||||
List<string> fields = new();
|
||||
bool isSupported = false;
|
||||
switch (layerRenderer)
|
||||
{
|
||||
case AC.CIM.CIMSimpleRenderer:
|
||||
isSupported = true;
|
||||
break;
|
||||
case AC.CIM.CIMUniqueValueRenderer uniqueValueRenderer:
|
||||
isSupported = true;
|
||||
fields = uniqueValueRenderer.Fields.ToList();
|
||||
break;
|
||||
case AC.CIM.CIMClassBreaksRenderer classBreaksRenderer:
|
||||
isSupported = true;
|
||||
fields.Add(classBreaksRenderer.Field);
|
||||
break;
|
||||
default:
|
||||
// TODO: log error here that a renderer is unsupported
|
||||
break;
|
||||
}
|
||||
|
||||
if (isSupported)
|
||||
{
|
||||
StoredRenderer = layerRenderer;
|
||||
foreach (string field in fields)
|
||||
{
|
||||
if (layerFieldDictionary.TryGetValue(field, out string? fieldName))
|
||||
{
|
||||
StoredRendererFields.Add(fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a las layer renderer to be used by <see cref="ProcessLasLayerColor"/> in <see cref="StoredTinRenderer"/>
|
||||
/// </summary>
|
||||
/// <param name="lasLayer"></param>
|
||||
/// <exception cref="AC.CalledOnWrongThreadException">Must be called on MCT.</exception>
|
||||
public void StoreRenderer(ADM.LasDatasetLayer lasLayer)
|
||||
{
|
||||
// clear stored values
|
||||
StoredTinRenderer = null;
|
||||
|
||||
// POC: not sure why we are only using the first renderer here
|
||||
AC.CIM.CIMTinRenderer layerRenderer = lasLayer.GetRenderers()[0];
|
||||
bool isSupported = false;
|
||||
switch (layerRenderer)
|
||||
{
|
||||
case AC.CIM.CIMTinUniqueValueRenderer:
|
||||
isSupported = true;
|
||||
break;
|
||||
default:
|
||||
// TODO: log error here that a renderer is unsupported
|
||||
break;
|
||||
}
|
||||
|
||||
if (isSupported)
|
||||
{
|
||||
StoredTinRenderer = layerRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a las layer's point color by the stored <see cref="StoredRenderer"/>, and stores the point's id and color proxy to the <see cref="ColorProxyCache"/>.
|
||||
/// POC: logic probably can be combined with ProcessFeatureLayerColor.
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
public void ProcessLasLayerColor(ACD.Analyst3D.LasPoint point, string pointApplicationId)
|
||||
{
|
||||
// get the color from the renderer and point
|
||||
AC.CIM.CIMColor? color;
|
||||
switch (StoredTinRenderer)
|
||||
{
|
||||
case AC.CIM.CIMTinUniqueValueRenderer uniqueValueRenderer:
|
||||
color = GetPointColorByUniqueValueRenderer(uniqueValueRenderer, point);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// get or create the color proxy for the point
|
||||
int argb = CIMColorToInt(color ?? point.RGBColor);
|
||||
AddObjectIdToColorProxyCache(pointApplicationId, argb);
|
||||
}
|
||||
|
||||
// Retrieves the las point color from a unique value renderer
|
||||
// unique renderers have groups of conditions that may affect the color of a feature
|
||||
// resulting in a different color than the default renderer symbol color
|
||||
private AC.CIM.CIMColor? GetPointColorByUniqueValueRenderer(
|
||||
AC.CIM.CIMTinUniqueValueRenderer renderer,
|
||||
ACD.Analyst3D.LasPoint point
|
||||
)
|
||||
{
|
||||
foreach (AC.CIM.CIMUniqueValueGroup group in renderer.Groups)
|
||||
{
|
||||
foreach (AC.CIM.CIMUniqueValueClass groupClass in group.Classes)
|
||||
{
|
||||
foreach (AC.CIM.CIMUniqueValue value in groupClass.Values)
|
||||
{
|
||||
// all field values have to match the row values
|
||||
for (int i = 0; i < value.FieldValues.Length; i++)
|
||||
{
|
||||
string groupValue = value.FieldValues[i].Replace("<Null>", "");
|
||||
object? pointValue = point.ClassCode;
|
||||
|
||||
if (ValuesAreEqual(groupValue, pointValue))
|
||||
{
|
||||
return groupClass.Symbol.Symbol.GetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a feature layer's row color by the stored <see cref="StoredRenderer"/>, and stores the row's id and color proxy to the <see cref="ColorProxyCache"/>.
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ACD.Exceptions.GeodatabaseException"></exception>
|
||||
public void ProcessFeatureLayerColor(ACD.Row row, string rowApplicationId)
|
||||
{
|
||||
// if stored color is not null, this means the renderer was a simple renderer that applies to the entire layer, and was already created.
|
||||
// just add the row application id to the color proxy.
|
||||
if (StoredColor is int existingColorProxyId)
|
||||
{
|
||||
AddObjectIdToColorProxyCache(rowApplicationId, existingColorProxyId);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the color from the renderer and row
|
||||
AC.CIM.CIMColor? color = null;
|
||||
switch (StoredRenderer)
|
||||
{
|
||||
// simple renderers do not rely on fields, so the color can be retrieved from the renderer directly
|
||||
case AC.CIM.CIMSimpleRenderer simpleRenderer:
|
||||
color = simpleRenderer.Symbol.Symbol.GetColor();
|
||||
break;
|
||||
|
||||
case AC.CIM.CIMUniqueValueRenderer uniqueValueRenderer:
|
||||
color = GetRowColorByUniqueValueRenderer(uniqueValueRenderer, row);
|
||||
break;
|
||||
|
||||
case AC.CIM.CIMClassBreaksRenderer classBreaksRenderer:
|
||||
color = GetRowColorByClassBreaksRenderer(classBreaksRenderer, row);
|
||||
break;
|
||||
}
|
||||
|
||||
if (color is null)
|
||||
{
|
||||
// TODO: log error or throw exception that color could not be retrieved
|
||||
return;
|
||||
}
|
||||
|
||||
// get or create the color proxy for the row
|
||||
int argb = CIMColorToInt(color);
|
||||
AddObjectIdToColorProxyCache(rowApplicationId, argb);
|
||||
|
||||
// store color if from simple renderer
|
||||
if (StoredRenderer is AC.CIM.CIMSimpleRenderer)
|
||||
{
|
||||
StoredColor = argb;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves the row color from a class breaks renderer
|
||||
// unique renderers have groups of conditions that may affect the color of a feature
|
||||
// resulting in a different color than the default renderer symbol color
|
||||
private AC.CIM.CIMColor? GetRowColorByClassBreaksRenderer(AC.CIM.CIMClassBreaksRenderer renderer, ACD.Row row)
|
||||
{
|
||||
AC.CIM.CIMColor? color = null;
|
||||
|
||||
// get the default symbol color
|
||||
if (renderer.DefaultSymbol?.Symbol.GetColor() is AC.CIM.CIMColor defaultColor)
|
||||
{
|
||||
color = defaultColor;
|
||||
}
|
||||
|
||||
// get the first stored field, since this renderer should only have 1 field
|
||||
double storedFieldValue = Convert.ToDouble(row[StoredRendererFields.First()]);
|
||||
|
||||
List<AC.CIM.CIMClassBreak> reversedBreaks = new(renderer.Breaks);
|
||||
reversedBreaks.Reverse();
|
||||
foreach (var rBreak in reversedBreaks)
|
||||
{
|
||||
// keep looping until the last matching condition
|
||||
if (storedFieldValue <= rBreak.UpperBound)
|
||||
{
|
||||
if (rBreak.Symbol.Symbol.GetColor() is AC.CIM.CIMColor breakColor)
|
||||
{
|
||||
color = breakColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: log error here, could not retrieve break color from symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// Retrieves the row color from a unique value renderer
|
||||
// unique renderers have groups of conditions that may affect the color of a feature
|
||||
// resulting in a different color than the default renderer symbol color
|
||||
private AC.CIM.CIMColor? GetRowColorByUniqueValueRenderer(AC.CIM.CIMUniqueValueRenderer renderer, ACD.Row row)
|
||||
{
|
||||
AC.CIM.CIMColor? color = null;
|
||||
|
||||
// get the default symbol color
|
||||
if (renderer.DefaultSymbol?.Symbol.GetColor() is AC.CIM.CIMColor defaultColor)
|
||||
{
|
||||
color = defaultColor;
|
||||
}
|
||||
|
||||
// note: usually there is only 1 group
|
||||
foreach (AC.CIM.CIMUniqueValueGroup group in renderer.Groups)
|
||||
{
|
||||
// loop through all values in groups to see if any have met conditions that result in a different color
|
||||
foreach (AC.CIM.CIMUniqueValueClass groupClass in group.Classes)
|
||||
{
|
||||
bool groupConditionsMet = true;
|
||||
foreach (AC.CIM.CIMUniqueValue value in groupClass.Values)
|
||||
{
|
||||
// all field values have to match the row values
|
||||
for (int i = 0; i < StoredRendererFields.Count; i++)
|
||||
{
|
||||
string groupValue = value.FieldValues[i];
|
||||
object? rowValue = row[StoredRendererFields[i]];
|
||||
|
||||
if (!ValuesAreEqual(groupValue, rowValue))
|
||||
{
|
||||
groupConditionsMet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the group color to class symbol color if conditions are met
|
||||
if (groupConditionsMet)
|
||||
{
|
||||
if (groupClass.Symbol.Symbol.GetColor() is AC.CIM.CIMColor groupColor)
|
||||
{
|
||||
color = groupColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: log error here, could not retrieve group color from symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the label string of a UniqueValueRenderer (groupValue), and an object value (row, las point), to determine if they are equal
|
||||
/// </summary>
|
||||
/// <param name="objectValue"></param>
|
||||
/// <param name="groupValue"></param>
|
||||
private bool ValuesAreEqual(string groupValue, object? objectValue)
|
||||
{
|
||||
switch (objectValue)
|
||||
{
|
||||
case int:
|
||||
case short:
|
||||
case long:
|
||||
case byte:
|
||||
string objectValueString = Convert.ToString(objectValue) ?? "";
|
||||
return groupValue.Equals(objectValueString);
|
||||
|
||||
case string:
|
||||
return groupValue.Equals(objectValue);
|
||||
|
||||
// POC: these are tricky to compare with the label strings accurately, so will trim both values to 5 decimal places.
|
||||
case double d:
|
||||
return double.TryParse(groupValue, out double groupDouble) && groupDouble - d < 0.000001;
|
||||
case float f:
|
||||
return float.TryParse(groupValue, out float groupFloat) && groupFloat - f < 0.000001;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void AddObjectIdToColorProxyCache(string objectId, int argb)
|
||||
{
|
||||
if (ColorProxyCache.TryGetValue(argb, out ColorProxy? colorProxy))
|
||||
{
|
||||
colorProxy.objects.Add(objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ColorProxy newColorProxy =
|
||||
new()
|
||||
{
|
||||
name = argb.ToString(),
|
||||
objects = new() { objectId },
|
||||
value = argb,
|
||||
applicationId = argb.ToString()
|
||||
};
|
||||
|
||||
ColorProxyCache.Add(argb, newColorProxy);
|
||||
}
|
||||
}
|
||||
|
||||
private int ArgbToInt(int a, int r, int g, int b)
|
||||
{
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
// Gets the argb int from a CIMColor
|
||||
// Defaults to assuming CIMColor.Values represent the red, green, and blue channels.
|
||||
private int CIMColorToInt(AC.CIM.CIMColor color)
|
||||
{
|
||||
switch (color)
|
||||
{
|
||||
case AC.CIM.CIMHSVColor hsv:
|
||||
(float hsvR, float hsvG, float hsvB) = RgbFromHsv(hsv.H, hsv.S, hsv.V);
|
||||
return ArgbToInt(
|
||||
(int)Math.Round(hsv.Alpha),
|
||||
(int)Math.Round(hsvR * 255),
|
||||
(int)Math.Round(hsvG * 255),
|
||||
(int)Math.Round(hsvB * 255)
|
||||
);
|
||||
|
||||
case AC.CIM.CIMCMYKColor cmyk:
|
||||
float k = cmyk.K;
|
||||
int cmykR = Convert.ToInt32(255 * (1 - cmyk.C) * (1 - k));
|
||||
int cmykG = Convert.ToInt32(255 * (1 - cmyk.M) * (1 - k));
|
||||
int cmykB = Convert.ToInt32(255 * (1 - cmyk.Y) * (1 - k));
|
||||
return ArgbToInt((int)Math.Round(cmyk.Alpha), cmykR, cmykG, cmykB);
|
||||
|
||||
default:
|
||||
return ArgbToInt(
|
||||
(int)Math.Round(color.Alpha),
|
||||
(int)Math.Round(color.Values[0]),
|
||||
(int)Math.Round(color.Values[1]),
|
||||
(int)Math.Round(color.Values[2])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private (float, float, float) RgbFromHsv(float hue, float saturation, float value)
|
||||
{
|
||||
// Translates HSV color to RGB color
|
||||
// H: 0.0 - 360.0, S: 0.0 - 100.0, V: 0.0 - 100.0
|
||||
// R, G, B: 0.0 - 1.0
|
||||
|
||||
float c = (value / 100) * (saturation / 100);
|
||||
float x = c * (1 - Math.Abs(((hue / 60) % 2) - 1));
|
||||
float m = (value / 100) - c;
|
||||
|
||||
float r = 0;
|
||||
float g = 0;
|
||||
float b = 0;
|
||||
|
||||
if (hue >= 0 && hue < 60)
|
||||
{
|
||||
r = c;
|
||||
g = x;
|
||||
b = 0;
|
||||
}
|
||||
else if (hue >= 60 && hue < 120)
|
||||
{
|
||||
r = x;
|
||||
g = c;
|
||||
b = 0;
|
||||
}
|
||||
else if (hue >= 120 && hue < 180)
|
||||
{
|
||||
r = 0;
|
||||
g = c;
|
||||
b = x;
|
||||
}
|
||||
else if (hue >= 180 && hue < 240)
|
||||
{
|
||||
r = 0;
|
||||
g = x;
|
||||
b = c;
|
||||
}
|
||||
else if (hue >= 240 && hue < 300)
|
||||
{
|
||||
r = x;
|
||||
g = 0;
|
||||
b = c;
|
||||
}
|
||||
else if (hue >= 300 && hue < 360)
|
||||
{
|
||||
r = c;
|
||||
g = 0;
|
||||
b = x;
|
||||
}
|
||||
|
||||
r += m;
|
||||
g += m;
|
||||
b += m;
|
||||
|
||||
return (r, g, b);
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp;
|
||||
|
||||
public class ArcGISLayerUnpacker
|
||||
{
|
||||
/// <summary>
|
||||
/// Cache of all collections created by unpacked Layer MapMembers. Key is the Speckle applicationId (Layer URI).
|
||||
/// </summary>
|
||||
public Dictionary<string, Collection> CollectionCache { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Mapmembers can be layers containing objects, or LayerContainers containing other layers.
|
||||
/// Unpacks selected mapMembers and creates their corresponding collection on the root collection.
|
||||
/// </summary>
|
||||
/// <param name="mapMembers"></param>
|
||||
/// <param name="parentCollection"></param>
|
||||
/// <returns>List of layers containing objects.</returns>
|
||||
/// <exception cref="AC.CalledOnWrongThreadException">Thrown when this method is *not* called on the MCT, because this method accesses mapmember fields</exception>
|
||||
public List<ADM.MapMember> UnpackSelection(
|
||||
IEnumerable<ADM.MapMember> mapMembers,
|
||||
Collection parentCollection,
|
||||
List<ADM.MapMember>? objects = null
|
||||
)
|
||||
{
|
||||
if (objects is null)
|
||||
{
|
||||
objects = new();
|
||||
}
|
||||
|
||||
foreach (ADM.MapMember mapMember in mapMembers)
|
||||
{
|
||||
switch (mapMember)
|
||||
{
|
||||
case ADM.ILayerContainer container:
|
||||
Collection containerCollection = CreateAndCacheMapMemberCollection(mapMember, true);
|
||||
parentCollection.elements.Add(containerCollection);
|
||||
|
||||
UnpackSelection(container.Layers, containerCollection, objects);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(objects.Contains(mapMember)))
|
||||
{
|
||||
Collection collection = CreateAndCacheMapMemberCollection(mapMember);
|
||||
parentCollection.elements.Add(collection);
|
||||
objects.Add(mapMember);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
private Collection CreateAndCacheMapMemberCollection(ADM.MapMember mapMember, bool isLayerContainer = false)
|
||||
{
|
||||
string mapMemberApplicationId = mapMember.GetSpeckleApplicationId();
|
||||
Collection collection =
|
||||
new()
|
||||
{
|
||||
name = mapMember.Name,
|
||||
applicationId = mapMemberApplicationId,
|
||||
["type"] = mapMember.GetType().Name
|
||||
};
|
||||
|
||||
switch (mapMember)
|
||||
{
|
||||
case ADM.IDisplayTable displayTable: // get fields from layers that implement IDisplayTable, eg FeatureLayer or StandaloneTable
|
||||
Dictionary<string, string>? fields = displayTable
|
||||
.GetFieldDescriptions()
|
||||
.ToDictionary(field => field.Name, field => field.Type.ToString());
|
||||
collection["fields"] = fields;
|
||||
if (mapMember is ADM.BasicFeatureLayer basicFeatureLayer)
|
||||
{
|
||||
collection["shapeType"] = basicFeatureLayer.ShapeType.ToString();
|
||||
}
|
||||
break;
|
||||
|
||||
case ADM.Layer layer:
|
||||
collection["mapLayerType"] = layer.MapLayerType.ToString();
|
||||
break;
|
||||
|
||||
case ADM.ILayerContainer:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isLayerContainer) // do not cache layer containers, since these won't contain any objects
|
||||
{
|
||||
CollectionCache.Add(mapMemberApplicationId, collection);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using ArcGIS.Core.Data.Raster;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
|
||||
public static class SpeckleApplicationIdExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves the Speckle application id for map members
|
||||
/// </summary>
|
||||
public static string GetSpeckleApplicationId(this ADM.MapMember mapMember) => mapMember.URI;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the Speckle application id for Features as a concatenation of the layer URI (applicationId)
|
||||
/// and the row OID (index of row in layer).
|
||||
/// </summary>
|
||||
/// <exception cref="ACD.Exceptions.GeodatabaseException">Throws when this is *not* called on MCT. Use QueuedTask.Run.</exception>
|
||||
public static string GetSpeckleApplicationId(this ACD.Row row, string layerApplicationId) =>
|
||||
$"{layerApplicationId}_{row.GetObjectID()}";
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the Speckle application id for Raster as a concatenation of the layer URI (applicationId) and 0-index
|
||||
/// </summary>
|
||||
public static string GetSpeckleApplicationId(this Raster _, string layerApplicationId) => $"{layerApplicationId}_0";
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the Speckle application id for LasDatasets as a concatenation of the layer URI (applicationId)
|
||||
/// and point OID.
|
||||
/// </summary>
|
||||
public static string GetSpeckleApplicationId(this ACD.Analyst3D.LasPoint point, string layerApplicationId) =>
|
||||
$"{layerApplicationId}_{point.PointID}";
|
||||
}
|
||||
|
Before Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 948 B |
|
Before Width: | Height: | Size: 714 B |
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,411 +0,0 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.ArcGIS3;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Objects.Data;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Operations.Receive;
|
||||
|
||||
public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
private readonly IRootToHostConverter _converter;
|
||||
private readonly IFeatureClassUtils _featureClassUtils;
|
||||
private readonly ILocalToGlobalUnpacker _localToGlobalUnpacker;
|
||||
private readonly LocalToGlobalConverterUtils _localToGlobalConverterUtils;
|
||||
|
||||
// POC: figure out the correct scope to only initialize on Receive
|
||||
private readonly IConverterSettingsStore<ArcGISConversionSettings> _settingsStore;
|
||||
private readonly GraphTraversal _traverseFunction;
|
||||
private readonly ArcGISColorManager _colorManager;
|
||||
|
||||
public ArcGISHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
IConverterSettingsStore<ArcGISConversionSettings> settingsStore,
|
||||
IFeatureClassUtils featureClassUtils,
|
||||
ILocalToGlobalUnpacker localToGlobalUnpacker,
|
||||
LocalToGlobalConverterUtils localToGlobalConverterUtils,
|
||||
GraphTraversal traverseFunction,
|
||||
ArcGISColorManager colorManager
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_settingsStore = settingsStore;
|
||||
_featureClassUtils = featureClassUtils;
|
||||
_localToGlobalUnpacker = localToGlobalUnpacker;
|
||||
_localToGlobalConverterUtils = localToGlobalConverterUtils;
|
||||
_traverseFunction = traverseFunction;
|
||||
_colorManager = colorManager;
|
||||
}
|
||||
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
return QueuedTask.Run(
|
||||
() => BuildInternal(rootObject, projectName, modelName, onOperationProgressed, cancellationToken)
|
||||
);
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BuildInternal(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// TODO get spatialRef and offsets & rotation from ProjectInfo in CommitObject
|
||||
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
|
||||
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// get materials
|
||||
List<RenderMaterialProxy>? materials = (rootObject[ProxyKeys.RENDER_MATERIAL] as List<object>)
|
||||
?.Cast<RenderMaterialProxy>()
|
||||
.ToList();
|
||||
if (materials != null)
|
||||
{
|
||||
_colorManager.ParseMaterials(materials, onOperationProgressed);
|
||||
}
|
||||
|
||||
// get colors
|
||||
List<ColorProxy>? colors = (rootObject[ProxyKeys.COLOR] as List<object>)?.Cast<ColorProxy>().ToList();
|
||||
if (colors != null)
|
||||
{
|
||||
_colorManager.ParseColors(colors, onOperationProgressed);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
IReadOnlyCollection<LocalToGlobalMap> objectsToConvert = GetObjectsToConvert(rootObject);
|
||||
Dictionary<TraversalContext, ObjectConversionTracker> conversionTracker = new();
|
||||
|
||||
// 1. convert everything
|
||||
List<ReceiveConversionResult> results = new(objectsToConvert.Count);
|
||||
List<string> bakedObjectIds = new();
|
||||
foreach (LocalToGlobalMap objectToConvert in objectsToConvert)
|
||||
{
|
||||
string[] path = GetLayerPath(objectToConvert.TraversalContext);
|
||||
Base obj = objectToConvert.AtomicObject;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
obj = _localToGlobalConverterUtils.TransformObjects(objectToConvert.AtomicObject, objectToConvert.Matrix);
|
||||
object conversionResult = _converter.Convert(obj);
|
||||
|
||||
string nestedLayerPath = $"{string.Join("\\", path)}";
|
||||
|
||||
if (obj is ArcgisObject gisObj)
|
||||
{
|
||||
nestedLayerPath += $"\\{gisObj.name}";
|
||||
}
|
||||
else
|
||||
{
|
||||
nestedLayerPath += $"\\{obj.speckle_type.Split(".")[^1]}"; // add sub-layer by speckleType, for non-GIS objects
|
||||
}
|
||||
|
||||
conversionTracker[objectToConvert.TraversalContext] = new ObjectConversionTracker(
|
||||
obj,
|
||||
(Geometry?)conversionResult,
|
||||
nestedLayerPath
|
||||
);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // DO NOT CATCH SPECIFIC STUFF, conversion errors should be recoverable
|
||||
{
|
||||
results.Add(new(Status.ERROR, obj, null, null, ex));
|
||||
}
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / objectsToConvert.Count));
|
||||
}
|
||||
|
||||
// 2.1. Group conversionTrackers (to write into datasets)
|
||||
onOperationProgressed.Report(new("Grouping features into layers", null));
|
||||
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups =
|
||||
_featureClassUtils.GroupConversionTrackers(
|
||||
conversionTracker,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
);
|
||||
|
||||
// 2.2. Write groups of objects to Datasets
|
||||
onOperationProgressed.Report(new("Writing to Database", null));
|
||||
|
||||
_featureClassUtils.CreateDatasets(
|
||||
conversionTracker,
|
||||
convertedGroups,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
);
|
||||
|
||||
// 3. add layer and tables to the Map and Table Of Content
|
||||
|
||||
// Create placeholder for GroupLayers
|
||||
Dictionary<string, GroupLayer> createdLayerGroups = new();
|
||||
|
||||
int bakeCount = 0;
|
||||
Dictionary<string, (MapMember, CIMUniqueValueRenderer?)> bakedMapMembers = new();
|
||||
onOperationProgressed.Report(new("Adding to Map", bakeCount));
|
||||
|
||||
foreach (var item in conversionTracker)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var trackerItem = conversionTracker[item.Key]; // updated tracker object
|
||||
|
||||
// BAKE OBJECTS HERE
|
||||
if (trackerItem.Exception != null)
|
||||
{
|
||||
results.Add(new(Status.ERROR, trackerItem.Base, null, null, trackerItem.Exception));
|
||||
}
|
||||
else if (trackerItem.DatasetId == null)
|
||||
{
|
||||
results.Add(
|
||||
new(
|
||||
Status.ERROR,
|
||||
trackerItem.Base,
|
||||
null,
|
||||
null,
|
||||
new ArgumentException($"Unknown error: Dataset not created for {trackerItem.Base.speckle_type}")
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (bakedMapMembers.TryGetValue(trackerItem.DatasetId, out var value))
|
||||
{
|
||||
// if the layer already created, just add more features to report, and more color categories
|
||||
// add layer and layer URI to tracker
|
||||
trackerItem.AddConvertedMapMember(value.Item1);
|
||||
trackerItem.AddLayerURI(value.Item1.URI);
|
||||
conversionTracker[item.Key] = trackerItem; // not necessary atm, but needed if we use conversionTracker further
|
||||
|
||||
// add color category
|
||||
CIMUniqueValueRenderer? uvr = _colorManager.CreateOrEditLayerRenderer(item.Key, trackerItem, value.Item2);
|
||||
// replace renderer
|
||||
bakedMapMembers[trackerItem.DatasetId] = (value.Item1, uvr);
|
||||
|
||||
// only add a report item
|
||||
AddResultsFromTracker(trackerItem, results);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no layer yet, create and add layer to Map
|
||||
MapMember mapMember = AddDatasetsToMap(trackerItem, createdLayerGroups, projectName, modelName);
|
||||
|
||||
// add layer and layer URI to tracker
|
||||
trackerItem.AddConvertedMapMember(mapMember);
|
||||
trackerItem.AddLayerURI(mapMember.URI);
|
||||
conversionTracker[item.Key] = trackerItem; // not necessary atm, but needed if we use conversionTracker further
|
||||
|
||||
// add layer URI to bakedIds
|
||||
bakedObjectIds.Add(trackerItem.MappedLayerURI == null ? "" : trackerItem.MappedLayerURI);
|
||||
|
||||
// add color category
|
||||
CIMUniqueValueRenderer? uvr = _colorManager.CreateOrEditLayerRenderer(item.Key, trackerItem, null);
|
||||
// mark dataset as already created
|
||||
bakedMapMembers[trackerItem.DatasetId] = (mapMember, uvr);
|
||||
|
||||
// add report item
|
||||
AddResultsFromTracker(trackerItem, results);
|
||||
}
|
||||
|
||||
onOperationProgressed.Report(new("Adding to Map", (double)++bakeCount / conversionTracker.Count));
|
||||
}
|
||||
|
||||
// apply renderers to baked layers
|
||||
foreach (var bakedMember in bakedMapMembers)
|
||||
{
|
||||
if (bakedMember.Value.Item1 is FeatureLayer fLayer)
|
||||
{
|
||||
// Set the feature layer's renderer.
|
||||
fLayer.SetRenderer(bakedMember.Value.Item2);
|
||||
}
|
||||
}
|
||||
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
|
||||
|
||||
// TODO: validated a correct set regarding bakedobject ids
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
|
||||
{
|
||||
// keep GISlayers in the list, because they are still needed to extract CRS of the commit (code below)
|
||||
List<TraversalContext> objectsToConvertTc = _traverseFunction.Traverse(rootObject).ToList();
|
||||
|
||||
// now filter the objects
|
||||
objectsToConvertTc = objectsToConvertTc.Where(ctx => ctx.Current is not Collection).ToList();
|
||||
|
||||
var instanceDefinitionProxies = (rootObject[ProxyKeys.INSTANCE_DEFINITION] as List<object>)
|
||||
?.Cast<InstanceDefinitionProxy>()
|
||||
.ToList();
|
||||
|
||||
return _localToGlobalUnpacker.Unpack(instanceDefinitionProxies, objectsToConvertTc);
|
||||
}
|
||||
|
||||
private void AddResultsFromTracker(ObjectConversionTracker trackerItem, List<ReceiveConversionResult> results)
|
||||
{
|
||||
if (trackerItem.MappedLayerURI == null) // should not happen
|
||||
{
|
||||
results.Add(
|
||||
new(
|
||||
Status.ERROR,
|
||||
trackerItem.Base,
|
||||
null,
|
||||
null,
|
||||
new ArgumentException($"Created Layer URI not found for {trackerItem.Base.speckle_type}")
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode layer ID and ID of its feature in 1 object represented as string
|
||||
ObjectID objectId = new(trackerItem.MappedLayerURI, trackerItem.DatasetRow);
|
||||
if (trackerItem.HostAppGeom != null) // individual hostAppGeometry
|
||||
{
|
||||
results.Add(
|
||||
new(
|
||||
Status.SUCCESS,
|
||||
trackerItem.Base,
|
||||
objectId.ObjectIdToString(),
|
||||
trackerItem.HostAppGeom.GetType().ToString()
|
||||
)
|
||||
);
|
||||
}
|
||||
else // hostApp Layers
|
||||
{
|
||||
results.Add(
|
||||
new(
|
||||
Status.SUCCESS,
|
||||
trackerItem.Base,
|
||||
objectId.ObjectIdToString(),
|
||||
trackerItem.HostAppMapMember?.GetType().ToString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MapMember AddDatasetsToMap(
|
||||
ObjectConversionTracker trackerItem,
|
||||
Dictionary<string, GroupLayer> createdLayerGroups,
|
||||
string projectName,
|
||||
string modelName
|
||||
)
|
||||
{
|
||||
// get layer details
|
||||
string? datasetId = trackerItem.DatasetId; // should not be null here
|
||||
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
|
||||
string nestedLayerName = trackerItem.NestedLayerName;
|
||||
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
{
|
||||
Map map = _settingsStore.Current.Map;
|
||||
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
|
||||
mainGroupLayer.SetExpanded(true);
|
||||
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
|
||||
}
|
||||
|
||||
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
|
||||
|
||||
// Most of the Speckle-written datasets will be containing geometry and added as Layers
|
||||
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
|
||||
// We can create a connection to the dataset in advance and determine its type, but this will be more
|
||||
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
|
||||
try
|
||||
{
|
||||
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
{
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
// if Scene
|
||||
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
|
||||
if (_settingsStore.Current.Map.IsScene)
|
||||
{
|
||||
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
|
||||
var layerElevationSurface = new CIMLayerElevationSurface { ElevationSurfaceLayerURI = groundSurfaceLayer.URI, };
|
||||
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
}
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary<string, GroupLayer> createdLayerGroups)
|
||||
{
|
||||
GroupLayer lastGroup = createdLayerGroups.FirstOrDefault().Value;
|
||||
if (lastGroup == null) // if layer not found
|
||||
{
|
||||
throw new InvalidOperationException("Speckle Layer Group not found");
|
||||
}
|
||||
|
||||
// iterate through each nested level
|
||||
string createdGroupPath = "";
|
||||
var allPathElements = nestedLayerPath.Split("\\").Where(x => !string.IsNullOrEmpty(x));
|
||||
foreach (string pathElement in allPathElements)
|
||||
{
|
||||
createdGroupPath += "\\" + pathElement;
|
||||
if (createdLayerGroups.TryGetValue(createdGroupPath, out var existingGroupLayer))
|
||||
{
|
||||
lastGroup = existingGroupLayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create new GroupLayer under last found Group, named with last pathElement
|
||||
lastGroup = LayerFactory.Instance.CreateGroupLayer(lastGroup, 0, pathElement);
|
||||
lastGroup.SetExpanded(true);
|
||||
}
|
||||
createdLayerGroups[createdGroupPath] = lastGroup;
|
||||
}
|
||||
return lastGroup;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static string[] GetLayerPath(TraversalContext context)
|
||||
{
|
||||
string[] collectionBasedPath = context.GetAscendantOfType<Collection>().Select(c => c.name).ToArray();
|
||||
string[] reverseOrderPath =
|
||||
collectionBasedPath.Length != 0 ? collectionBasedPath : context.GetPropertyPath().ToArray();
|
||||
|
||||
var originalPath = reverseOrderPath.Reverse().ToArray();
|
||||
return originalPath.Where(x => !string.IsNullOrEmpty(x)).ToArray();
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
using ArcGIS.Core.Data.Raster;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.ArcGIS3;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.ArcGis.Operations.Send;
|
||||
|
||||
/// <summary>
|
||||
/// Stateless builder object to turn an ISendFilter into a <see cref="Base"/> object
|
||||
/// </summary>
|
||||
public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
|
||||
private readonly ArcGISLayerUnpacker _layerUnpacker;
|
||||
private readonly ArcGISColorUnpacker _colorUnpacker;
|
||||
private readonly IConverterSettingsStore<ArcGISConversionSettings> _converterSettings;
|
||||
private readonly ILogger<ArcGISRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
public ArcGISRootObjectBuilder(
|
||||
ArcGISLayerUnpacker layerUnpacker,
|
||||
ArcGISColorUnpacker colorUnpacker,
|
||||
IConverterSettingsStore<ArcGISConversionSettings> converterSettings,
|
||||
IRootToSpeckleConverter rootToSpeckleConverter,
|
||||
ILogger<ArcGISRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
MapMembersUtils mapMemberUtils
|
||||
)
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_converterSettings = converterSettings;
|
||||
_rootToSpeckleConverter = rootToSpeckleConverter;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
|
||||
|
||||
private async Task<RootObjectBuilderResult> BuildInternal(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// TODO: add a warning if Geographic CRS is set
|
||||
// "Data has been sent in the units 'degrees'. It is advisable to set the project CRS to Projected type (e.g. EPSG:32631) to be able to receive geometry correctly in CAD/BIM software"
|
||||
|
||||
|
||||
// 0 - Create Root collection and attach CRS properties
|
||||
// CRS properties are useful for data based workflows coming out of gis applications
|
||||
SpatialReference sr = _converterSettings.Current.ActiveCRSoffsetRotation.SpatialReference;
|
||||
Dictionary<string, object?> spatialReference =
|
||||
new()
|
||||
{
|
||||
["name"] = sr.Name,
|
||||
["unit"] = sr.Unit.Name,
|
||||
["wkid"] = sr.Wkid,
|
||||
["wkt"] = sr.Wkt,
|
||||
};
|
||||
|
||||
Dictionary<string, object?> crs =
|
||||
new()
|
||||
{
|
||||
["trueNorthRadians"] = _converterSettings.Current.ActiveCRSoffsetRotation.TrueNorthRadians,
|
||||
["latOffset"] = _converterSettings.Current.ActiveCRSoffsetRotation.LatOffset,
|
||||
["lonOffset"] = _converterSettings.Current.ActiveCRSoffsetRotation.LonOffset,
|
||||
["spatialReference"] = spatialReference
|
||||
};
|
||||
|
||||
Collection rootCollection =
|
||||
new()
|
||||
{
|
||||
name = ADM.MapView.Active.Map.Name,
|
||||
["units"] = _converterSettings.Current.SpeckleUnits,
|
||||
["crs"] = crs
|
||||
};
|
||||
|
||||
// 1 - Unpack the selected mapmembers
|
||||
// In Arcgis, mapmembers are collections of other mapmember or objects.
|
||||
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
|
||||
// Mapmember dynamically attached properties are also added at this step.
|
||||
List<ADM.MapMember> unpackedLayers;
|
||||
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
|
||||
long allFeaturesCount;
|
||||
ADM.Map map = ADM.MapView.Active.Map;
|
||||
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
|
||||
using (var _ = _activityFactory.Start("Unpacking selection"))
|
||||
{
|
||||
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
|
||||
|
||||
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
|
||||
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
|
||||
allFeaturesCount = layersWithFeatureCount.Values.Sum();
|
||||
}
|
||||
|
||||
List<SendConversionResult> results = new(unpackedLayers.Count);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using (var convertingActivity = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
long count = 0;
|
||||
|
||||
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string layerApplicationId = layer.GetSpeckleApplicationId();
|
||||
|
||||
try
|
||||
{
|
||||
// get the corresponding collection for this layer - we'll add all converted objects to the collection
|
||||
if (_layerUnpacker.CollectionCache.TryGetValue(layerApplicationId, out Collection? layerCollection))
|
||||
{
|
||||
var status = Status.SUCCESS;
|
||||
var sdkStatus = SdkActivityStatusCode.Ok;
|
||||
|
||||
// TODO: check cache first to see if this layer was previously converted
|
||||
/*
|
||||
if (_sendConversionCache.TryGetValue(
|
||||
sendInfo.ProjectId,
|
||||
layerApplicationId,
|
||||
out ObjectReference? value
|
||||
))
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
|
||||
featureLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
|
||||
rasterLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedRasterLayerObjects);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
|
||||
lasDatasetLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedLasDatasetObjects);
|
||||
break;
|
||||
default:
|
||||
status = Status.ERROR;
|
||||
sdkStatus = SdkActivityStatusCode.Error;
|
||||
break;
|
||||
}
|
||||
|
||||
count += layerFeatureCount;
|
||||
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
|
||||
convertingActivity?.SetStatus(sdkStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SpeckleException($"No converted Collection found for layer {layerApplicationId}.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, layer.GetType().Name);
|
||||
results.Add(new(Status.ERROR, layerApplicationId, layer.GetType().Name, null, ex));
|
||||
convertingActivity?.SetStatus(SdkActivityStatusCode.Error);
|
||||
convertingActivity?.RecordException(ex);
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
// 3 - Add Color Proxies
|
||||
rootCollection[ProxyKeys.COLOR] = _colorUnpacker.ColorProxyCache.Values.ToList();
|
||||
|
||||
return new RootObjectBuilderResult(rootCollection, results);
|
||||
}
|
||||
|
||||
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
|
||||
{
|
||||
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
|
||||
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
{
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
// count Raster layer as 1 feature: not optimal but this is the approach for now
|
||||
layersFeatureCount.Add(rasterLayer, 1);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
var dataset = lasDatasetLayer.GetLasDataset();
|
||||
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
|
||||
layersFeatureCount.Add(
|
||||
lasDatasetLayer,
|
||||
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return layersFeatureCount;
|
||||
}
|
||||
|
||||
private List<Base> ConvertFeatureLayerObjects(
|
||||
ADM.FeatureLayer featureLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRendererAndFields(featureLayer);
|
||||
|
||||
// search the rows of the layer, where each row is treated like an object
|
||||
// RowCursor is IDisposable but is not being correctly picked up by IDE warnings.
|
||||
// This means we need to be carefully adding using statements based on the API documentation coming from each method/class
|
||||
using (ACD.RowCursor rowCursor = featureLayer.Search())
|
||||
{
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every feature
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
|
||||
using (ACD.Row row = rowCursor.Current)
|
||||
{
|
||||
// get application id. test for subtypes before defaulting to base type.
|
||||
Base converted = _rootToSpeckleConverter.Convert(row);
|
||||
string applicationId = row.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
|
||||
private List<Base> ConvertRasterLayerObjects(
|
||||
ADM.RasterLayer rasterLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
Raster raster = rasterLayer.GetRaster();
|
||||
|
||||
// check cancellation token before conversion
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
Base converted = _rootToSpeckleConverter.Convert(raster);
|
||||
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
private List<Base> ConvertLasDatasetLayerObjects(
|
||||
ADM.LasDatasetLayer lasDatasetLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
|
||||
try
|
||||
{
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRenderer(lasDatasetLayer);
|
||||
|
||||
using (ACD.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.SearchPoints(new ACD.Analyst3D.LasPointFilter()))
|
||||
{
|
||||
while (ptCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every point
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
|
||||
{
|
||||
Base converted = _rootToSpeckleConverter.Convert(pt);
|
||||
string applicationId = pt.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ACD.Exceptions.TinException ex)
|
||||
{
|
||||
throw new SpeckleException("3D analyst extension is not enabled for .las layer operations", ex);
|
||||
}
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Speckle.Connectors.ArcGIS3_all_users": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "C:\\Program Files\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
|
||||
"commandLineArgs": ""
|
||||
},
|
||||
"Speckle.Connectors.ArcGIS3_user": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
|
||||
"commandLineArgs": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<RootNameSpace>Speckle.Connectors.ArcGIS</RootNameSpace>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<DefineConstants>$(DefineConstants);ARCGIS3</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Config.daml" />
|
||||
<Content Include="Images\s2logo_16.png" />
|
||||
<Content Include="Images\s2logo_32.png" />
|
||||
<Content Include="DarkImages\s2logo_16.png" />
|
||||
<Content Include="DarkImages\s2logo_32.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Esri.ArcGISPro.Extensions30" IncludeAssets="compile" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\ArcGIS\Speckle.Converters.ArcGIS3\Speckle.Converters.ArcGIS3.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="Esri.ArcGISPro.Extensions30.Speckle.targets" />
|
||||
</Project>
|
||||
@@ -1,42 +0,0 @@
|
||||
using ArcGIS.Desktop.Framework;
|
||||
using ArcGIS.Desktop.Framework.Contracts;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS;
|
||||
|
||||
internal sealed class SpeckleDUI3ViewModel : DockPane
|
||||
{
|
||||
private const string DOCKPANE_ID = "SpeckleDUI3_SpeckleDUI3";
|
||||
|
||||
internal static void Create()
|
||||
{
|
||||
var pane = FrameworkApplication.DockPaneManager.Find(DOCKPANE_ID);
|
||||
pane?.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the pane is initialized.
|
||||
/// </summary>
|
||||
protected override async Task InitializeAsync()
|
||||
{
|
||||
await base.InitializeAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the pane is uninitialized.
|
||||
/// </summary>
|
||||
protected override async Task UninitializeAsync()
|
||||
{
|
||||
await base.UninitializeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Button implementation to create a new instance of the pane and activate it.
|
||||
/// </summary>
|
||||
internal sealed class SpeckleDUI3OpenButton : Button
|
||||
{
|
||||
protected override void OnClick()
|
||||
{
|
||||
SpeckleDUI3ViewModel.Create();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS;
|
||||
|
||||
public class SpeckleDUI3Wrapper : UserControl
|
||||
{
|
||||
public SpeckleDUI3Wrapper()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
Content = SpeckleModule.Current.Container.GetRequiredService<DUI3ControlWebView>();
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using ArcGIS.Desktop.Framework;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.ArcGIS.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Converters.ArcGIS3;
|
||||
using Module = ArcGIS.Desktop.Framework.Contracts.Module;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS;
|
||||
|
||||
/// <summary>
|
||||
/// This sample shows how to implement pane that contains an Edge WebView2 control using the built-in ArcGIS Pro SDK's WebBrowser control. For details on how to utilize the WebBrowser control in an add-in see here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#webbrowser For details on how to utilize the Microsoft Edge web browser control in an add-in see here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#webbrowser-control
|
||||
/// </summary>
|
||||
internal sealed class SpeckleModule : Module
|
||||
{
|
||||
private static SpeckleModule? s_this;
|
||||
private readonly IDisposable? _disposableLogger;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the singleton instance to this module here
|
||||
/// </summary>
|
||||
public static SpeckleModule Current =>
|
||||
s_this ??= (SpeckleModule)FrameworkApplication.FindModule("ConnectorArcGIS_Module");
|
||||
|
||||
public ServiceProvider Container { get; }
|
||||
|
||||
public SpeckleModule()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver.OnAssemblyResolve<SpeckleModule>;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
// init DI
|
||||
_disposableLogger = services.Initialize(HostApplications.ArcGIS, GetVersion());
|
||||
services.AddArcGIS();
|
||||
services.AddArcGISConverters();
|
||||
Container = services.BuildServiceProvider();
|
||||
Container.UseDUI();
|
||||
}
|
||||
|
||||
private HostAppVersion GetVersion()
|
||||
{
|
||||
#if ARCGIS3
|
||||
return HostAppVersion.v3;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by Framework when ArcGIS Pro is closing
|
||||
/// </summary>
|
||||
/// <returns>False to prevent Pro from closing, otherwise True</returns>
|
||||
protected override bool CanUnload()
|
||||
{
|
||||
//TODO - add your business logic
|
||||
//return false to ~cancel~ Application close
|
||||
_disposableLogger?.Dispose();
|
||||
Container.Dispose();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
using System.Xml.Linq;
|
||||
using ArcGIS.Desktop.Core.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
public class ArcGISDocumentStore : DocumentModelStore
|
||||
{
|
||||
public ArcGISDocumentStore(
|
||||
ILogger<DocumentModelStore> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(logger, jsonSerializer)
|
||||
{
|
||||
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
|
||||
ProjectSavingEvent.Subscribe(
|
||||
_ =>
|
||||
{
|
||||
topLevelExceptionHandler.CatchUnhandled(OnProjectSaving);
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
true
|
||||
);
|
||||
ProjectClosingEvent.Subscribe(
|
||||
_ =>
|
||||
{
|
||||
topLevelExceptionHandler.CatchUnhandled(OnProjectClosing);
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
// in case plugin was loaded into already opened Map, read metadata from the current Map
|
||||
if (!IsDocumentInit && MapView.Active != null)
|
||||
{
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnProjectClosing()
|
||||
{
|
||||
if (MapView.Active is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SaveState();
|
||||
}
|
||||
|
||||
private void OnProjectSaving()
|
||||
{
|
||||
if (MapView.Active is not null)
|
||||
{
|
||||
SaveState();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
|
||||
/// </summary>
|
||||
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
|
||||
{
|
||||
if (args.IncomingView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState) =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
|
||||
var existingMetadata = map.GetMetadata();
|
||||
|
||||
// Parse existing metadata
|
||||
XDocument existingXmlDocument = !string.IsNullOrEmpty(existingMetadata)
|
||||
? XDocument.Parse(existingMetadata)
|
||||
: new XDocument(new XElement("metadata"));
|
||||
|
||||
XElement xmlModelCards = new("SpeckleModelCards", modelCardState);
|
||||
|
||||
// Check if SpeckleModelCards element already exists at root and update it
|
||||
var speckleModelCardsElement = existingXmlDocument.Root?.Element("SpeckleModelCards");
|
||||
if (speckleModelCardsElement != null)
|
||||
{
|
||||
speckleModelCardsElement.ReplaceWith(xmlModelCards);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingXmlDocument.Root?.Add(xmlModelCards);
|
||||
}
|
||||
|
||||
map.SetMetadata(existingXmlDocument.ToString());
|
||||
})
|
||||
.FireAndForget();
|
||||
|
||||
protected override void LoadState() =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
var metadata = map.GetMetadata();
|
||||
var root = XDocument.Parse(metadata).Root;
|
||||
var element = root?.Element("SpeckleModelCards");
|
||||
if (element is null)
|
||||
{
|
||||
ClearAndSave();
|
||||
return;
|
||||
}
|
||||
|
||||
string modelsString = element.Value;
|
||||
LoadFromString(modelsString);
|
||||
})
|
||||
.FireAndForget();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
// bind together a layer object on the map, and auto-assigned ID if the specific feature
|
||||
public readonly struct MapMemberFeature
|
||||
{
|
||||
public int? FeatureId { get; } // unique feature id (start from 0) of a feature in the layer
|
||||
public MapMember MapMember { get; } // layer object on the Map
|
||||
|
||||
public MapMemberFeature(MapMember mapMember, int? featureId)
|
||||
{
|
||||
MapMember = mapMember;
|
||||
FeatureId = featureId;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
public class MapMembersUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns all Layers and Standalone Tables present on the Map
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <returns></returns>
|
||||
public List<MapMember> GetAllMapMembers(Map map)
|
||||
{
|
||||
// first get all map layers
|
||||
List<MapMember> mapMembers = new();
|
||||
var layerMapMembers = UnpackMapLayers(map.Layers);
|
||||
mapMembers.AddRange(layerMapMembers);
|
||||
|
||||
// add tables
|
||||
var standaloneTableMapMembers = UnpackMapLayers(map.StandaloneTables);
|
||||
mapMembers.AddRange(standaloneTableMapMembers);
|
||||
return mapMembers;
|
||||
}
|
||||
|
||||
public List<MapMember> UnpackMapLayers(IEnumerable<MapMember> mapMembersToUnpack)
|
||||
{
|
||||
List<MapMember> mapMembers = new();
|
||||
foreach (var layer in mapMembersToUnpack)
|
||||
{
|
||||
mapMembers.Add(layer);
|
||||
switch (layer)
|
||||
{
|
||||
case ILayerContainer subGroup:
|
||||
var subLayerMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subLayerMapMembers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mapMembers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the selected mapmembers into the same order as they appear in the Table of Contents (TOC) bar in the file.
|
||||
/// This is a required step before unpacking layers, because depending on the user selection order, some children layers may appear before their container layer if both the container and children layers are selected.
|
||||
/// </summary>
|
||||
public IEnumerable<MapMember> GetMapMembersInOrder(Map map, IReadOnlyList<MapMember> selectedMapMembers)
|
||||
{
|
||||
// first get all map layers
|
||||
List<MapMember> allMapMembers = GetAllMapMembers(map);
|
||||
|
||||
// recalculate selected layer priority from all map layers
|
||||
foreach (MapMember mapMember in allMapMembers)
|
||||
{
|
||||
if (selectedMapMembers.Contains(mapMember))
|
||||
{
|
||||
yield return mapMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
// this struct is needed to be able to parse single-string value into IDs of both a layer, and it's individual feature
|
||||
public struct ObjectID
|
||||
{
|
||||
private const string FEATURE_ID_SEPARATOR = "__speckleFeatureId__";
|
||||
public string MappedLayerURI { get; } // unique ID of the layer on the map
|
||||
public int? FeatureId { get; } // unique feature id (start from 0) of a feature in the layer
|
||||
|
||||
public ObjectID(string encodedId)
|
||||
{
|
||||
List<string> stringParts = encodedId.Split(FEATURE_ID_SEPARATOR).ToList();
|
||||
MappedLayerURI = stringParts[0];
|
||||
FeatureId = null;
|
||||
if (stringParts.Count > 1)
|
||||
{
|
||||
FeatureId = Convert.ToInt32(stringParts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectID(string layerId, int? featureId)
|
||||
{
|
||||
MappedLayerURI = layerId;
|
||||
FeatureId = featureId;
|
||||
}
|
||||
|
||||
public readonly string ObjectIdToString()
|
||||
{
|
||||
if (FeatureId == null)
|
||||
{
|
||||
return $"{MappedLayerURI}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{MappedLayerURI}{FEATURE_ID_SEPARATOR}{FeatureId}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<Target AfterTargets="Clean" Name="CleanAddinAutocad" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion);" />
|
||||
<Target AfterTargets="Clean" Name="CleanAddinAutocad" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad.bundle\Contents\Windows\Speckle.Connectors.Autocad$(AutoCADVersion);" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildAutoCAD" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<Target AfterTargets="Build" Name="AfterBuildAutoCAD" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<ItemGroup>
|
||||
<AutoCADDLLs Include="$(TargetDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Message Text="AutoCAD Version $(AutoCADVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion)\%(RecursiveDir)" SourceFiles="@(AutoCADDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad.bundle\Contents\Windows\Speckle.Connectors.Autocad$(AutoCADVersion)\%(RecursiveDir)" SourceFiles="@(AutoCADDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad.bundle\" SourceFiles="$(TargetDir)\Plugin\BundleAutoCAD\PackageContents.xml" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Clean" Name="CleanAddinCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion);" />
|
||||
<Target AfterTargets="Clean" Name="CleanAddinCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d.bundle\Contents\Windows\Speckle.Connectors.Civil3d$(Civil3DVersion);" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<Target AfterTargets="Build" Name="AfterBuildCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<ItemGroup>
|
||||
<Civil3DDLLs Include="$(TargetDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Message Text="Civil3D Version $(Civil3DVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion)\%(RecursiveDir)" SourceFiles="@(Civil3DDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d.bundle\Contents\Windows\Speckle.Connectors.Civil3d$(Civil3DVersion)\%(RecursiveDir)" SourceFiles="@(Civil3DDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d.bundle\" SourceFiles="$(TargetDir)\Plugin\BundleCivil3D\PackageContents.xml" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<PropertyGroup Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(AutoCADVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<PropertyGroup Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
<StartArguments>/product C3D</StartArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target AfterTargets="Clean" Name="CleanAddinPlant3D" Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\Contents\Windows\Speckle.Connectors.Plant3d$(Plant3DVersion);" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildPlant3D" Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<ItemGroup>
|
||||
<Plant3DDLLs Include="$(TargetDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Message Text="Plant3D Version $(Plant3DVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\Contents\Windows\Speckle.Connectors.Plant3d$(Plant3DVersion)\%(RecursiveDir)" SourceFiles="@(Plant3DDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\" SourceFiles="$(TargetDir)\Plugin\BundlePlant3D\PackageContents.xml" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Plant3DVersion)\acad.exe</StartProgram>
|
||||
<StartArguments>/product PLNT3D</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
<DefineConstants>$(DefineConstants);AUTOCAD;AUTOCAD2022;AUTOCAD2022_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Autocad\Speckle.Converters.Autocad2022\Speckle.Converters.Autocad2022.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.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -73,8 +73,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -169,6 +169,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -259,9 +282,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +314,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -336,35 +358,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
<DefineConstants>$(DefineConstants);AUTOCAD;AUTOCAD2023;AUTOCAD2022_OR_GREATER;AUTOCAD2023_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Autocad\Speckle.Converters.Autocad2023\Speckle.Converters.Autocad2023.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.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -73,8 +73,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -169,6 +169,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -259,9 +282,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +314,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -336,35 +358,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
<DefineConstants>$(DefineConstants);AUTOCAD;AUTOCAD2024;AUTOCAD2022_OR_GREATER;AUTOCAD2023_OR_GREATER;AUTOCAD2024_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Autocad\Speckle.Converters.Autocad2024\Speckle.Converters.Autocad2024.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.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -73,8 +73,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -169,6 +169,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -259,9 +282,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -293,7 +315,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -337,35 +359,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,20 +8,23 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- .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 -->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Autocad\Speckle.Converters.Autocad2025\Speckle.Converters.Autocad2025.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.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -75,11 +75,6 @@
|
||||
"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",
|
||||
@@ -160,6 +155,25 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -215,9 +229,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -249,7 +262,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -293,34 +306,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -8,20 +8,23 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- .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 -->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Autocad\Speckle.Converters.Autocad2026\Speckle.Converters.Autocad2026.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.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -75,11 +75,6 @@
|
||||
"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",
|
||||
@@ -160,6 +155,25 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -215,9 +229,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -249,7 +262,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -293,34 +306,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -1,119 +1,59 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public abstract class AutocadReceiveBaseBinding : IReceiveBinding
|
||||
public abstract class AutocadReceiveBaseBinding(
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IThreadContext threadContext,
|
||||
IReceiveOperationManagerFactory receiveOperationManagerFactory
|
||||
) : IReceiveBinding
|
||||
{
|
||||
public string Name => "receiveBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
public IBrowserBridge Parent { get; } = parent;
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadReceiveBinding> _logger;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private ReceiveBindingUICommands Commands { get; } = new(parent);
|
||||
|
||||
private ReceiveBindingUICommands Commands { get; }
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc);
|
||||
|
||||
protected AutocadReceiveBaseBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_cancellationManager = cancellationManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
public void CancelReceive(string modelCardId) => cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
|
||||
await threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
|
||||
|
||||
private async Task ReceiveInternal(string modelCardId)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
InitializeSettings(scope.ServiceProvider);
|
||||
|
||||
try
|
||||
{
|
||||
// Get receiver card
|
||||
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
|
||||
using var manager = receiveOperationManagerFactory.Create();
|
||||
await manager.Process(
|
||||
Commands,
|
||||
modelCardId,
|
||||
InitializeSettings,
|
||||
async (_, processor) =>
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No download model card was found.");
|
||||
try
|
||||
{
|
||||
// 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;
|
||||
return await processor();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// reenable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
|
||||
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
|
||||
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
|
||||
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
|
||||
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
|
||||
Application.DocumentManager.CurrentDocument.Editor.Regen();
|
||||
}
|
||||
}
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(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;
|
||||
|
||||
// Receive host objects
|
||||
var operationResults = await scope
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
operationResults.BakedObjectIds,
|
||||
operationResults.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);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// reenable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
|
||||
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
|
||||
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
|
||||
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
|
||||
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
|
||||
Application.DocumentManager.CurrentDocument.Editor.Regen();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
@@ -16,31 +14,18 @@ public sealed class AutocadReceiveBinding : AutocadReceiveBaseBinding
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public AutocadReceiveBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
IThreadContext threadContext,
|
||||
IReceiveOperationManagerFactory receiveOperationManagerFactory
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext
|
||||
)
|
||||
: base(parent, cancellationManager, threadContext, receiveOperationManagerFactory)
|
||||
{
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
}
|
||||
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
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.Common.Threading;
|
||||
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;
|
||||
@@ -33,14 +27,11 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
|
||||
|
||||
/// <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:
|
||||
@@ -50,32 +41,29 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
/// </summary>
|
||||
private ConcurrentBag<string> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
private readonly Dictionary<string, Matrix3d> _docUcsTracker = new();
|
||||
|
||||
protected AutocadSendBaseBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager idleManager
|
||||
IAppIdleManager idleManager,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_serviceProvider = serviceProvider;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_idleManager = idleManager;
|
||||
_sendOperationManagerFactory = sendOperationManagerFactory;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
|
||||
@@ -87,6 +75,10 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
// catches the case when autocad just opens up with a blank new doc
|
||||
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
|
||||
}
|
||||
|
||||
Application.SystemVariableChanged += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnSystemVariableChanged(e));
|
||||
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
@@ -94,8 +86,6 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
@@ -104,11 +94,58 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
}
|
||||
|
||||
_docSubsTracker.Add(doc.Name);
|
||||
_docUcsTracker[doc.Name] = doc.Editor.CurrentUserCoordinateSystem;
|
||||
|
||||
doc.Database.ObjectAppended += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectErased += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles system variable changes to detect UCS modifications.
|
||||
/// When UCS changes, clears the conversion cache and expires all sender model cards.
|
||||
/// </summary>
|
||||
private void OnSystemVariableChanged(Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventArgs e)
|
||||
{
|
||||
// check if this is a UCS-defining system variable
|
||||
string varName = e.Name.ToUpperInvariant();
|
||||
bool isUcsChange = varName == "UCSNAME" || varName == "UCSORG" || varName == "UCSXDIR" || varName == "UCSYDIR";
|
||||
|
||||
if (!isUcsChange)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get the currently active document
|
||||
Document doc = Application.DocumentManager.MdiActiveDocument;
|
||||
if (doc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var currentUcs = doc.Editor.CurrentUserCoordinateSystem;
|
||||
|
||||
// first time tracking this document's UCS
|
||||
if (!_docUcsTracker.TryGetValue(doc.Name, out Matrix3d storedUcs))
|
||||
{
|
||||
_docUcsTracker[doc.Name] = currentUcs;
|
||||
return;
|
||||
}
|
||||
|
||||
// ucs hasn't actually changed (multiple variables fire for single UCS change)
|
||||
if (currentUcs.IsEqualTo(storedUcs))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ucs has changed - all cached conversions invalid
|
||||
_sendConversionCache.ClearCache();
|
||||
_docUcsTracker[doc.Name] = currentUcs;
|
||||
|
||||
// expire all sender model cards
|
||||
_idleManager.SubscribeToIdle(nameof(ExpireAllSenders), async () => await ExpireAllSenders());
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
|
||||
@@ -139,6 +176,19 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expires all sender model cards when a global change occurs (like UCS change).
|
||||
/// </summary>
|
||||
private async Task ExpireAllSenders()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
var expiredSenderIds = senders.Select(s => s.ModelCardId.NotNull()).ToList();
|
||||
if (expiredSenderIds.Count > 0)
|
||||
{
|
||||
await Commands.SetModelsExpired(expiredSenderIds);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
@@ -152,55 +202,19 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
{
|
||||
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);
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
using var manager = _sendOperationManagerFactory.Create();
|
||||
// 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()
|
||||
await manager.Process(
|
||||
Commands,
|
||||
modelCardId,
|
||||
(sp, card) => InitializeSettings(sp),
|
||||
card => Application.DocumentManager.CurrentDocument.GetObjects(card.SendFilter.NotNull().RefreshObjectIds()),
|
||||
Application.DocumentManager.CurrentDocument.Name,
|
||||
null
|
||||
);
|
||||
|
||||
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.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.VersionId, 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);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
@@ -9,7 +8,6 @@ using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
@@ -22,29 +20,23 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager appIdleManager
|
||||
IAppIdleManager appIdleManager,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext,
|
||||
topLevelExceptionHandler,
|
||||
appIdleManager
|
||||
appIdleManager,
|
||||
sendOperationManagerFactory
|
||||
)
|
||||
{
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
|
||||
@@ -18,6 +18,10 @@ public static class AutocadConnectorModule
|
||||
// Send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, AutocadRootObjectBuilder>();
|
||||
serviceCollection.AddScoped<
|
||||
IRootContinuousTraversalBuilder<AutocadRootObject>,
|
||||
AutocadContinuousTraversalBuilder
|
||||
>();
|
||||
|
||||
// Receive
|
||||
serviceCollection.LoadReceive();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Autodesk.AutoCAD.Colors;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
|
||||
@@ -110,22 +110,20 @@ public class AutocadColorUnpacker
|
||||
string name = color.ColorNameForDisplay;
|
||||
string id = color.GetSpeckleApplicationId();
|
||||
|
||||
ColorProxy colorProxy =
|
||||
new()
|
||||
{
|
||||
value = argb,
|
||||
applicationId = id,
|
||||
name = name,
|
||||
objects = new()
|
||||
};
|
||||
ColorProxy colorProxy = new()
|
||||
{
|
||||
value = argb,
|
||||
applicationId = id,
|
||||
name = name,
|
||||
objects = new(),
|
||||
};
|
||||
|
||||
// add the color source as well for receiving in other apps
|
||||
// POC: in order to support full fidelity color support across autocad and rhino, we need to keep track of the color source property. Not sure if this is the best place to keep track of the source, vs on a ColorSourceProxy or as a property on the atomic object.
|
||||
colorProxy["source"] = color.IsByBlock
|
||||
? "block"
|
||||
: color.IsByLayer
|
||||
? "layer"
|
||||
: "object";
|
||||
colorProxy["source"] =
|
||||
color.IsByBlock ? "block"
|
||||
: color.IsByLayer ? "layer"
|
||||
: "object";
|
||||
|
||||
// set additional properties if by aci or by block
|
||||
// ByBlock colors for some reason do not have their color value set to the correct color (white): instead it's a near-black
|
||||
|
||||
@@ -53,7 +53,7 @@ public class AutocadGroupUnpacker
|
||||
{
|
||||
applicationId = groupAppId,
|
||||
name = group.Name,
|
||||
objects = [applicationId]
|
||||
objects = [applicationId],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ 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;
|
||||
@@ -16,6 +15,7 @@ using Speckle.Sdk.Dependencies;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
@@ -139,7 +139,7 @@ public class AutocadInstanceBaker : IInstanceBaker<IReadOnlyCollection<Entity>>
|
||||
? matId
|
||||
: ObjectId.Null;
|
||||
|
||||
BlockReference blockRef = new(insertionPoint, definitionId) { BlockTransform = matrix3d, Layer = layerName, };
|
||||
BlockReference blockRef = new(insertionPoint, definitionId) { BlockTransform = matrix3d, Layer = layerName };
|
||||
|
||||
if (objColor is not null)
|
||||
{
|
||||
@@ -252,7 +252,7 @@ public class AutocadInstanceBaker : IInstanceBaker<IReadOnlyCollection<Entity>>
|
||||
matrix.M41,
|
||||
matrix.M42,
|
||||
matrix.M43,
|
||||
matrix.M44
|
||||
matrix.M44,
|
||||
};
|
||||
|
||||
var m3d = new Matrix3d(scaledTransform);
|
||||
@@ -291,7 +291,7 @@ public class AutocadInstanceBaker : IInstanceBaker<IReadOnlyCollection<Entity>>
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
matrix[3, 3]
|
||||
matrix[3, 3],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@ using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Converters.Autocad.Helpers;
|
||||
using Speckle.Converters.AutocadShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
@@ -17,16 +18,19 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
{
|
||||
private readonly IHostToSpeckleUnitConverter<UnitsValue> _unitsConverter;
|
||||
private readonly IInstanceObjectsManager<AutocadRootObject, List<Entity>> _instanceObjectsManager;
|
||||
private readonly IPropertiesExtractor _propertiesExtractor;
|
||||
private readonly ILogger<AutocadInstanceUnpacker> _logger;
|
||||
|
||||
public AutocadInstanceUnpacker(
|
||||
IHostToSpeckleUnitConverter<UnitsValue> unitsConverter,
|
||||
IInstanceObjectsManager<AutocadRootObject, List<Entity>> instanceObjectsManager,
|
||||
IPropertiesExtractor propertiesExtractor,
|
||||
ILogger<AutocadInstanceUnpacker> logger
|
||||
)
|
||||
{
|
||||
_unitsConverter = unitsConverter;
|
||||
_instanceObjectsManager = instanceObjectsManager;
|
||||
_propertiesExtractor = propertiesExtractor;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -42,6 +46,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
{
|
||||
UnpackInstance(blockReference, 0, transaction);
|
||||
}
|
||||
|
||||
_instanceObjectsManager.AddAtomicObject(obj.ApplicationId, obj);
|
||||
}
|
||||
return _instanceObjectsManager.GetUnpackResult();
|
||||
@@ -62,15 +67,22 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
? instance.AnonymousBlockTableRecord
|
||||
: instance.BlockTableRecord;
|
||||
|
||||
InstanceProxy instanceProxy =
|
||||
new()
|
||||
{
|
||||
applicationId = instanceId,
|
||||
definitionId = definitionId.ToString(),
|
||||
maxDepth = depth,
|
||||
transform = GetMatrix(instance.BlockTransform.ToArray()),
|
||||
units = _unitsConverter.ConvertOrThrow(Application.DocumentManager.CurrentDocument.Database.Insunits)
|
||||
};
|
||||
// transforms on instances are always stored in WCS
|
||||
InstanceProxy instanceProxy = new()
|
||||
{
|
||||
applicationId = instanceId,
|
||||
definitionId = definitionId.ToString(),
|
||||
maxDepth = depth,
|
||||
transform = TransformHelper.ConvertToInstanceMatrix4x4(instance.BlockTransform),
|
||||
units = _unitsConverter.ConvertOrThrow(Application.DocumentManager.CurrentDocument.Database.Insunits),
|
||||
};
|
||||
|
||||
var properties = _propertiesExtractor.GetProperties(instance);
|
||||
if (properties?.Count > 0)
|
||||
{
|
||||
instanceProxy["properties"] = properties;
|
||||
}
|
||||
|
||||
_instanceObjectsManager.AddInstanceProxy(instanceId, instanceProxy);
|
||||
|
||||
// For each block instance that has the same definition, we need to keep track of the "maximum depth" at which is found.
|
||||
@@ -140,7 +152,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
applicationId = definitionId.ToString(),
|
||||
objects = new(),
|
||||
maxDepth = depth,
|
||||
name = !instance.AnonymousBlockTableRecord.IsNull ? "Dynamic instance " + definitionId : definition.Name
|
||||
name = !instance.AnonymousBlockTableRecord.IsNull ? "Dynamic instance " + definitionId : definition.Name,
|
||||
};
|
||||
|
||||
// Go through each definition object
|
||||
@@ -162,6 +174,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
UnpackInstance(blockReference, depth + 1, transaction);
|
||||
}
|
||||
|
||||
_instanceObjectsManager.AddAtomicDefinitionObjectId(appId);
|
||||
_instanceObjectsManager.AddAtomicObject(appId, new(obj, appId));
|
||||
}
|
||||
|
||||
@@ -172,7 +185,4 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
_logger.LogError(ex, "Failed unpacking Autocad instance");
|
||||
}
|
||||
}
|
||||
|
||||
private Matrix4x4 GetMatrix(double[] t) =>
|
||||
new(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12], t[13], t[14], t[15]);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.GraphicsInterface;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
using Material = Autodesk.AutoCAD.DatabaseServices.Material;
|
||||
using RenderMaterial = Speckle.Objects.Other.RenderMaterial;
|
||||
|
||||
@@ -170,13 +170,12 @@ public class AutocadMaterialBaker : IAutocadMaterialBaker
|
||||
MaterialColor diffuseColor = new(Method.Override, 1, entityDiffuseColor);
|
||||
MaterialDiffuseComponent diffuse = new(diffuseColor, map);
|
||||
|
||||
Material mat =
|
||||
new()
|
||||
{
|
||||
Name = matName,
|
||||
Opacity = opacity,
|
||||
Diffuse = diffuse
|
||||
};
|
||||
Material mat = new()
|
||||
{
|
||||
Name = matName,
|
||||
Opacity = opacity,
|
||||
Diffuse = diffuse,
|
||||
};
|
||||
|
||||
if (renderMaterial["reflectivity"] is double reflectivity)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,12 @@ public class AutocadMaterialUnpacker
|
||||
|
||||
if (transaction.GetObject(entity.MaterialId, OpenMode.ForRead) is Material material)
|
||||
{
|
||||
// skip default material
|
||||
if (material.Name == "Global")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string materialId = material.GetSpeckleApplicationId();
|
||||
if (materialProxies.TryGetValue(materialId, out RenderMaterialProxy? value))
|
||||
{
|
||||
@@ -77,6 +83,12 @@ public class AutocadMaterialUnpacker
|
||||
{
|
||||
if (transaction.GetObject(layer.MaterialId, OpenMode.ForRead) is Material material)
|
||||
{
|
||||
// skip default material
|
||||
if (material.Name == "Global")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string materialId = material.GetSpeckleApplicationId();
|
||||
string layerId = layer.GetSpeckleApplicationId(); // Do not use handle directly, see note in the 'GetSpeckleApplicationId' method
|
||||
if (materialProxies.TryGetValue(materialId, out RenderMaterialProxy? value))
|
||||
@@ -110,14 +122,13 @@ public class AutocadMaterialUnpacker
|
||||
diffuseColor.Blue
|
||||
);
|
||||
|
||||
RenderMaterial renderMaterial =
|
||||
new()
|
||||
{
|
||||
name = material.Name,
|
||||
opacity = material.Opacity.Percentage,
|
||||
diffuse = diffuse.ToArgb(),
|
||||
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;
|
||||
@@ -127,7 +138,7 @@ public class AutocadMaterialUnpacker
|
||||
{
|
||||
value = renderMaterial,
|
||||
objects = new(),
|
||||
applicationId = id
|
||||
applicationId = id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Dependencies;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Receive;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Base class for AutoCAD host object builders. Expects to be a scoped dependency per receive operation.</para>
|
||||
/// </summary>
|
||||
public abstract class AutocadHostObjectBaseBuilder : IHostObjectBuilder
|
||||
{
|
||||
private readonly IRootToHostConverter _converter;
|
||||
private readonly AutocadLayerBaker _layerBaker;
|
||||
private readonly AutocadGroupBaker _groupBaker;
|
||||
private readonly AutocadInstanceBaker _instanceBaker;
|
||||
private readonly IAutocadMaterialBaker _materialBaker;
|
||||
private readonly IAutocadColorBaker _colorBaker;
|
||||
private readonly AutocadContext _autocadContext;
|
||||
private readonly RootObjectUnpacker _rootObjectUnpacker;
|
||||
private readonly IReceiveConversionHandler _conversionHandler;
|
||||
|
||||
protected AutocadHostObjectBaseBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker,
|
||||
IReceiveConversionHandler conversionHandler
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_layerBaker = layerBaker;
|
||||
_groupBaker = groupBaker;
|
||||
_instanceBaker = instanceBaker;
|
||||
_materialBaker = materialBaker;
|
||||
_colorBaker = colorBaker;
|
||||
_autocadContext = autocadContext;
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
_conversionHandler = conversionHandler;
|
||||
}
|
||||
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// Layer filter for received commit with project and model name
|
||||
_layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 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)
|
||||
{
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// 3 - Parse and bake proxies (materials and colors), as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
_materialBaker.ParseAndBakeRenderMaterials(
|
||||
unpackedRoot.RenderMaterialProxies,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
_colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
|
||||
// 3.5 - Parse and bake additional proxies that are needed for conversion
|
||||
ParseAndBakeAdditionalProxies(rootObject, baseLayerPrefix);
|
||||
|
||||
// 4 - Convert atomic objects
|
||||
HashSet<ReceiveConversionResult> results = new();
|
||||
HashSet<string> bakedObjectIds = new();
|
||||
Dictionary<string, IReadOnlyCollection<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
var ex = _conversionHandler.TryConvert(() =>
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id.NotNull();
|
||||
IReadOnlyCollection<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.UnionWith(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
|
||||
bakedObjectIds.UnionWith(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
});
|
||||
if (ex != null)
|
||||
{
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
// 5 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
|
||||
bakedObjectIds.RemoveWhere(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.UnionWith(createdInstanceIds);
|
||||
results.RemoveWhere(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.UnionWith(instanceConversionResults);
|
||||
|
||||
// 6 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
IReadOnlyCollection<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.UnionWith(groupResults);
|
||||
}
|
||||
|
||||
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
|
||||
}
|
||||
|
||||
protected void PreReceiveDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
_layerBaker.DeleteAllLayersByPrefix(baseLayerPrefix);
|
||||
_instanceBaker.PurgeInstances(baseLayerPrefix);
|
||||
_materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
PreReceiveAdditionalDeepClean(baseLayerPrefix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method for adding app-specific additional deep clean of the document prior to receiving.
|
||||
/// </summary>
|
||||
protected virtual void PreReceiveAdditionalDeepClean(string baseLayerPrefix) { }
|
||||
|
||||
/// <summary>
|
||||
/// Method for parsing and baking additional app-specific proxies on the root prior to converting and baking objects
|
||||
/// </summary>
|
||||
protected virtual void ParseAndBakeAdditionalProxies(Base rootObject, string baseLayerPrefix) { }
|
||||
|
||||
private IReadOnlyCollection<Entity> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
{
|
||||
string layerName = _layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
var convertedEntities = new HashSet<Entity>();
|
||||
|
||||
using var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1: convert
|
||||
var converted = _converter.Convert(obj);
|
||||
|
||||
// 2: handle result
|
||||
switch (converted)
|
||||
{
|
||||
case Entity entity:
|
||||
var bakedEntity = BakeObject(entity, obj, layerName, tr);
|
||||
convertedEntities.Add(bakedEntity);
|
||||
break;
|
||||
|
||||
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
|
||||
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix, tr);
|
||||
convertedEntities.UnionWith(bakedFallbackEntities);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: capture defualt case with report object here? Same as in Rhino
|
||||
break;
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
return convertedEntities.Freeze();
|
||||
}
|
||||
|
||||
private Entity BakeObject(
|
||||
Entity entity,
|
||||
Base originalObject,
|
||||
string layerName,
|
||||
Transaction tr,
|
||||
Base? parentObject = null
|
||||
)
|
||||
{
|
||||
var objId = originalObject.applicationId ?? originalObject.id.NotNull();
|
||||
if (_colorBaker.ObjectColorsIdMap.TryGetValue(objId, out AutocadColor? color))
|
||||
{
|
||||
entity.Color = color;
|
||||
}
|
||||
|
||||
if (_materialBaker.TryGetMaterialId(originalObject, parentObject, out ObjectId matId))
|
||||
{
|
||||
entity.MaterialId = matId;
|
||||
}
|
||||
|
||||
entity.AppendToDb(layerName);
|
||||
|
||||
// Hook for derived classes to perform additional operations after entity is added to database
|
||||
PostBakeEntity(entity, originalObject, tr);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method for additional app-specific operations on entities after the entity has been added to the document database.
|
||||
/// Called after the entity is added to the database in an open transaction
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="originalObject"></param>
|
||||
/// <param name="tr"></param>
|
||||
protected virtual void PostBakeEntity(Entity entity, Base originalObject, Transaction tr)
|
||||
{
|
||||
// Default implementation does nothing - override in derived classes
|
||||
}
|
||||
|
||||
private List<Entity> BakeObjectsAsGroup(
|
||||
List<(Entity, Base)> fallbackConversionResult,
|
||||
Base parentObject,
|
||||
string layerName,
|
||||
string baseLayerName,
|
||||
Transaction tr
|
||||
)
|
||||
{
|
||||
var ids = new ObjectIdCollection();
|
||||
var entities = new List<Entity>();
|
||||
foreach (var (conversionResult, originalObject) in fallbackConversionResult)
|
||||
{
|
||||
BakeObject(conversionResult, originalObject, layerName, tr, parentObject);
|
||||
ids.Add(conversionResult.ObjectId);
|
||||
entities.Add(conversionResult);
|
||||
}
|
||||
|
||||
if (entities.Count <= 1) // return if empty list or only one, because we don't want to create empty or single item groups.
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
var groupDictionary = (DBDictionary)
|
||||
tr.GetObject(Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId, OpenMode.ForWrite);
|
||||
|
||||
var groupName = _autocadContext.RemoveInvalidChars(
|
||||
$@"{parentObject.speckle_type.Split('.').Last()} - {parentObject.applicationId ?? parentObject.id} ({baseLayerName})"
|
||||
);
|
||||
|
||||
var newGroup = new Group(groupName, true);
|
||||
newGroup.Append(ids);
|
||||
groupDictionary.UpgradeOpen();
|
||||
groupDictionary.SetAt(groupName, newGroup);
|
||||
tr.AddNewlyCreatedDBObject(newGroup, true);
|
||||
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
@@ -1,238 +1,35 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Dependencies;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Receive;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Expects to be a scoped dependency per receive operation.</para>
|
||||
/// <para>AutoCAD-specific host object builder. Expects to be a scoped dependency per receive operation.</para>
|
||||
/// </summary>
|
||||
public class AutocadHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker
|
||||
) : IHostObjectBuilder
|
||||
public sealed class AutocadHostObjectBuilder : AutocadHostObjectBaseBuilder
|
||||
{
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
public AutocadHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker,
|
||||
IReceiveConversionHandler conversionHandler
|
||||
)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
materialBaker.ParseAndBakeRenderMaterials(
|
||||
unpackedRoot.RenderMaterialProxies,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
|
||||
// 4 - Convert atomic objects
|
||||
HashSet<ReceiveConversionResult> results = new();
|
||||
HashSet<string> bakedObjectIds = new();
|
||||
Dictionary<string, IReadOnlyCollection<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id.NotNull();
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
IReadOnlyCollection<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.UnionWith(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
|
||||
bakedObjectIds.UnionWith(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
// 5 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
|
||||
bakedObjectIds.RemoveWhere(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.UnionWith(createdInstanceIds);
|
||||
results.RemoveWhere(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.UnionWith(instanceConversionResults);
|
||||
|
||||
// 6 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
IReadOnlyCollection<ReceiveConversionResult> groupResults = groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.UnionWith(groupResults);
|
||||
}
|
||||
|
||||
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
layerBaker.DeleteAllLayersByPrefix(baseLayerPrefix);
|
||||
instanceBaker.PurgeInstances(baseLayerPrefix);
|
||||
materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<Entity> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
{
|
||||
string layerName = layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
var convertedEntities = new HashSet<Entity>();
|
||||
|
||||
using var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1: convert
|
||||
var converted = converter.Convert(obj);
|
||||
|
||||
// 2: handle result
|
||||
switch (converted)
|
||||
{
|
||||
case Entity entity:
|
||||
var bakedEntity = BakeObject(entity, obj, layerName);
|
||||
convertedEntities.Add(bakedEntity);
|
||||
break;
|
||||
|
||||
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
|
||||
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix);
|
||||
convertedEntities.UnionWith(bakedFallbackEntities);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: capture defualt case with report object here? Same as in Rhino
|
||||
break;
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
return convertedEntities.Freeze();
|
||||
}
|
||||
|
||||
private Entity BakeObject(Entity entity, Base originalObject, string layerName, Base? parentObject = null)
|
||||
{
|
||||
var objId = originalObject.applicationId ?? originalObject.id.NotNull();
|
||||
if (colorBaker.ObjectColorsIdMap.TryGetValue(objId, out AutocadColor? color))
|
||||
{
|
||||
entity.Color = color;
|
||||
}
|
||||
|
||||
if (materialBaker.TryGetMaterialId(originalObject, parentObject, out ObjectId matId))
|
||||
{
|
||||
entity.MaterialId = matId;
|
||||
}
|
||||
|
||||
entity.AppendToDb(layerName);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private List<Entity> BakeObjectsAsGroup(
|
||||
List<(Entity, Base)> fallbackConversionResult,
|
||||
Base parentObject,
|
||||
string layerName,
|
||||
string baseLayerName
|
||||
)
|
||||
{
|
||||
var ids = new ObjectIdCollection();
|
||||
var entities = new List<Entity>();
|
||||
foreach (var (conversionResult, originalObject) in fallbackConversionResult)
|
||||
{
|
||||
BakeObject(conversionResult, originalObject, layerName, parentObject);
|
||||
ids.Add(conversionResult.ObjectId);
|
||||
entities.Add(conversionResult);
|
||||
}
|
||||
|
||||
if (entities.Count <= 1) // return if empty list or only one, because we don't want to create empty or single item groups.
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
|
||||
var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.TopTransaction;
|
||||
var groupDictionary = (DBDictionary)
|
||||
tr.GetObject(Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId, OpenMode.ForWrite);
|
||||
|
||||
var groupName = autocadContext.RemoveInvalidChars(
|
||||
$@"{parentObject.speckle_type.Split('.').Last()} - {parentObject.applicationId ?? parentObject.id} ({baseLayerName})"
|
||||
);
|
||||
|
||||
var newGroup = new Group(groupName, true);
|
||||
newGroup.Append(ids);
|
||||
groupDictionary.UpgradeOpen();
|
||||
groupDictionary.SetAt(groupName, newGroup);
|
||||
tr.AddNewlyCreatedDBObject(newGroup, true);
|
||||
|
||||
return entities;
|
||||
}
|
||||
: base(
|
||||
converter,
|
||||
layerBaker,
|
||||
groupBaker,
|
||||
instanceBaker,
|
||||
materialBaker,
|
||||
colorBaker,
|
||||
autocadContext,
|
||||
rootObjectUnpacker,
|
||||
conversionHandler
|
||||
) { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
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;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
using Speckle.Sdk.Pipelines.Send;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for AutoCAD continuous traversal builders that stream objects through a
|
||||
/// <see cref="SendPipeline"/> for packfile-based uploads. Same conversion logic as
|
||||
/// <see cref="AutocadRootObjectBaseBuilder"/>, but processes elements through the pipeline.
|
||||
/// </summary>
|
||||
public abstract class AutocadContinuousTraversalBaseBuilder : IRootContinuousTraversalBuilder<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 AutocadContinuousTraversalBaseBuilder(
|
||||
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;
|
||||
}
|
||||
|
||||
[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!!!
|
||||
"""
|
||||
)]
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
string projectId,
|
||||
SendPipeline sendPipeline,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// 0 - Init the root
|
||||
Collection root = new()
|
||||
{
|
||||
name = Application
|
||||
.DocumentManager.CurrentDocument.Name.Split(_documentPathSeparator, StringSplitOptions.None)
|
||||
.Reverse()
|
||||
.First(),
|
||||
};
|
||||
|
||||
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 and process through pipeline
|
||||
List<LayerTableRecord> usedAcadLayers = new();
|
||||
List<SendConversionResult> results = new();
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
(Collection objectCollection, LayerTableRecord? autocadLayer) = CreateObjectCollection(entity, tr);
|
||||
|
||||
if (autocadLayer is not null)
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(objectCollection);
|
||||
}
|
||||
|
||||
var result = await ConvertAutocadEntity(
|
||||
entity,
|
||||
applicationId,
|
||||
objectCollection,
|
||||
instanceProxies,
|
||||
projectId,
|
||||
sendPipeline
|
||||
);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed.Report(
|
||||
new($"Converting objects... ({count:N0} / {atomicObjects.Count:N0})", (double)++count / atomicObjects.Count)
|
||||
);
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Process root collection and wait for all uploads
|
||||
await sendPipeline.Process(root);
|
||||
await sendPipeline.WaitForUpload();
|
||||
|
||||
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 async Task<SendConversionResult> ConvertAutocadEntity(
|
||||
Entity entity,
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId,
|
||||
SendPipeline sendPipeline
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// NOTE: this is the main part that differentiate from the main root object builder
|
||||
var reference = await sendPipeline.Process(converted).ConfigureAwait(false);
|
||||
collectionHost.elements.Add(reference);
|
||||
return new(Status.SUCCESS, applicationId, sourceType, reference);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, sourceType);
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public sealed class AutocadContinuousTraversalBuilder : AutocadContinuousTraversalBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
|
||||
public AutocadContinuousTraversalBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
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;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
@@ -7,18 +8,22 @@ 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.Autocad.Helpers;
|
||||
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;
|
||||
using Speckle.Sdk.Pipelines.Progress;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly IConverterSettingsStore<AutocadConversionSettings> _converterSettings;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly AutocadInstanceUnpacker _instanceUnpacker;
|
||||
@@ -30,6 +35,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
|
||||
protected AutocadRootObjectBaseBuilder(
|
||||
IRootToSpeckleConverter converter,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
@@ -40,6 +46,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_converterSettings = converterSettings;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_instanceUnpacker = instanceObjectManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
@@ -60,63 +67,90 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
)]
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
string projectId,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// 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()
|
||||
};
|
||||
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);
|
||||
var (atomicObjects, atomicDefinitionObjectIds, instanceProxies, instanceDefinitionProxies) =
|
||||
_instanceUnpacker.UnpackSelection(objects);
|
||||
root[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies;
|
||||
|
||||
// 2 - Unpack the groups
|
||||
root[ProxyKeys.GROUP] = _groupUnpacker.UnpackGroups(atomicObjects);
|
||||
|
||||
// 3 - Add the Reference Point
|
||||
Matrix3d? referenceTransform = null;
|
||||
if (
|
||||
Application.DocumentManager.CurrentDocument.Editor.CurrentUserCoordinateSystem is Matrix3d matrix
|
||||
&& matrix != Matrix3d.Identity
|
||||
)
|
||||
{
|
||||
referenceTransform = matrix.Inverse();
|
||||
|
||||
/* POC: Do not attach transform to root for now! we are not consuming this in autocad/civil on receive and in revit it will undo all baked transforms :(
|
||||
var transformMatrix = ReferencePointHelper.CreateTransformDataForRootObject(matrix);
|
||||
root[ReferencePointHelper.REFERENCE_POINT_TRANSFORM_KEY] = transformMatrix;
|
||||
*/
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 4 - Convert atomic objects
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
cancellationToken.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)
|
||||
{
|
||||
// Create and add a collection for this entity if not done so already.
|
||||
(Collection objectCollection, LayerTableRecord? autocadLayer) = CreateObjectCollection(entity, tr);
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(objectCollection);
|
||||
}
|
||||
|
||||
if (autocadLayer is not null)
|
||||
SendConversionResult? result = null;
|
||||
// If this is a atomic definition object, we *do not* want to bake in the reference point transform to the object
|
||||
if (atomicDefinitionObjectIds.Contains(applicationId))
|
||||
{
|
||||
using (_converterSettings.Push(currentSettings => currentSettings with { ReferencePointTransform = null }))
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(objectCollection);
|
||||
result = ConvertAutocadEntity(entity, applicationId, objectCollection, instanceProxies, projectId);
|
||||
}
|
||||
|
||||
var result = ConvertAutocadEntity(
|
||||
}
|
||||
else // this is a selected atomic object (not part of definition)
|
||||
{
|
||||
result = ConvertAutocadEntity(
|
||||
entity,
|
||||
applicationId,
|
||||
objectCollection,
|
||||
instanceProxies,
|
||||
sendInfo.ProjectId
|
||||
projectId,
|
||||
referenceTransform // set this for top level instance proxies to use if needed
|
||||
);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
|
||||
}
|
||||
|
||||
results.Add(result);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
@@ -124,10 +158,10 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
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
|
||||
// 5 - Unpack the render material proxies
|
||||
root[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackMaterials(atomicObjects, usedAcadLayers);
|
||||
|
||||
// 5 - Unpack the color proxies
|
||||
// 6 - Unpack the color proxies
|
||||
root[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, usedAcadLayers);
|
||||
|
||||
// add any additional properties (most likely from verticals)
|
||||
@@ -152,15 +186,24 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId
|
||||
string projectId,
|
||||
Matrix3d? transform = null
|
||||
)
|
||||
{
|
||||
string sourceType = entity.GetType().ToString();
|
||||
try
|
||||
{
|
||||
Base converted;
|
||||
if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
if (entity is BlockReference br && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
{
|
||||
// modify transform by reference point this if it is top level
|
||||
if (instanceProxy.maxDepth == 0 && transform is Matrix3d validTransform)
|
||||
{
|
||||
instanceProxy.transform = TransformHelper.ConvertToInstanceMatrix4x4(
|
||||
br.BlockTransform.PreMultiplyBy(validTransform)
|
||||
);
|
||||
}
|
||||
|
||||
converted = instanceProxy;
|
||||
}
|
||||
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
|
||||
|
||||
@@ -2,6 +2,7 @@ using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
@@ -15,6 +16,7 @@ public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
public AutocadRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
IRootToSpeckleConverter converter,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
@@ -25,6 +27,7 @@ public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
converterSettings,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
|
||||
@@ -7,6 +7,8 @@ public static class AppUtils
|
||||
public static Speckle.Sdk.Application App =>
|
||||
#if CIVIL3D
|
||||
HostApplications.Civil3D;
|
||||
#elif PLANT3D
|
||||
HostApplications.Plant3D;
|
||||
#elif AUTOCAD
|
||||
HostApplications.AutoCAD;
|
||||
#else
|
||||
@@ -14,11 +16,11 @@ public static class AppUtils
|
||||
#endif
|
||||
|
||||
public static HostAppVersion Version =>
|
||||
#if AUTOCAD2026 || CIVIL3D2026
|
||||
#if AUTOCAD2026 || CIVIL3D2026 || PLANT3D2026
|
||||
HostAppVersion.v2026;
|
||||
#elif AUTOCAD2025 || CIVIL3D2025
|
||||
#elif AUTOCAD2025 || CIVIL3D2025 || PLANT3D2025
|
||||
HostAppVersion.v2025;
|
||||
#elif AUTOCAD2024 || CIVIL3D2024
|
||||
#elif AUTOCAD2024 || CIVIL3D2024 || PLANT3D2024
|
||||
HostAppVersion.v2024;
|
||||
#elif AUTOCAD2023|| CIVIL3D2023
|
||||
HostAppVersion.v2023;
|
||||
|
||||
@@ -11,16 +11,19 @@ using Speckle.Converters.Autocad;
|
||||
#elif CIVIL3D
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Connectors.Civil3dShared.DependencyInjection;
|
||||
#elif PLANT3D
|
||||
using Speckle.Connectors.Plant3dShared.DependencyInjection;
|
||||
using Speckle.Converters.Plant3dShared;
|
||||
#endif
|
||||
namespace Speckle.Connectors.Autocad.Plugin;
|
||||
|
||||
public class AutocadCommand
|
||||
{
|
||||
private static PaletteSet? PaletteSet { get; set; }
|
||||
private static readonly Guid s_id = new("3223E594-1B09-4E54-B3DD-8EA0BECE7BA5");
|
||||
private static readonly Guid s_id = new("7C27DD2B-86E8-4D31-B3DE-B34B267B1DC8");
|
||||
public ServiceProvider? Container { get; private set; }
|
||||
private IDisposable? _disposableLogger;
|
||||
public const string COMMAND_STRING = "SpeckleBeta";
|
||||
public const string COMMAND_STRING = "Speckle";
|
||||
|
||||
[CommandMethod(COMMAND_STRING)]
|
||||
public void Command()
|
||||
@@ -31,28 +34,33 @@ public class AutocadCommand
|
||||
return;
|
||||
}
|
||||
|
||||
PaletteSet = new PaletteSet($"Speckle (Beta)", s_id)
|
||||
PaletteSet = new PaletteSet($"Speckle", s_id)
|
||||
{
|
||||
Size = new Size(400, 500),
|
||||
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right)
|
||||
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right),
|
||||
};
|
||||
|
||||
// init DI
|
||||
var services = new ServiceCollection();
|
||||
|
||||
_disposableLogger = services.Initialize(AppUtils.App, AppUtils.Version);
|
||||
|
||||
#if AUTOCAD
|
||||
services.AddAutocad();
|
||||
services.AddAutocadConverters();
|
||||
#elif CIVIL3D
|
||||
services.AddCivil3d();
|
||||
services.AddCivil3dConverters();
|
||||
#elif PLANT3D
|
||||
services.AddPlant3d();
|
||||
services.AddPlant3dConverters();
|
||||
#endif
|
||||
Container = services.BuildServiceProvider();
|
||||
Container.UseDUI();
|
||||
|
||||
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
|
||||
PaletteSet.AddVisual("Speckle (Beta)", panelWebView);
|
||||
PaletteSet.AddVisual("Speckle", panelWebView);
|
||||
|
||||
FocusPalette();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Autodesk.Windows;
|
||||
using Speckle.Sdk;
|
||||
#if !AUTOCAD2025_OR_GREATER && !CIVIL3D2025_OR_GREATER
|
||||
#if !AUTOCAD2025_OR_GREATER && !CIVIL3D2025_OR_GREATER && !PLANT3D2025_OR_GREATER
|
||||
using System.IO;
|
||||
#endif
|
||||
|
||||
@@ -49,19 +49,18 @@ public class AutocadRibbon
|
||||
private void Create()
|
||||
{
|
||||
RibbonTab tab = FindOrMakeTab("Speckle");
|
||||
RibbonPanelSource source = new() { Title = "Speckle (Beta)" };
|
||||
RibbonPanelSource source = new() { Title = "Speckle" };
|
||||
RibbonPanel panel = new() { Source = source };
|
||||
tab.Panels.Add(panel);
|
||||
|
||||
RibbonToolTip speckleToolTip =
|
||||
new()
|
||||
{
|
||||
Title = "Speckle (Beta)",
|
||||
Content = $"Next Gen Speckle Connector (Beta) for {AppUtils.App.Name}",
|
||||
IsHelpEnabled = true // Without this "Press F1 for help" does not appear in the tooltip
|
||||
};
|
||||
RibbonToolTip speckleToolTip = new()
|
||||
{
|
||||
Title = "Speckle",
|
||||
Content = $"Next Gen Speckle Connector for {AppUtils.App.Name}",
|
||||
IsHelpEnabled = true, // Without this "Press F1 for help" does not appear in the tooltip
|
||||
};
|
||||
|
||||
_ = CreateSpeckleButton("Speckle (Beta)", source, null, speckleToolTip, "logo");
|
||||
_ = CreateSpeckleButton("Speckle", source, null, speckleToolTip, "logo");
|
||||
}
|
||||
|
||||
private void ComponentManager_ItemInitialized(object? sender, RibbonItemEventArgs e)
|
||||
@@ -121,7 +120,7 @@ public class AutocadRibbon
|
||||
ShowText = true,
|
||||
ToolTip = tooltip,
|
||||
HelpSource = new System.Uri("https://speckle.guide/user/autocadcivil.html"),
|
||||
Size = RibbonItemSize.Large
|
||||
Size = RibbonItemSize.Large,
|
||||
};
|
||||
|
||||
if (TryLoadPngImgSource(imageName + "16.png", out ImageSource? imageSource))
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ApplicationPackage
|
||||
SchemaVersion="1.0"
|
||||
AppVersion="1.0"
|
||||
Author="AEC SYSTEMS LTD"
|
||||
Name="Speckle for AutoCAD"
|
||||
Description="Speckle for AutoCAD"
|
||||
Icon="./Contents/Resources/Logo.ico"
|
||||
ProductCode="{958850b9-3782-4e6f-b9b3-1b570e0fcae1}"
|
||||
UpgradeCode="{274de351-80aa-4972-9b45-6a93f8ce968f}"
|
||||
>
|
||||
<!-- For now, we're not updating the AppVersion & ProductCodes with each version -->
|
||||
|
||||
<CompanyDetails Name="Speckle" Url="https://speckle.systems" Email="support@speckle.systems" />
|
||||
<Components>
|
||||
<!-- AutoCAD 2022 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Autocad2022"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Autocad2022/Speckle.Connectors.Autocad2022.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="AutoCAD" SeriesMin="R24.1" SeriesMax="R24.1" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2023 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Autocad2023"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Autocad2023/Speckle.Connectors.Autocad2023.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="AutoCAD" SeriesMin="R24.2" SeriesMax="R24.2" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2024 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Autocad2024"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Autocad2024/Speckle.Connectors.Autocad2024.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="AutoCAD" SeriesMin="R24.3" SeriesMax="R24.3" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2025 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Autocad2025"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Autocad2025/Speckle.Connectors.Autocad2025.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="AutoCAD" SeriesMin="R25.0" SeriesMax="R25.0" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2026 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Autocad2026"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Autocad2026/Speckle.Connectors.Autocad2026.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="AutoCAD" SeriesMin="R25.1" SeriesMax="R25.1" />
|
||||
</ComponentEntry>
|
||||
</Components>
|
||||
</ApplicationPackage>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ApplicationPackage
|
||||
SchemaVersion="1.0"
|
||||
AppVersion="1.0"
|
||||
Author="AEC SYSTEMS LTD"
|
||||
Name="Speckle for Civil 3D"
|
||||
Description="Speckle for Civil 3D"
|
||||
Icon="./Contents/Resources/Logo.ico"
|
||||
ProductCode="{cecad7b2-daa9-4a9d-941d-737619ffd999}"
|
||||
UpgradeCode="{ccf4134d-0e24-4e91-8bf4-781ec7313bef}"
|
||||
>
|
||||
<!-- For now, we're not updating the AppVersion & ProductCodes with each version -->
|
||||
|
||||
<CompanyDetails Name="Speckle" Url="https://speckle.systems" Email="support@speckle.systems" />
|
||||
<Components>
|
||||
<!-- AutoCAD 2022 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Civil3d2022"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Civil3d2022/Speckle.Connectors.Civil3d2022.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Civil3D" SeriesMin="R24.1" SeriesMax="R24.1" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2023 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Civil3d2023"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Civil3d2023/Speckle.Connectors.Civil3d2023.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Civil3D" SeriesMin="R24.2" SeriesMax="R24.2" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2024 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Civil3d2024"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Civil3d2024/Speckle.Connectors.Civil3d2024.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Civil3D" SeriesMin="R24.3" SeriesMax="R24.3" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2025 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Civil3d2025"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Civil3d2025/Speckle.Connectors.Civil3d2025.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Civil3D" SeriesMin="R25.0" SeriesMax="R25.0" />
|
||||
</ComponentEntry>
|
||||
|
||||
<!-- AutoCAD 2026 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Civil3d2026"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Civil3d2026/Speckle.Connectors.Civil3d2026.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Civil3D" SeriesMin="R25.1" SeriesMax="R25.1" />
|
||||
</ComponentEntry>
|
||||
</Components>
|
||||
</ApplicationPackage>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ApplicationPackage
|
||||
SchemaVersion="1.0"
|
||||
AppVersion="1.0"
|
||||
Author="AEC SYSTEMS LTD"
|
||||
Name="Speckle for Plant 3D"
|
||||
Description="Speckle for Plant 3D"
|
||||
Icon="./Contents/Resources/Logo.ico"
|
||||
ProductCode="{b91352b6-01db-4084-93c8-684bb231947e}"
|
||||
UpgradeCode="{91c7e43f-e962-40e9-85bd-d6bd733b6964}"
|
||||
>
|
||||
<CompanyDetails Name="Speckle" Url="https://speckle.systems" Email="support@speckle.systems" />
|
||||
<Components>
|
||||
<!-- Plant 3D 2026 -->
|
||||
<ComponentEntry
|
||||
AppName="Speckle.Connectors.Plant3d2026"
|
||||
ModuleName="./Contents/Windows/Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.dll"
|
||||
LoadOnAutoCADStartup="True"
|
||||
>
|
||||
<RuntimeRequirements OS="Win64" Platform="Plant3D" SeriesMin="R25.1" SeriesMax="R25.1" />
|
||||
</ComponentEntry>
|
||||
</Components>
|
||||
</ApplicationPackage>
|
||||
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 430 B |
@@ -38,8 +38,11 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Extensions\EntityExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Extensions\SpeckleApplicationIdExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TransactionContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\AutocadHostObjectBaseBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\AutocadHostObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObject.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadContinuousTraversalBaseBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadContinuousTraversalBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBaseBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadRibbon.cs" />
|
||||
@@ -52,4 +55,15 @@
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\s2logo16.png" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\s2logo32.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Plugin\BundleCivil3D\PackageContents.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Plugin\BundleAutoCAD\PackageContents.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Plugin\BundlePlant3D\PackageContents.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -3,6 +3,15 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{41BC679F-887F-44CF-971D-A5502EE87DB0}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Local|AnyCPU' ">
|
||||
<OutputPath>bin\Local\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
</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"/>
|
||||
|
||||
@@ -8,16 +8,22 @@
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2022.0.2" ExcludeAssets="runtime" />
|
||||
</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" />
|
||||
|
||||
<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>
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -178,6 +178,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -268,9 +291,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +324,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,35 +368,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,22 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" ExcludeAssets="runtime" />
|
||||
</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" />
|
||||
|
||||
<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>
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -178,6 +178,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -268,9 +291,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +324,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,35 +368,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,22 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2024.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2024\Speckle.Converters.Civil3d2024.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" />
|
||||
|
||||
<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>
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -178,6 +178,29 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -268,9 +291,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +324,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,35 +368,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"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.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,23 +8,26 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- .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 -->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
|
||||
</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>
|
||||
|
||||
@@ -84,11 +84,6 @@
|
||||
"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",
|
||||
@@ -169,6 +164,25 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -224,9 +238,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -259,7 +272,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -303,34 +316,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -8,23 +8,26 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- .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 -->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<!--This is needed for managed dependencies-->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<!--This is needed for the rest-->
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<!--This is needed just to keep folder paths the same as the netframework versions of autocad/civil-->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2026\Speckle.Converters.Civil3d2026.csproj" />
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2026.0.0" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2026\Speckle.Converters.Civil3d2026.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>
|
||||
|
||||
@@ -84,11 +84,6 @@
|
||||
"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",
|
||||
@@ -169,6 +164,25 @@
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -224,9 +238,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )",
|
||||
"Speckle.Sdk": "[3.3.5, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.3.5, )"
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -259,7 +272,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -303,34 +316,12 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
|
||||
"requested": "[3.15.3, )",
|
||||
"resolved": "3.15.3",
|
||||
"contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.3.5"
|
||||
"Speckle.Sdk": "3.15.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.3.5"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.3.5, )",
|
||||
"resolved": "3.3.5",
|
||||
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Bindings;
|
||||
|
||||
@@ -19,27 +17,14 @@ public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public Civil3dReceiveBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
IThreadContext threadContext,
|
||||
IReceiveOperationManagerFactory receiveOperationManagerFactory
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext
|
||||
)
|
||||
: base(parent, cancellationManager, threadContext, receiveOperationManagerFactory)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
@@ -47,7 +32,7 @@ public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
|
||||
|
||||
// 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 receive binding for civil3d due to using a different unit converter (needed for conversion settings construction)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
@@ -11,7 +10,6 @@ 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;
|
||||
|
||||
@@ -25,30 +23,24 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager appIdleManager
|
||||
IAppIdleManager appIdleManager,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext,
|
||||
topLevelExceptionHandler,
|
||||
appIdleManager
|
||||
appIdleManager,
|
||||
sendOperationManagerFactory
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
|
||||
@@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Civil3dShared.Bindings;
|
||||
using Speckle.Connectors.Civil3dShared.HostApp;
|
||||
using Speckle.Connectors.Civil3dShared.Operations.Receive;
|
||||
using Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
@@ -20,14 +22,20 @@ public static class Civil3dConnectorModule
|
||||
// add send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
serviceCollection.AddScoped<
|
||||
IRootContinuousTraversalBuilder<AutocadRootObject>,
|
||||
Civil3dContinuousTraversalBuilder
|
||||
>();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dSendBinding>();
|
||||
|
||||
// add receive
|
||||
serviceCollection.LoadReceive();
|
||||
serviceCollection.AddScoped<IHostObjectBuilder, Civil3dHostObjectBuilder>();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dReceiveBinding>();
|
||||
|
||||
// additional classes
|
||||
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
|
||||
serviceCollection.AddScoped<PropertySetBaker>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
using AAEC = Autodesk.Aec;
|
||||
using AAECPDB = Autodesk.Aec.PropertyData.DatabaseServices;
|
||||
using ADB = Autodesk.AutoCAD.DatabaseServices;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class to bake property sets to entities on receive.
|
||||
/// </summary>
|
||||
public class PropertySetBaker
|
||||
{
|
||||
private const string PROP_SET_DEF_DICT_NAME = "AecPropertySetDefs";
|
||||
private readonly IConverterSettingsStore<Civil3dConversionSettings> _settingsStore;
|
||||
private readonly ILogger<PropertySetBaker> _logger;
|
||||
private readonly PropertyHandler _propertyHandler;
|
||||
|
||||
/// <summary>
|
||||
/// Map of property set definition name to its ObjectId. Populated during ParsePropertySetDefinitions.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, ADB.ObjectId> _propertySetDefinitionMap = new();
|
||||
|
||||
public PropertySetBaker(
|
||||
IConverterSettingsStore<Civil3dConversionSettings> settingsStore,
|
||||
ILogger<PropertySetBaker> logger
|
||||
)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
_logger = logger;
|
||||
_propertyHandler = new PropertyHandler();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all property set definitions with a prefix before receive operation.
|
||||
/// </summary>
|
||||
public void PurgePropertySets(string namePrefix)
|
||||
{
|
||||
ADB.Database db = _settingsStore.Current.Document.Database;
|
||||
using var tr = db.TransactionManager.StartTransaction();
|
||||
|
||||
List<ADB.ObjectId> definitionsToDelete = new();
|
||||
|
||||
// Access the property set definition dictionary from the named object dictionary
|
||||
var nod = (ADB.DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, ADB.OpenMode.ForRead);
|
||||
|
||||
if (nod.Contains(PROP_SET_DEF_DICT_NAME))
|
||||
{
|
||||
ADB.ObjectId propSetDefsDictId = nod.GetAt(PROP_SET_DEF_DICT_NAME);
|
||||
var propSetDefsDict = (ADB.DBDictionary)tr.GetObject(propSetDefsDictId, ADB.OpenMode.ForRead);
|
||||
|
||||
// Iterate through all property set definitions in the dictionary
|
||||
foreach (ADB.DBDictionaryEntry entry in propSetDefsDict)
|
||||
{
|
||||
if (entry.Key.Contains(namePrefix))
|
||||
{
|
||||
definitionsToDelete.Add(entry.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the matching definitions
|
||||
foreach (ADB.ObjectId defId in definitionsToDelete)
|
||||
{
|
||||
try
|
||||
{
|
||||
var propSetDef = (AAECPDB.PropertySetDefinition)tr.GetObject(defId, ADB.OpenMode.ForWrite);
|
||||
propSetDef.Erase();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to purge property set definition");
|
||||
}
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse and bake all property set definitions from the root object.
|
||||
/// Should be called after purging and after materials/colors are parsed.
|
||||
/// </summary>
|
||||
public void ParseAndBakePropertySetDefinitions(Base rootObject, string namePrefix)
|
||||
{
|
||||
_propertySetDefinitionMap.Clear();
|
||||
|
||||
if (rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] is not Dictionary<string, object?> definitions)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (definitions.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction();
|
||||
|
||||
foreach (var definition in definitions)
|
||||
{
|
||||
string setName = definition.Key;
|
||||
object? setDefObj = definition.Value;
|
||||
|
||||
if (setDefObj is not Dictionary<string, object?> setDefData)
|
||||
{
|
||||
_logger.LogWarning("Property set definition {SetName} has invalid data format", setName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!setDefData.TryGetValue(PropertySetDefinitionHandler.PROP_SET_PROP_DEFS_KEY, out var propDefsObj))
|
||||
{
|
||||
_logger.LogWarning("Property set definition {SetName} missing propertyDefinitions", setName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propDefsObj is not Dictionary<string, object?> propertyDefinitions)
|
||||
{
|
||||
_logger.LogWarning("Property set definition {SetName} propertyDefinitions has invalid format", setName);
|
||||
continue;
|
||||
}
|
||||
|
||||
ADB.ObjectId defId = CreatePropertySetDefinition(setName, propertyDefinitions, namePrefix, tr);
|
||||
if (!defId.IsNull)
|
||||
{
|
||||
_propertySetDefinitionMap[setName] = defId;
|
||||
}
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to bake property sets from a Speckle object to a Civil3D entity.
|
||||
/// </summary>
|
||||
public bool TryBakePropertySets(ADB.Entity entity, Base sourceObject, ADB.Transaction tr)
|
||||
{
|
||||
if (
|
||||
sourceObject["properties"] is not Dictionary<string, object?> properties
|
||||
|| !properties.TryGetValue("Property Sets", out var propertySetsObj)
|
||||
|| propertySetsObj is not Dictionary<string, object?> propertySets
|
||||
|| propertySets.Count == 0
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var propertySet in propertySets)
|
||||
{
|
||||
string setName = propertySet.Key;
|
||||
object? setDataObj = propertySet.Value;
|
||||
|
||||
if (setDataObj is not Dictionary<string, object?> setData)
|
||||
{
|
||||
_logger.LogWarning("Property set {SetName} has invalid data format", setName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TryBakePropertySet(entity, setName, setData, tr))
|
||||
{
|
||||
_logger.LogWarning("Failed to bake property set {SetName} onto entity", setName);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to bake property sets onto entity {Handle}", entity.Handle);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryBakePropertySet(
|
||||
ADB.Entity entity,
|
||||
string setName,
|
||||
Dictionary<string, object?> setData,
|
||||
ADB.Transaction tr
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_propertySetDefinitionMap.TryGetValue(setName, out ADB.ObjectId propertySetDefId))
|
||||
{
|
||||
_logger.LogWarning("Property set definition {SetName} not found in definition map", setName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (propertySetDefId.IsNull)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ObjectHasPropertySet(entity, propertySetDefId))
|
||||
{
|
||||
throw new SpeckleException($"Property set '{setName}' already exists on entity.");
|
||||
}
|
||||
|
||||
return AddPropertySetToEntity(entity, propertySetDefId, setData, tr);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to process property set {SetName}", setName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ADB.ObjectId CreatePropertySetDefinition(
|
||||
string setName,
|
||||
Dictionary<string, object?> propertyDefinitions,
|
||||
string namePrefix,
|
||||
ADB.Transaction tr
|
||||
)
|
||||
{
|
||||
var db = _settingsStore.Current.Document.Database;
|
||||
using AAECPDB.DictionaryPropertySetDefinitions propSetDefs = new(db);
|
||||
|
||||
string prefixedName = $"{setName}-{namePrefix}";
|
||||
|
||||
AAECPDB.PropertySetDefinition propSetDef = new();
|
||||
propSetDef.SetToStandard(db);
|
||||
propSetDef.SubSetDatabaseDefaults(db);
|
||||
//propSetDef.Description = "Property Set Definition added by Speckle"; // POC: should use the description that was published. can this back in if needed
|
||||
propSetDef.AppliesToAll = true;
|
||||
|
||||
foreach (var propertyDefinition in propertyDefinitions)
|
||||
{
|
||||
string propertyName = propertyDefinition.Key;
|
||||
object? propertyDefObj = propertyDefinition.Value;
|
||||
|
||||
if (propertyDefObj is not Dictionary<string, object?> propertyDefDict)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
!propertyDefDict.TryGetValue(PropertySetDefinitionHandler.PROP_DEF_TYPE_KEY, out var dataTypeStr)
|
||||
|| dataTypeStr is not string dataTypeString
|
||||
)
|
||||
{
|
||||
_logger.LogError(
|
||||
"Property set definition {SetName} is invalid: property {PropertyName} missing or invalid dataType",
|
||||
setName,
|
||||
propertyName
|
||||
);
|
||||
return ADB.ObjectId.Null;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse(dataTypeString, out AAEC.PropertyData.DataType dataType))
|
||||
{
|
||||
_logger.LogError(
|
||||
"Property set definition {SetName} is invalid: unsupported data type {DataType} for property {PropertyName}",
|
||||
setName,
|
||||
dataTypeString,
|
||||
propertyName
|
||||
);
|
||||
return ADB.ObjectId.Null;
|
||||
}
|
||||
|
||||
AAECPDB.PropertyDefinition propDef = new() { DataType = dataType, Name = propertyName };
|
||||
|
||||
propDef.SetToStandard(db);
|
||||
propDef.SubSetDatabaseDefaults(db);
|
||||
|
||||
if (
|
||||
propertyDefDict.TryGetValue(PropertySetDefinitionHandler.PROP_DEF_DEFAULT_VALUE_KEY, out object? defaultValue)
|
||||
&& defaultValue != null
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Cast numeric types to avoid bad numeric value errors
|
||||
var convertedValue = dataType switch
|
||||
{
|
||||
AAEC.PropertyData.DataType.Integer => (int)(long)defaultValue,
|
||||
AAEC.PropertyData.DataType.AutoIncrement => (int)(long)defaultValue,
|
||||
_ => defaultValue,
|
||||
};
|
||||
|
||||
propDef.DefaultData = convertedValue;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogWarning(
|
||||
ex,
|
||||
"Failed to set default value for property {PropertyName}, continuing without default",
|
||||
propertyName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
propSetDef.Definitions.Add(propDef);
|
||||
}
|
||||
|
||||
propSetDefs.AddNewRecord(prefixedName, propSetDef);
|
||||
tr.AddNewlyCreatedDBObject(propSetDef, true);
|
||||
|
||||
return propSetDef.ObjectId;
|
||||
}
|
||||
|
||||
private bool ObjectHasPropertySet(ADB.DBObject obj, ADB.ObjectId propertySetId)
|
||||
{
|
||||
try
|
||||
{
|
||||
ADB.ObjectId tempId = AAECPDB.PropertyDataServices.GetPropertySet(obj, propertySetId);
|
||||
return !tempId.IsNull;
|
||||
}
|
||||
catch (Autodesk.AutoCAD.Runtime.Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddPropertySetToEntity(
|
||||
ADB.Entity entity,
|
||||
ADB.ObjectId propertySetDefId,
|
||||
Dictionary<string, object?> setData,
|
||||
ADB.Transaction tr
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!entity.IsWriteEnabled)
|
||||
{
|
||||
entity.UpgradeOpen();
|
||||
}
|
||||
|
||||
AAECPDB.PropertyDataServices.AddPropertySet(entity, propertySetDefId);
|
||||
|
||||
return TrySetPropertyValues(entity, propertySetDefId, setData, tr);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to add property set to entity");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TrySetPropertyValues(
|
||||
ADB.Entity entity,
|
||||
ADB.ObjectId propertySetDefId,
|
||||
Dictionary<string, object?> setData,
|
||||
ADB.Transaction tr
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
ADB.ObjectId propertySetId = AAECPDB.PropertyDataServices.GetPropertySet(entity, propertySetDefId);
|
||||
var propertySet = (AAECPDB.PropertySet)tr.GetObject(propertySetId, ADB.OpenMode.ForWrite);
|
||||
var setDefinition = (AAECPDB.PropertySetDefinition)tr.GetObject(propertySetDefId, ADB.OpenMode.ForRead);
|
||||
|
||||
// Build a map of property names to definition IDs
|
||||
Dictionary<string, int> propertyNameToId = new();
|
||||
foreach (AAECPDB.PropertyDefinition propDef in setDefinition.Definitions)
|
||||
{
|
||||
propertyNameToId[propDef.Name] = propDef.Id;
|
||||
}
|
||||
|
||||
foreach (var propertyEntry in setData)
|
||||
{
|
||||
string propertyName = propertyEntry.Key;
|
||||
object? propertyDataObj = propertyEntry.Value;
|
||||
|
||||
if (propertyDataObj is not Dictionary<string, object?> propertyDataDict)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!propertyDataDict.TryGetValue("value", out var value) || value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!propertyNameToId.TryGetValue(propertyName, out int propertyId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_propertyHandler.TryGetValue(
|
||||
() =>
|
||||
{
|
||||
propertySet.SetAt(propertyId, value);
|
||||
return true;
|
||||
},
|
||||
out _
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to update property set values");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||