Compare commits
509 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| df6e2070b0 | |||
| 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 | |||
| afcc5c91db | |||
| 65cf7a762a | |||
| 658e3d5c25 | |||
| 0e5ee6632f | |||
| 193a7375ae | |||
| 46cd0f8f15 | |||
| 169cfd6123 | |||
| 389395c5b5 | |||
| a24e9f575b | |||
| 2f8bda5484 | |||
| ead151bec0 | |||
| 83b7280758 | |||
| 98c4c33acc | |||
| 30cbd1dead | |||
| 789962f50c | |||
| 30ea9858c6 | |||
| 6ff458a0b6 | |||
| ceb02df1b4 | |||
| ce3e6ef5fa | |||
| 53e6a84f7f | |||
| 602889d1e3 | |||
| ec22e6ca39 | |||
| 532b5157d0 | |||
| 74cd1b3e2c | |||
| bd3e20a082 | |||
| f319e0dc1d | |||
| bdd1e61b6d | |||
| c8ceeab2d9 | |||
| 81f2ed0a75 | |||
| 2232227a8b | |||
| 871359738c | |||
| ea2cb90b2e | |||
| 248c96d9c2 | |||
| a71a9ef32c |
@@ -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
|
||||
@@ -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",
|
||||
[
|
||||
@@ -44,6 +43,7 @@ public static class Consts
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2026", "net8.0-windows")
|
||||
]
|
||||
),
|
||||
new("plant3d", [new("Connectors/Autocad/Speckle.Connectors.Plant3d2026", "net8.0-windows")]),
|
||||
new(
|
||||
"navisworks",
|
||||
[
|
||||
@@ -60,7 +60,8 @@ public static class Consts
|
||||
"teklastructures",
|
||||
[
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2025", "net48")
|
||||
]
|
||||
),
|
||||
new(
|
||||
@@ -69,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")]),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
@@ -150,7 +151,7 @@ Target(
|
||||
|
||||
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>
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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.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);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,23 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
? instance.AnonymousBlockTableRecord
|
||||
: instance.BlockTableRecord;
|
||||
|
||||
// transforms on instances are always stored in WCS
|
||||
InstanceProxy instanceProxy =
|
||||
new()
|
||||
{
|
||||
applicationId = instanceId,
|
||||
definitionId = definitionId.ToString(),
|
||||
maxDepth = depth,
|
||||
transform = GetMatrix(instance.BlockTransform.ToArray()),
|
||||
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.
|
||||
@@ -162,6 +175,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
|
||||
UnpackInstance(blockReference, depth + 1, transaction);
|
||||
}
|
||||
|
||||
_instanceObjectsManager.AddAtomicDefinitionObjectId(appId);
|
||||
_instanceObjectsManager.AddAtomicObject(appId, new(obj, appId));
|
||||
}
|
||||
|
||||
@@ -172,7 +186,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;
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,197 @@
|
||||
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,7 +67,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
)]
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
string projectId,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
@@ -81,42 +88,70 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
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 +159,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 +187,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,7 +34,7 @@ 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)
|
||||
@@ -39,20 +42,25 @@ public class AutocadCommand
|
||||
|
||||
// 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,19 @@ 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}",
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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,79 @@
|
||||
<?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,31 @@
|
||||
<?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"/>
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Receive;
|
||||
using Speckle.Connectors.Civil3dShared.HostApp;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Models;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Operations.Receive;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Civil3D specific host object builder with property set support. Expects to be a scoped dependency per receive operation.</para>
|
||||
/// </summary>
|
||||
public sealed class Civil3dHostObjectBuilder : AutocadHostObjectBaseBuilder
|
||||
{
|
||||
private readonly PropertySetBaker _propertySetBaker;
|
||||
|
||||
public Civil3dHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker,
|
||||
IReceiveConversionHandler conversionHandler,
|
||||
PropertySetBaker propertySetBaker
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
layerBaker,
|
||||
groupBaker,
|
||||
instanceBaker,
|
||||
materialBaker,
|
||||
colorBaker,
|
||||
autocadContext,
|
||||
rootObjectUnpacker,
|
||||
conversionHandler
|
||||
)
|
||||
{
|
||||
_propertySetBaker = propertySetBaker;
|
||||
}
|
||||
|
||||
protected override void PreReceiveAdditionalDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
_propertySetBaker.PurgePropertySets(baseLayerPrefix);
|
||||
}
|
||||
|
||||
protected override void ParseAndBakeAdditionalProxies(Base rootObject, string baseLayerPrefix)
|
||||
{
|
||||
_propertySetBaker.ParseAndBakePropertySetDefinitions(rootObject, baseLayerPrefix);
|
||||
}
|
||||
|
||||
protected override void PostBakeEntity(Entity entity, Base originalObject, Transaction tr)
|
||||
{
|
||||
_propertySetBaker.TryBakePropertySets(entity, originalObject, tr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
|
||||
public sealed class Civil3dContinuousTraversalBuilder : AutocadContinuousTraversalBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
|
||||
|
||||
public Civil3dContinuousTraversalBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
PropertySetDefinitionHandler propertySetDefinitionHandler,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
colorUnpacker,
|
||||
groupUnpacker,
|
||||
logger,
|
||||
activityFactory
|
||||
)
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_propertySetDefinitionHandler = propertySetDefinitionHandler;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
|
||||
public override void AddAdditionalProxiesToRoot(Collection rootObject)
|
||||
{
|
||||
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
@@ -20,6 +21,7 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
PropertySetDefinitionHandler propertySetDefinitionHandler,
|
||||
IRootToSpeckleConverter converter,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
@@ -30,6 +32,7 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
converterSettings,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
|
||||
@@ -11,11 +11,16 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\PropertySetBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\Civil3dHostObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dContinuousTraversalBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dSendBinding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)HostApp\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Receive\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Plant3DVersion>2026</Plant3DVersion>
|
||||
<DefineConstants>$(DefineConstants);PLANT3D2026;PLANT3D;PLANT3D2024_OR_GREATER;PLANT3D2025_OR_GREATER;PLANT3D2026_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<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-->
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
|
||||
<PackageReference Include="Speckle.Plant3D.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.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.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems" Label="Shared" />
|
||||
|
||||
<Import Project="..\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -1,19 +1,7 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net6.0-windows7.0": {
|
||||
"Esri.ArcGISPro.Extensions30": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.2.0.49743, )",
|
||||
"resolved": "3.2.0.49743",
|
||||
"contentHash": "fmnYm+mD14Cz0Uqh1ij37SfLJerkyFHK5581y5tXT/l3H2ZvUmVuuxjYquXzyzj9p7IexQzMW4xCpxe+mD922g=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"net8.0-windows7.0": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
@@ -39,12 +27,27 @@
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2026.0.0, )",
|
||||
"resolved": "2026.0.0",
|
||||
"contentHash": "WlkV81PmbK/ftoM7aGpU6LGosKbePBQej9MO/m63rFMozX89tsitEhE12o58wu7K/4FmRUdAMolYtdK20EDBnw=="
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"Speckle.Plant3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2026.0.0, )",
|
||||
"resolved": "2026.0.0",
|
||||
"contentHash": "VT8M6CGQl1mk3/5Ro3AEAOVrOs/cX58YRwYZnu+6xeHvsazK07Et/6kMJsde4Y7Xrpox7eBLKgYeOspiRVvX5g==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2026.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -76,21 +79,11 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"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",
|
||||
@@ -171,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",
|
||||
@@ -221,21 +233,13 @@
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
|
||||
},
|
||||
"speckle.common.meshtriangulation": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"LibTessDotNet": "[1.1.15, )",
|
||||
"Speckle.DoubleNumerics": "[4.1.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"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": {
|
||||
@@ -255,26 +259,21 @@
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.arcgis3": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Esri.ArcGISPro.Extensions30": "[3.2.0.49743, )",
|
||||
"Speckle.Common.MeshTriangulation": "[1.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.3.5, )"
|
||||
"Speckle.Objects": "[3.15.3, )"
|
||||
}
|
||||
},
|
||||
"LibTessDotNet": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.1.15, )",
|
||||
"resolved": "1.1.15",
|
||||
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
|
||||
"speckle.converters.plant3d2026": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2026.0.0, )",
|
||||
"Speckle.Connectors.DUI.WebView": "[1.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )",
|
||||
"Speckle.Plant3D.API": "[2026.0.0, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
@@ -297,6 +296,12 @@
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
@@ -311,38 +316,15 @@
|
||||
},
|
||||
"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=="
|
||||
}
|
||||
},
|
||||
"net6.0-windows7.0/win-x64": {
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Plant3dShared;
|
||||
|
||||
namespace Speckle.Connectors.Plant3dShared.Bindings;
|
||||
|
||||
public sealed class Plant3dSendBinding : AutocadSendBaseBinding
|
||||
{
|
||||
private readonly IPlant3dConversionSettingsFactory _plant3dConversionSettingsFactory;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public Plant3dSendBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
ICancellationManager cancellationManager,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IPlant3dConversionSettingsFactory plant3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager appIdleManager,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
sendConversionCache,
|
||||
threadContext,
|
||||
topLevelExceptionHandler,
|
||||
appIdleManager,
|
||||
sendOperationManagerFactory
|
||||
)
|
||||
{
|
||||
_plant3dConversionSettingsFactory = plant3dConversionSettingsFactory;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
}
|
||||
|
||||
// We need a separate send binding for Plant 3D due to using a different unit converter (needed for conversion settings construction)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<Plant3dConversionSettings>>()
|
||||
.Initialize(_plant3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.Plant3dShared.Bindings;
|
||||
using Speckle.Connectors.Plant3dShared.Operations.Send;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Plant3dShared.DependencyInjection;
|
||||
|
||||
public static class Plant3dConnectorModule
|
||||
{
|
||||
public static void AddPlant3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
|
||||
// add send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Plant3dRootObjectBuilder>();
|
||||
serviceCollection.AddSingleton<IBinding, Plant3dSendBinding>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Plant3dShared.Operations.Send;
|
||||
|
||||
public sealed class Plant3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
|
||||
public Plant3dRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
IRootToSpeckleConverter converter,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
converterSettings,
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Speckle.Connectors.Plant3dShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Plant3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Plant3dRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Plant3dSendBinding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<Import Project="Speckle.Connectors.Plant3dShared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -96,7 +96,7 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
var typeKey = (ModelObjectType)objectType[i];
|
||||
var typeName = typeKey.ToString();
|
||||
encodedIds.Add(ObjectIdentifier.Encode(objectType[i], objectName[i]));
|
||||
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
|
||||
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1;
|
||||
}
|
||||
var summary =
|
||||
encodedIds.Count == 0
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.Operations.Send.Settings;
|
||||
using Speckle.Connectors.CSiShared.Settings;
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
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.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Bindings;
|
||||
|
||||
@@ -26,97 +21,72 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
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 IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<CsiSharedSendBinding> _logger;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly ICsiConversionSettingsFactory _csiConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
|
||||
private readonly ToSpeckleSettingsManager _toSpeckleSettingsManager;
|
||||
|
||||
public CsiSharedSendBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
ICancellationManager cancellationManager,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<CsiSharedSendBinding> logger,
|
||||
ICsiConversionSettingsFactory csiConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ICsiApplicationService csiApplicationService
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory,
|
||||
ToSpeckleSettingsManager toSpeckleSettingsManager
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
_csiConversionSettingsFactory = csiConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_activityFactory = activityFactory;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
_sendOperationManagerFactory = sendOperationManagerFactory;
|
||||
_toSpeckleSettingsManager = toSpeckleSettingsManager;
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
public List<ICardSetting> GetSendSettings() =>
|
||||
[new LoadCaseCombinationSetting([], _csiApplicationService.SapModel), new ResultTypeSetting([])];
|
||||
|
||||
public async Task Send(string modelCardId)
|
||||
{
|
||||
using var activity = _activityFactory.Start();
|
||||
|
||||
try
|
||||
{
|
||||
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
|
||||
using var manager = _sendOperationManagerFactory.Create();
|
||||
var (fileName, fileSizeBytes) = GetFileInfo();
|
||||
await manager.Process(
|
||||
Commands,
|
||||
modelCardId,
|
||||
(sp, card) =>
|
||||
{
|
||||
throw new InvalidOperationException("No publish model card was found.");
|
||||
}
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
|
||||
.Initialize(_csiConversionSettingsFactory.Create(_csiApplicationService.SapModel));
|
||||
sp.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
|
||||
.Initialize(
|
||||
_csiConversionSettingsFactory.Create(
|
||||
_csiApplicationService.SapModel,
|
||||
_toSpeckleSettingsManager.GetLoadCasesAndCombinations(card),
|
||||
_toSpeckleSettingsManager.GetResultTypes(card)
|
||||
)
|
||||
);
|
||||
},
|
||||
card => card.SendFilter.NotNull().RefreshObjectIds().Select(DecodeObjectIdentifier).ToList(),
|
||||
fileName,
|
||||
fileSizeBytes
|
||||
);
|
||||
}
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
List<ICsiWrapper> wrappers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(DecodeObjectIdentifier)
|
||||
.ToList();
|
||||
|
||||
if (wrappers.Count == 0)
|
||||
{
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
|
||||
.Execute(
|
||||
wrappers,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
private (string? fileName, long? fileBytes) GetFileInfo()
|
||||
{
|
||||
string fullPath = _csiApplicationService.SapModel.GetModelFilename(true);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(fullPath);
|
||||
return (fileInfo.Name, fileInfo.Length);
|
||||
}
|
||||
|
||||
private ICsiWrapper DecodeObjectIdentifier(string encodedId)
|
||||
|
||||
@@ -5,7 +5,7 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Helpers;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
@@ -82,14 +82,18 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
ModelPathHash = Crypt.Md5(_csiApplicationService.SapModel.GetModelFilename(), length: 32);
|
||||
ModelPathHash = Md5.GetString(_csiApplicationService.SapModel.GetModelFilename());
|
||||
HostAppUserDataPath = Path.Combine(
|
||||
SpecklePathProvider.UserSpeckleFolderPath,
|
||||
"ConnectorsFileData",
|
||||
_speckleApplication.Slug
|
||||
);
|
||||
DocumentStateFile = Path.Combine(HostAppUserDataPath, $"{ModelPathHash}.json");
|
||||
_logger.LogDebug($"Paths set - Hash: {ModelPathHash}, File: {DocumentStateFile}");
|
||||
_logger.LogDebug(
|
||||
"Paths set - Hash: {ModelPathHash}, File: {DocumentStateFile}",
|
||||
ModelPathHash,
|
||||
DocumentStateFile
|
||||
);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
|
||||
@@ -20,23 +20,8 @@ public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
GetMaterialName(sectionName, properties);
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties) =>
|
||||
GetSectionProperties(sectionName, properties);
|
||||
GetPropertyModifiers(sectionName, properties);
|
||||
}
|
||||
|
||||
private void GetMaterialName(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
// get material name
|
||||
string materialName = string.Empty;
|
||||
_settingsStore.Current.SapModel.PropFrame.GetMaterial(sectionName, ref materialName);
|
||||
|
||||
// append to General Data of properties dictionary
|
||||
Dictionary<string, object?> generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["Material"] = materialName;
|
||||
}
|
||||
|
||||
private void GetSectionProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
@@ -69,47 +54,20 @@ public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
|
||||
ref radiusOfGyrationAboutMinorAxis
|
||||
);
|
||||
|
||||
string distanceUnit = _settingsStore.Current.SpeckleUnits;
|
||||
string areaUnit = $"{distanceUnit}²"; // // TODO: Formalize this better
|
||||
string modulusUnit = $"{distanceUnit}³"; // // TODO: Formalize this better
|
||||
string inertiaUnit = $"{distanceUnit}\u2074"; // TODO: Formalize this better
|
||||
|
||||
Dictionary<string, object?> mechanicalProperties = properties.EnsureNested(
|
||||
SectionPropertyCategory.SECTION_PROPERTIES
|
||||
);
|
||||
mechanicalProperties.AddWithUnits("Area", crossSectionalArea, areaUnit);
|
||||
mechanicalProperties.AddWithUnits("As2", shearAreaInMajorAxisDirection, areaUnit);
|
||||
mechanicalProperties.AddWithUnits("As3", shearAreaInMinorAxisDirection, areaUnit);
|
||||
mechanicalProperties.AddWithUnits("J", torsionalConstant, inertiaUnit);
|
||||
mechanicalProperties.AddWithUnits("I22", momentOfInertiaAboutMajorAxis, inertiaUnit);
|
||||
mechanicalProperties.AddWithUnits("I33", momentOfInertiaAboutMinorAxis, inertiaUnit);
|
||||
mechanicalProperties.AddWithUnits("S22", sectionModulusAboutMajorAxis, modulusUnit);
|
||||
mechanicalProperties.AddWithUnits("S33", sectionModulusAboutMinorAxis, modulusUnit);
|
||||
mechanicalProperties.AddWithUnits("Z22", plasticModulusAboutMajorAxis, modulusUnit);
|
||||
mechanicalProperties.AddWithUnits("Z33", plasticModulusAboutMinorAxis, modulusUnit);
|
||||
mechanicalProperties.AddWithUnits("R22", radiusOfGyrationAboutMajorAxis, distanceUnit);
|
||||
mechanicalProperties.AddWithUnits("R33", radiusOfGyrationAboutMinorAxis, distanceUnit);
|
||||
}
|
||||
|
||||
private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
double[] stiffnessModifiersArray = [];
|
||||
_settingsStore.Current.SapModel.PropFrame.GetModifiers(sectionName, ref stiffnessModifiersArray);
|
||||
|
||||
Dictionary<string, object?> modifiers =
|
||||
new()
|
||||
{
|
||||
["Cross-section (Axial) Area"] = stiffnessModifiersArray[0],
|
||||
["Shear Area in 2 Direction"] = stiffnessModifiersArray[1],
|
||||
["Shear Area in 3 Direction"] = stiffnessModifiersArray[2],
|
||||
["Torsional Constant"] = stiffnessModifiersArray[3],
|
||||
["Moment of Inertia about 2 Axis"] = stiffnessModifiersArray[4],
|
||||
["Moment of Inertia about 3 Axis"] = stiffnessModifiersArray[5],
|
||||
["Mass"] = stiffnessModifiersArray[6],
|
||||
["Weight"] = stiffnessModifiersArray[7],
|
||||
};
|
||||
|
||||
Dictionary<string, object?> generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["Modifiers"] = modifiers;
|
||||
mechanicalProperties.Add("Area", crossSectionalArea);
|
||||
mechanicalProperties.Add("As2", shearAreaInMajorAxisDirection);
|
||||
mechanicalProperties.Add("As3", shearAreaInMinorAxisDirection);
|
||||
mechanicalProperties.Add("J", torsionalConstant);
|
||||
mechanicalProperties.Add("I22", momentOfInertiaAboutMajorAxis);
|
||||
mechanicalProperties.Add("I33", momentOfInertiaAboutMinorAxis);
|
||||
mechanicalProperties.Add("S22", sectionModulusAboutMajorAxis);
|
||||
mechanicalProperties.Add("S33", sectionModulusAboutMinorAxis);
|
||||
mechanicalProperties.Add("Z22", plasticModulusAboutMajorAxis);
|
||||
mechanicalProperties.Add("Z33", plasticModulusAboutMinorAxis);
|
||||
mechanicalProperties.Add("R22", radiusOfGyrationAboutMajorAxis);
|
||||
mechanicalProperties.Add("R33", radiusOfGyrationAboutMinorAxis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
/// Currently, all material property extraction can happen on a CsiShared level which simplifies things a lot.
|
||||
/// Properties depend on the directional symmetry of the material, hence the switch statements.
|
||||
/// </remarks>
|
||||
public class CsiMaterialPropertyExtractor
|
||||
public class CsiMaterialPropertyExtractor : IMaterialPropertyExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// Property strings for all mechanical properties, used by numerous methods.
|
||||
@@ -35,11 +35,11 @@ public class CsiMaterialPropertyExtractor
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
public void ExtractProperties(string materialName, Dictionary<string, object?> properties)
|
||||
public void ExtractProperties(string name, Dictionary<string, object?> properties)
|
||||
{
|
||||
GetGeneralProperties(materialName, properties);
|
||||
GetWeightAndMassProperties(materialName, properties); // TODO: Add units
|
||||
GetMechanicalProperties(materialName, properties); // TODO: Add units
|
||||
GetGeneralProperties(name, properties);
|
||||
GetWeightAndMassProperties(name, properties);
|
||||
GetMechanicalProperties(name, properties);
|
||||
}
|
||||
|
||||
private void GetGeneralProperties(string materialName, Dictionary<string, object?> properties)
|
||||
@@ -76,7 +76,7 @@ public class CsiMaterialPropertyExtractor
|
||||
ref massPerUnitVolume
|
||||
);
|
||||
|
||||
var weightAndMass = properties.EnsureNested("Weight and Mass");
|
||||
var weightAndMass = properties.EnsureNested(SectionPropertyCategory.WEIGHT_AND_MASS);
|
||||
weightAndMass["Weight per Unit Volume"] = weightPerUnitVolume;
|
||||
weightAndMass["Mass per Unit Volume"] = massPerUnitVolume;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public class CsiMaterialPropertyExtractor
|
||||
_ => throw new ArgumentException($"Unknown symmetry type: {materialDirectionalSymmetryKey}")
|
||||
};
|
||||
|
||||
var mechanicalProperties = properties.EnsureNested("Mechanical Properties");
|
||||
var mechanicalProperties = properties.EnsureNested(SectionPropertyCategory.MECHANICAL_DATA);
|
||||
mechanicalProperties["Directional Symmetry Type"] = materialDirectionalSymmetryValue.ToString();
|
||||
|
||||
GetMechanicalPropertiesByType(materialName, materialDirectionalSymmetryValue, mechanicalProperties);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Converters.CSiShared.ToSpeckle.Helpers;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
public class CsiResultsExtractorFactory
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public CsiResultsExtractorFactory(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public IApplicationResultsExtractor GetExtractor(string resultsKey) =>
|
||||
resultsKey switch
|
||||
{
|
||||
ResultsKey.BASE_REACT => _serviceProvider.GetRequiredService<CsiBaseReactResultsExtractor>(),
|
||||
ResultsKey.FRAME_FORCES => _serviceProvider.GetRequiredService<CsiFrameForceResultsExtractor>(),
|
||||
ResultsKey.JOINT_REACT => _serviceProvider.GetRequiredService<CsiJointReactResultsExtractor>(),
|
||||
ResultsKey.MODAL_PERIOD => _serviceProvider.GetRequiredService<CsiModalPeriodExtractor>(),
|
||||
ResultsKey.PIER_FORCES => _serviceProvider.GetRequiredService<CsiPierForceResultsExtractor>(),
|
||||
ResultsKey.SPANDREL_FORCES => _serviceProvider.GetRequiredService<CsiSpandrelForceResultsExtractor>(),
|
||||
ResultsKey.STORY_DRIFTS => _serviceProvider.GetRequiredService<CsiStoryDriftsResultsExtractor>(),
|
||||
ResultsKey.STORY_FORCES => _serviceProvider.GetRequiredService<CsiStoryForceResultsExtractor>(),
|
||||
_ => throw new InvalidOperationException($"{resultsKey} not accounted for in CsiResultsExtractorFactory")
|
||||
};
|
||||
}
|
||||