Compare commits
109 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 509d3275af | |||
| c562190973 |
@@ -7,12 +7,12 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
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)
|
||||
|
||||
@@ -28,12 +28,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
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)
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ jobs:
|
||||
file_version: ${{ steps.set-version.outputs.file_version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
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)
|
||||
|
||||
@@ -83,12 +83,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
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)
|
||||
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +292,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -336,18 +336,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -357,14 +357,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +292,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -336,18 +336,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -357,14 +357,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -293,7 +293,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,9 +210,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -244,7 +244,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -288,18 +288,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -307,14 +307,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -210,9 +210,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -244,7 +244,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -288,18 +288,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -307,14 +307,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+9
@@ -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"/>
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +302,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,18 +346,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -367,14 +367,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +302,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,18 +346,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -367,14 +367,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,7 +302,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,18 +346,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -367,14 +367,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,9 +219,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -254,7 +254,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -298,18 +298,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -317,14 +317,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -219,9 +219,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -254,7 +254,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -298,18 +298,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -317,14 +317,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -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,6 +1,8 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
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;
|
||||
@@ -23,6 +25,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly ICsiConversionSettingsFactory _csiConversionSettingsFactory;
|
||||
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
|
||||
private readonly ToSpeckleSettingsManager _toSpeckleSettingsManager;
|
||||
|
||||
public CsiSharedSendBinding(
|
||||
IBrowserBridge parent,
|
||||
@@ -30,7 +33,8 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
ICancellationManager cancellationManager,
|
||||
ICsiConversionSettingsFactory csiConversionSettingsFactory,
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
ISendOperationManagerFactory sendOperationManagerFactory,
|
||||
ToSpeckleSettingsManager toSpeckleSettingsManager
|
||||
)
|
||||
{
|
||||
_sendFilters = sendFilters.ToList();
|
||||
@@ -40,11 +44,13 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
_csiConversionSettingsFactory = csiConversionSettingsFactory;
|
||||
_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)
|
||||
{
|
||||
@@ -52,9 +58,17 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
await manager.Process(
|
||||
Commands,
|
||||
modelCardId,
|
||||
(sp, _) =>
|
||||
(sp, card) =>
|
||||
{
|
||||
sp.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
|
||||
.Initialize(_csiConversionSettingsFactory.Create(_csiApplicationService.SapModel)),
|
||||
.Initialize(
|
||||
_csiConversionSettingsFactory.Create(
|
||||
_csiApplicationService.SapModel,
|
||||
_toSpeckleSettingsManager.GetLoadCasesAndCombinations(card),
|
||||
_toSpeckleSettingsManager.GetResultTypes(card)
|
||||
)
|
||||
);
|
||||
},
|
||||
card => card.SendFilter.NotNull().RefreshObjectIds().Select(DecodeObjectIdentifier).ToList()
|
||||
);
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
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.PIER_FORCES => _serviceProvider.GetRequiredService<CsiPierForceResultsExtractor>(),
|
||||
ResultsKey.SPANDREL_FORCES => _serviceProvider.GetRequiredService<CsiSpandrelForceResultsExtractor>(),
|
||||
ResultsKey.STORY_DRIFTS => _serviceProvider.GetRequiredService<CsiStoryDriftsResultsExtractor>(),
|
||||
_ => throw new InvalidOperationException($"{resultsKey} not accounted for in CsiResultsExtractorFactory")
|
||||
};
|
||||
}
|
||||
+52
-1
@@ -4,9 +4,11 @@ using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Extensions;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
@@ -37,6 +39,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
private readonly ILogger<CsiRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly AnalysisResultsExtractor _analysisResultsExtractor;
|
||||
|
||||
public CsiRootObjectBuilder(
|
||||
IRootToSpeckleConverter rootToSpeckleConverter,
|
||||
@@ -46,7 +49,8 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
ISectionUnpacker sectionUnpacker,
|
||||
ILogger<CsiRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ICsiApplicationService csiApplicationService
|
||||
ICsiApplicationService csiApplicationService,
|
||||
AnalysisResultsExtractor analysisResultsExtractor
|
||||
)
|
||||
{
|
||||
_converterSettings = converterSettings;
|
||||
@@ -57,6 +61,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
_analysisResultsExtractor = analysisResultsExtractor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -112,6 +117,34 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
rootObjectCollection[ProxyKeys.SECTION] = _sectionUnpacker.UnpackSections().ToList();
|
||||
}
|
||||
|
||||
// Extract analysis results (if applicable)
|
||||
// NOTE: objectSelectionSummary used to extract results for objects being published ONLY
|
||||
// NOTE: etabs is complicated and we can't get specifics from original selection
|
||||
var objectSelectionSummary = GetObjectSummary(csiObjects);
|
||||
var selectedCasesAndCombinations = _converterSettings.Current.SelectedLoadCasesAndCombinations;
|
||||
var requestedResultTypes = _converterSettings.Current.SelectedResultTypes;
|
||||
|
||||
if (selectedCasesAndCombinations?.Count > 0)
|
||||
{
|
||||
if (requestedResultTypes == null || requestedResultTypes.Count == 0)
|
||||
{
|
||||
throw new SpeckleException(
|
||||
"No result type input for the requested load cases and combinations. Adjust publish settings."
|
||||
);
|
||||
}
|
||||
|
||||
if (!_csiApplicationService.SapModel.GetModelIsLocked())
|
||||
{
|
||||
throw new SpeckleException("Model unlocked. No access to analysis results.");
|
||||
}
|
||||
|
||||
var analysisResults = _analysisResultsExtractor.ExtractAnalysisResults(
|
||||
selectedCasesAndCombinations,
|
||||
requestedResultTypes,
|
||||
objectSelectionSummary
|
||||
);
|
||||
rootObjectCollection["analysisResults"] = analysisResults;
|
||||
}
|
||||
return new RootObjectBuilderResult(rootObjectCollection, results);
|
||||
}
|
||||
|
||||
@@ -158,4 +191,22 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a summary of object types and their associated names from the collection of CSI wrappers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A summary of object names for each object type is needed for getting analysis results of the selected objects only.
|
||||
/// During object conversion, however, we lose the selection (like a clear selection)(presumably because of other api calls).
|
||||
/// This has to be recreated since GetSelection() return type is bound by the interface.
|
||||
/// The LINQ-based implementation is computationally inexpensive as it operates on an already-loaded collection without additional API calls.
|
||||
/// Also, we don't want to rely on user selection remaining active, what if someone re-publishes using model card cache?
|
||||
/// </remarks>
|
||||
private Dictionary<ModelObjectType, List<string>> GetObjectSummary(IReadOnlyList<ICsiWrapper> csiObjects) =>
|
||||
csiObjects
|
||||
.GroupBy(csiObject => csiObject.ObjectType)
|
||||
.ToDictionary(
|
||||
group => group.Key, // ModelObjectType (FRAME, JOINT, etc.)
|
||||
group => group.Select(obj => obj.Name).ToList() // Extract Name from each ICsiWrapper and convert to List<string>
|
||||
);
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Newtonsoft.Json.Linq;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Operations.Send.Settings;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly Dictionary<string, List<string>?> _loadCaseCombinationCache = new();
|
||||
private readonly Dictionary<string, List<string>?> _resultTypeCache = new();
|
||||
|
||||
public ToSpeckleSettingsManager(ISendConversionCache sendConversionCache)
|
||||
{
|
||||
_sendConversionCache = sendConversionCache;
|
||||
}
|
||||
|
||||
public List<string> GetLoadCasesAndCombinations(SenderModelCard modelCard)
|
||||
{
|
||||
var setting = modelCard.Settings?.FirstOrDefault(s => s.Id == "loadCasesAndCombinations");
|
||||
var returnValue = (setting?.Value as JArray)?.Select(x => x.ToString()).ToList() ?? [];
|
||||
|
||||
if (_loadCaseCombinationCache.TryGetValue(modelCard.ModelCardId.NotNull(), out List<string>? previousValue))
|
||||
{
|
||||
if (!AreListsEqual(previousValue, returnValue))
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
_loadCaseCombinationCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public List<string> GetResultTypes(SenderModelCard modelCard)
|
||||
{
|
||||
var setting = modelCard.Settings?.FirstOrDefault(s => s.Id == "resultTypes");
|
||||
var returnValue = (setting?.Value as JArray)?.Select(x => x.ToString()).ToList() ?? [];
|
||||
|
||||
if (_resultTypeCache.TryGetValue(modelCard.ModelCardId.NotNull(), out List<string>? previousValue))
|
||||
{
|
||||
if (!AreListsEqual(previousValue, returnValue))
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
_resultTypeCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private static bool AreListsEqual(List<string>? list1, List<string>? list2)
|
||||
{
|
||||
if (list1 == null && list2 == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (list1 == null || list2 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return list1.Count == list2.Count && list1.OrderBy(x => x).SequenceEqual(list2.OrderBy(x => x));
|
||||
}
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().RefreshObjectIds() : [];
|
||||
_sendConversionCache.EvictObjects(objectIds);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ using Speckle.Connectors.CSiShared.Builders;
|
||||
using Speckle.Connectors.CSiShared.Filters;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Connectors.CSiShared.Operations.Send.Settings;
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
@@ -44,13 +46,18 @@ public static class ServiceRegistration
|
||||
services.AddScoped<SendOperation<ICsiWrapper>>();
|
||||
|
||||
services.AddScoped<CsiMaterialPropertyExtractor>();
|
||||
services.AddScoped<CsiResultsExtractorFactory>();
|
||||
services.AddScoped<MaterialUnpacker>();
|
||||
services.AddScoped<IFrameSectionPropertyExtractor, CsiFrameSectionPropertyExtractor>();
|
||||
services.AddScoped<IShellSectionPropertyExtractor, CsiShellSectionPropertyExtractor>();
|
||||
services.AddScoped<AnalysisResultsExtractor>();
|
||||
|
||||
// add converter caches
|
||||
services.AddScoped<CsiToSpeckleCacheSingleton>();
|
||||
|
||||
// add settings manager
|
||||
services.AddScoped<ToSpeckleSettingsManager>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Settings;
|
||||
|
||||
public class LoadCaseCombinationSetting(List<string> values, cSapModel sapModel) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "loadCasesAndCombinations";
|
||||
public string? Title { get; set; } = "Load Cases & Combinations";
|
||||
public string? Type { get; set; } = "array";
|
||||
public object? Value { get; set; } = values;
|
||||
public List<string>? Enum { get; set; } = LoadCaseHelper.GetLoadCasesAndCombinations(sapModel);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Settings;
|
||||
|
||||
public class ResultTypeSetting(List<string> values) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "resultTypes";
|
||||
public string? Title { get; set; } = "Result Type";
|
||||
public string? Type { get; set; } = "array";
|
||||
public object? Value { get; set; } = values;
|
||||
public List<string>? Enum { get; set; } = ResultsKey.All.OrderBy(x => x).ToList();
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\CsiSharedSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\CsiResultsExtractorFactory.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\MaterialUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiSendCollectionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\CsiFrameSectionPropertyExtractor.cs" />
|
||||
@@ -27,12 +28,17 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\ISectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\ISectionUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\CsiRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\CsiPluginBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleFormBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsing.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiApplicationService.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiDocumentModelStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Settings\LoadCaseCombinationSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Settings\ResultTypeSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Utils\LoadCaseHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Utils\AnalysisResultsExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Utils\ObjectIdentifiers.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Utils;
|
||||
|
||||
public class AnalysisResultsExtractor
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _converterSettingsStore;
|
||||
private readonly CsiResultsExtractorFactory _resultsExtractorFactory;
|
||||
|
||||
public AnalysisResultsExtractor(
|
||||
IConverterSettingsStore<CsiConversionSettings> converterSettingsStore,
|
||||
CsiResultsExtractorFactory resultsExtractorFactory
|
||||
)
|
||||
{
|
||||
_converterSettingsStore = converterSettingsStore;
|
||||
_resultsExtractorFactory = resultsExtractorFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts complete analysis results including units retrieval, load case configuration, and results extraction.
|
||||
/// Assumes inputs have been validated by caller.
|
||||
/// </summary>
|
||||
public Base ExtractAnalysisResults(
|
||||
List<string> selectedCasesAndCombinations,
|
||||
List<string> requestedResultTypes,
|
||||
Dictionary<ModelObjectType, List<string>> objectSelectionSummary
|
||||
)
|
||||
{
|
||||
// Step 1: get analysis units
|
||||
var analysisResults = CreateAnalysisResultsWithUnits();
|
||||
|
||||
// Step 2: configure and validate load cases
|
||||
ConfigureAndValidateSelectedLoadCases(selectedCasesAndCombinations);
|
||||
|
||||
// Step 3: extract results using clean factory pattern
|
||||
ExtractResults(requestedResultTypes, objectSelectionSummary, analysisResults);
|
||||
|
||||
return analysisResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a Base object and pre-populates it with the models defined force units.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="SpeckleException"></exception>
|
||||
private Base CreateAnalysisResultsWithUnits()
|
||||
{
|
||||
var forceUnit = eForce.NotApplicable;
|
||||
var lengthUnit = eLength.NotApplicable;
|
||||
var temperatureUnit = eTemperature.NotApplicable;
|
||||
|
||||
int success = _converterSettingsStore.Current.SapModel.GetDatabaseUnits_2(
|
||||
ref forceUnit,
|
||||
ref lengthUnit,
|
||||
ref temperatureUnit
|
||||
);
|
||||
|
||||
if (success != 0)
|
||||
{
|
||||
throw new SpeckleException("Failed to retrieve units for analysis results");
|
||||
}
|
||||
|
||||
return new Base
|
||||
{
|
||||
["forceUnit"] = forceUnit.ToString(),
|
||||
["lengthUnit"] = lengthUnit.ToString(),
|
||||
["temperatureUnit"] = temperatureUnit.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private void ExtractResults(
|
||||
List<string> requestedResultTypes,
|
||||
Dictionary<ModelObjectType, List<string>> objectSelectionSummary,
|
||||
Base analysisResults
|
||||
)
|
||||
{
|
||||
foreach (var resultType in requestedResultTypes)
|
||||
{
|
||||
var extractor = _resultsExtractorFactory.GetExtractor(resultType);
|
||||
objectSelectionSummary.TryGetValue(extractor.TargetObjectType, out var objectNames);
|
||||
analysisResults[extractor.ResultsKey] = extractor.GetResults(objectNames);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for two things. Firstly, we need to setup the results so that only the requested cases and combinations
|
||||
/// are published. Secondly, we need to ensure that the requested cases and combinations are actually run.
|
||||
/// </summary>
|
||||
private void ConfigureAndValidateSelectedLoadCases(List<string> selectedLoadCases)
|
||||
{
|
||||
// step 1: configure load cases for output
|
||||
ConfigureSelectedLoadCases(selectedLoadCases);
|
||||
|
||||
// step 2: validate they are complete (throws on failure)
|
||||
ValidateSelectedCasesAreComplete(selectedLoadCases);
|
||||
}
|
||||
|
||||
private void ConfigureSelectedLoadCases(List<string> selectedLoadCases)
|
||||
{
|
||||
// deselect all load cases and combos
|
||||
_converterSettingsStore.Current.SapModel.Results.Setup.DeselectAllCasesAndCombosForOutput();
|
||||
|
||||
// ui presents cases and combinations as a flat list. we need to distinguish if the string is a case or combo
|
||||
// do this by seeing if the string is within the list of defined cases
|
||||
// typically defined load cases << defined load combinations, so this approach should be more efficient
|
||||
int numberOfLoadCases = 0;
|
||||
string[] loadCaseNames = [];
|
||||
_converterSettingsStore.Current.SapModel.LoadCases.GetNameList(ref numberOfLoadCases, ref loadCaseNames);
|
||||
|
||||
// set user selected combos to true (i.e. to export)
|
||||
foreach (var selectedLoadCase in selectedLoadCases)
|
||||
{
|
||||
int success = loadCaseNames.Contains(selectedLoadCase)
|
||||
? _converterSettingsStore.Current.SapModel.Results.Setup.SetCaseSelectedForOutput(selectedLoadCase)
|
||||
: _converterSettingsStore.Current.SapModel.Results.Setup.SetComboSelectedForOutput(selectedLoadCase);
|
||||
|
||||
// ui should only present valid options
|
||||
// `AnalysisResultsExtractor` only fetches load cases and load combinations (not patterns), so this should never throw
|
||||
if (success != 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to set {selectedLoadCase} for output.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateSelectedCasesAreComplete(List<string> selectedCasesAndCombinations)
|
||||
{
|
||||
// get status for all load cases (combinations not included in this API call)
|
||||
int numberItems = 0;
|
||||
string[] caseNames = [];
|
||||
int[] statuses = [];
|
||||
|
||||
int result = _converterSettingsStore.Current.SapModel.Analyze.GetCaseStatus(
|
||||
ref numberItems,
|
||||
ref caseNames,
|
||||
ref statuses
|
||||
);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
throw new SpeckleException("Failed to retrieve load case status from model.");
|
||||
}
|
||||
|
||||
// build lookup dictionary for load cases only
|
||||
var caseStatusLookup = caseNames
|
||||
.Zip(statuses, (name, status) => new { name, status })
|
||||
.ToDictionary(x => x.name, x => x.status);
|
||||
|
||||
// separate selected items into cases and combinations
|
||||
var selectedCases = selectedCasesAndCombinations.Where(item => caseStatusLookup.ContainsKey(item)).ToList();
|
||||
var selectedCombinations = selectedCasesAndCombinations.Except(selectedCases).ToList();
|
||||
|
||||
// validate load cases status
|
||||
var notFinishedCases = new List<string>();
|
||||
foreach (var caseName in selectedCases)
|
||||
{
|
||||
int status = caseStatusLookup[caseName];
|
||||
if (status != 4) // 1 = Not run, 2 = Could not start, 3 = Not finished, 4 = Finished
|
||||
{
|
||||
notFinishedCases.Add($"{caseName}");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Validate load combinations status
|
||||
// for now, assume combinations are valid if we can't validate them
|
||||
if (selectedCombinations.Count != 0)
|
||||
{
|
||||
// combinations validation not implemented - assuming they're valid for now
|
||||
// it'll get complicated, we can't get the status of a combination, so we need to check the constituent cases
|
||||
}
|
||||
|
||||
if (notFinishedCases.Count != 0)
|
||||
{
|
||||
string errorMessage =
|
||||
$"Analysis not complete for load cases: {string.Join(", ", notFinishedCases)}. Run analysis first.";
|
||||
throw new SpeckleException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
namespace Speckle.Connectors.CSiShared.Utils;
|
||||
|
||||
public static class LoadCaseHelper
|
||||
{
|
||||
public static List<string> GetLoadCasesAndCombinations(cSapModel sapModel)
|
||||
{
|
||||
var loadCasesAndCombos = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
// Check if model is loaded to prevent crashes
|
||||
var modelFilename = sapModel.GetModelFilename();
|
||||
if (string.IsNullOrEmpty(modelFilename))
|
||||
{
|
||||
return loadCasesAndCombos; // Return empty list if no model
|
||||
}
|
||||
|
||||
// Get Load Cases
|
||||
int numberItems = 0;
|
||||
string[]? names = null;
|
||||
|
||||
int ret = sapModel.LoadCases.GetNameList(ref numberItems, ref names);
|
||||
if (ret == 0 && names != null)
|
||||
{
|
||||
for (int i = 0; i < numberItems; i++)
|
||||
{
|
||||
loadCasesAndCombos.Add(names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Load Combinations
|
||||
numberItems = 0;
|
||||
names = null;
|
||||
ret = sapModel.RespCombo.GetNameList(ref numberItems, ref names);
|
||||
if (ret == 0 && names != null)
|
||||
{
|
||||
for (int i = 0; i < numberItems; i++)
|
||||
{
|
||||
loadCasesAndCombos.Add(names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Runtime.InteropServices.COMException)
|
||||
{
|
||||
// Return empty list on COM errors to prevent crashes
|
||||
return new List<string>();
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
// Return empty list on invalid operations to prevent crashes
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
return loadCasesAndCombos.Distinct().OrderBy(x => x).ToList();
|
||||
}
|
||||
}
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs21": {
|
||||
@@ -335,18 +335,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -356,14 +356,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,9 +210,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -236,7 +236,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs22": {
|
||||
@@ -286,18 +286,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -305,14 +305,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2020": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2021": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2022": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2023": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -285,7 +285,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2024": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -265,9 +265,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -291,7 +291,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2025": {
|
||||
@@ -337,18 +337,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -358,14 +358,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -266,9 +266,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +292,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2026": {
|
||||
@@ -339,18 +339,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -360,14 +360,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
+3
-1
@@ -73,6 +73,7 @@ public class NavisworksSendBinding : ISendBinding
|
||||
new IncludeInternalPropertiesSetting(false),
|
||||
new ConvertHiddenElementsSetting(false),
|
||||
new PreserveModelHierarchySetting(false),
|
||||
new RevitCategoryMappingSetting(false)
|
||||
];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
@@ -93,7 +94,8 @@ public class NavisworksSendBinding : ISendBinding
|
||||
visualRepresentationMode: _toSpeckleSettingsManagerNavisworks.GetVisualRepresentationMode(modelCard),
|
||||
convertHiddenElements: _toSpeckleSettingsManagerNavisworks.GetConvertHiddenElements(modelCard),
|
||||
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard),
|
||||
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard)
|
||||
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard),
|
||||
mappingToRevitCategories: _toSpeckleSettingsManagerNavisworks.GetMappingToRevitCategories(modelCard)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send.Settings;
|
||||
|
||||
public class RevitCategoryMappingSetting(bool value) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "mappingToRevitCategories";
|
||||
public string? Title { get; set; } = "Map to Revit Categories";
|
||||
public string? Type { get; set; } = "boolean";
|
||||
public List<string>? Enum { get; set; }
|
||||
public object? Value { get; set; } = value;
|
||||
}
|
||||
+23
@@ -18,6 +18,7 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
private readonly Dictionary<string, bool?> _convertHiddenElementsCache = [];
|
||||
private readonly Dictionary<string, bool?> _includeInternalPropertiesCache = [];
|
||||
private readonly Dictionary<string, bool?> _preserveModelHierarchyCache = [];
|
||||
private readonly Dictionary<string, bool?> _revitCategoryMappingCache = [];
|
||||
|
||||
public ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
|
||||
{
|
||||
@@ -78,6 +79,28 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
return origin;
|
||||
}
|
||||
|
||||
public bool GetMappingToRevitCategories(SenderModelCard modelCard)
|
||||
{
|
||||
if (modelCard == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelCard));
|
||||
}
|
||||
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "mappingToRevitCategories")?.Value as bool?;
|
||||
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_revitCategoryMappingCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
|
||||
{
|
||||
if (previousValue != returnValue)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
|
||||
_revitCategoryMappingCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public bool GetConvertHiddenElements(SenderModelCard modelCard)
|
||||
{
|
||||
if (modelCard == null)
|
||||
|
||||
+2
-1
@@ -25,10 +25,11 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\GeometryNodeMerger.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksHierarchyBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksRootObjectBuilder.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ConvertHiddenEleementsSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ConvertHiddenElementsSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\IncludeInternalPropertiesSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\OriginModeSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\PreserveModelHierarchySetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\RevitCategoryMapping.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManagerNavisworks.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\VisualRepresentationSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSelectionFilter.cs"/>
|
||||
|
||||
@@ -281,9 +281,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -306,7 +306,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -351,11 +351,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -366,9 +366,9 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -378,14 +378,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,9 +281,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -306,7 +306,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -351,11 +351,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -366,9 +366,9 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -378,14 +378,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,9 +281,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -306,7 +306,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -351,11 +351,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -366,9 +366,9 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -378,14 +378,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,9 +226,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -251,7 +251,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -296,11 +296,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -311,9 +311,9 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -321,14 +321,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -219,9 +219,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -244,7 +244,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2026": {
|
||||
@@ -280,11 +280,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -295,9 +295,9 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
@@ -305,14 +305,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -72,6 +72,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
return new DocumentInfo("", "", "") { Message = "Family environment files not supported by Speckle." };
|
||||
}
|
||||
|
||||
//should this use the Hashcode of the document instead of something like CreationGUID?
|
||||
var info = new DocumentInfo(doc.PathName, doc.Title, doc.GetHashCode().ToString());
|
||||
|
||||
return info;
|
||||
|
||||
@@ -216,12 +216,13 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
newSelectedObjectIds.Add(element.UniqueId);
|
||||
}
|
||||
|
||||
// We update the state on the UI SenderModelCard to prevent potential inconsistencies between hostApp IdMap in sendfilters.
|
||||
await Commands.SetFilterObjectIds(
|
||||
modelCard.ModelCardId.NotNull(),
|
||||
modelCard.SendFilter.IdMap,
|
||||
newSelectedObjectIds
|
||||
);
|
||||
// NOTE: preserve & persist original user selection for selection filter implemented during
|
||||
// [CNX-2400](https://linear.app/speckle/issue/CNX-2400/object-dont-update-on-publish)
|
||||
// NOTE: update with current document for views and categories filter since these represent dynamic queries
|
||||
// View & categories filters self-update their SelectedObjectIds in RefreshObjectIds(), maintaining consistency
|
||||
var objectIds =
|
||||
modelCard.SendFilter is RevitSelectionFilter ? modelCard.SendFilter.SelectedObjectIds : newSelectedObjectIds;
|
||||
await Commands.SetFilterObjectIds(modelCard.ModelCardId.NotNull(), modelCard.SendFilter.IdMap, objectIds);
|
||||
}
|
||||
|
||||
return documentElementContexts;
|
||||
|
||||
@@ -3,48 +3,45 @@ using Autodesk.Revit.DB.ExtensibleStorage;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.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;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.SQLite;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
// POC: should be interfaced out
|
||||
internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
{
|
||||
// POC: move to somewhere central?
|
||||
private static readonly Guid s_revitDocumentStoreId = new("D35B3695-EDC9-4E15-B62A-D3FC2CB83FA3");
|
||||
|
||||
private readonly ILogger<RevitDocumentStore> _logger;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly DocumentModelStorageSchema _documentModelStorageSchema;
|
||||
private readonly IdStorageSchema _idStorageSchema;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ISqLiteJsonCacheManager _jsonCacheManager;
|
||||
|
||||
public RevitDocumentStore(
|
||||
ILogger<DocumentModelStore> logger,
|
||||
IAppIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
IJsonSerializer jsonSerializer,
|
||||
DocumentModelStorageSchema documentModelStorageSchema,
|
||||
IdStorageSchema idStorageSchema,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext,
|
||||
IRevitTask revitTask
|
||||
IRevitTask revitTask,
|
||||
ISqLiteJsonCacheManagerFactory jsonCacheManagerFactory,
|
||||
ILogger<RevitDocumentStore> logger
|
||||
)
|
||||
: base(logger, jsonSerializer)
|
||||
{
|
||||
_jsonCacheManager = jsonCacheManagerFactory.CreateForUser("ConnectorsFileData");
|
||||
_idleManager = idleManager;
|
||||
_revitContext = revitContext;
|
||||
_documentModelStorageSchema = documentModelStorageSchema;
|
||||
_idStorageSchema = idStorageSchema;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_threadContext = threadContext;
|
||||
_logger = logger;
|
||||
|
||||
UIApplication uiApplication = _revitContext.UIApplication.NotNull();
|
||||
|
||||
@@ -101,80 +98,52 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
return;
|
||||
}
|
||||
|
||||
_threadContext
|
||||
.RunOnMain(() =>
|
||||
try
|
||||
{
|
||||
var key = GetKeyForDocument(document);
|
||||
if (key != null)
|
||||
{
|
||||
//if not the same active document then don't save the current cards to a bad document!
|
||||
if (!EnsureActiveDocumentIsSame(document))
|
||||
{
|
||||
return;
|
||||
}
|
||||
using Transaction t = new(document, "Speckle Write State");
|
||||
t.Start();
|
||||
using DataStorage ds = GetSettingsDataStorage(document) ?? DataStorage.Create(document);
|
||||
|
||||
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
|
||||
string serializedModels = Serialize();
|
||||
stateEntity.Set("contents", serializedModels);
|
||||
|
||||
using Entity idEntity = new(_idStorageSchema.GetSchema());
|
||||
idEntity.Set("Id", s_revitDocumentStoreId);
|
||||
|
||||
ds.SetEntity(idEntity);
|
||||
ds.SetEntity(stateEntity);
|
||||
t.Commit();
|
||||
})
|
||||
.FireAndForget();
|
||||
_jsonCacheManager.UpdateObject(key, modelCardState);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
var key = GetKeyForDocument(document);
|
||||
_logger.LogError(ex, "Failed to save model card state for document {DocumentId}", key);
|
||||
}
|
||||
}
|
||||
|
||||
private bool EnsureActiveDocumentIsSame(Document document)
|
||||
private string? GetKeyForDocument(Document doc)
|
||||
{
|
||||
var localDoc = _revitContext.UIApplication?.ActiveUIDocument?.Document;
|
||||
if (localDoc == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return localDoc.Equals(document);
|
||||
string? id = doc?.ProjectInformation?.UniqueId; //ProjectInformation Should only be null for family docs
|
||||
#if REVIT_2024_OR_GREATER
|
||||
id ??= doc.CreationGUID.ToString(); //fallback for family docs
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
{
|
||||
var stateEntity = GetSpeckleEntity(_revitContext.UIApplication?.ActiveUIDocument?.Document);
|
||||
var document = _revitContext.UIApplication?.ActiveUIDocument?.Document;
|
||||
// POC: this can happen? A: Not really, imho (dim) (Adam seyz yes it can if loading also triggers a save)
|
||||
if (document == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var stateEntity = GetSpeckleEntity(document);
|
||||
if (stateEntity == null || !stateEntity.IsValid())
|
||||
{
|
||||
ClearAndSave();
|
||||
return;
|
||||
}
|
||||
|
||||
string modelsString = stateEntity.Get<string>("contents");
|
||||
LoadFromString(modelsString);
|
||||
}
|
||||
|
||||
private DataStorage? GetSettingsDataStorage(Document doc)
|
||||
{
|
||||
using FilteredElementCollector collector = new(doc);
|
||||
FilteredElementCollector dataStorages = collector.OfClass(typeof(DataStorage));
|
||||
|
||||
foreach (Element element in dataStorages)
|
||||
var key = GetKeyForDocument(document);
|
||||
if (key != null)
|
||||
{
|
||||
DataStorage dataStorage = (DataStorage)element;
|
||||
Entity settingIdEntity = dataStorage.GetEntity(_idStorageSchema.GetSchema());
|
||||
if (!settingIdEntity.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Guid id = settingIdEntity.Get<Guid>("Id");
|
||||
if (!id.Equals(s_revitDocumentStoreId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return dataStorage;
|
||||
var state = _jsonCacheManager.GetObject(key);
|
||||
LoadFromString(state);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Entity? GetSpeckleEntity(Document? doc)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class ToHostSettingsManager : IToHostSettingsManager
|
||||
|
||||
public Transform? GetReferencePointSetting(ModelCard modelCard)
|
||||
{
|
||||
var referencePointString = modelCard.Settings?.First(s => s.Id == "referencePoint").Value as string;
|
||||
var referencePointString = modelCard.Settings?.FirstOrDefault(s => s.Id == "referencePoint")?.Value as string;
|
||||
if (
|
||||
referencePointString is not null
|
||||
&& ReferencePointSetting.ReferencePointMap.TryGetValue(
|
||||
|
||||
+52
-2
@@ -2,7 +2,9 @@ using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Converters.RevitShared.Extensions;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
@@ -75,8 +77,8 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
//this used to throw an exception, but we don't want to fail loudly if the view is not found
|
||||
return [];
|
||||
}
|
||||
using var viewCollector = new FilteredElementCollector(_doc, view.Id);
|
||||
var elementsInView = viewCollector.ToElements();
|
||||
|
||||
IEnumerable<Element> elementsInView = GetFilteredElementsForView(view);
|
||||
|
||||
// NOTE: FilteredElementCollector() includes sweeps and reveals from a wall family's definition and includes them as additional objects
|
||||
// on this return. displayValue for Wall already includes these, therefore we end up with duplicate elements on wall sweeps
|
||||
@@ -125,4 +127,52 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
_revitContext = revitContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
}
|
||||
|
||||
// NOTE: Element collector returns parts and source elements even when Parts Visibility is set as "Show Parts" only.
|
||||
// Below function collects list of ids to exclude from final list.
|
||||
private HashSet<ElementId> GetSourceElementIdsToExclude(IEnumerable<Element> elements)
|
||||
{
|
||||
var elementsToExclude = new HashSet<ElementId>();
|
||||
|
||||
foreach (var element in elements)
|
||||
{
|
||||
// check if element is a part
|
||||
if (element.Category?.GetBuiltInCategory() == BuiltInCategory.OST_Parts && element is Part part)
|
||||
{
|
||||
try
|
||||
{
|
||||
// get source element ids from the part
|
||||
var sourceIds = part.GetSourceElementIds();
|
||||
if (sourceIds != null)
|
||||
{
|
||||
foreach (var sourceId in sourceIds)
|
||||
{
|
||||
elementsToExclude.Add(sourceId.HostElementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// silently continue processing other Parts if one fails
|
||||
// this follows the pattern used elsewhere in the codebase
|
||||
}
|
||||
}
|
||||
}
|
||||
return elementsToExclude;
|
||||
}
|
||||
|
||||
private IEnumerable<Element> GetFilteredElementsForView(View view)
|
||||
{
|
||||
using var viewCollector = new FilteredElementCollector(_doc, view.Id);
|
||||
var allElements = viewCollector.ToElements();
|
||||
|
||||
// parts filtering when view is set to show Parts only (and overwrites allElements)
|
||||
if (view.PartsVisibility == PartsVisibility.ShowPartsOnly)
|
||||
{
|
||||
var idsToExclude = GetSourceElementIdsToExclude(allElements);
|
||||
return allElements.Where(e => !idsToExclude.Contains(e.Id));
|
||||
}
|
||||
|
||||
return allElements;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -225,7 +225,16 @@ public class RevitRootObjectBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR) || skippedObjectCount == atomicObjectCount)
|
||||
// if we ended up skipping everything, there is a reason for this, that users can diagnose themselves
|
||||
// this can occur if a published view contains only unsupported objects or if user trying to ONLY send linked model
|
||||
// docs but the setting is disabled
|
||||
if (skippedObjectCount == atomicObjectCount)
|
||||
{
|
||||
throw new SpeckleException("No supported objects visible. Update publish filter or check publish settings.");
|
||||
}
|
||||
|
||||
// this is, I suppose, fully on us?
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
+5
-5
@@ -37,7 +37,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public DetailLevelType GetDetailLevelSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var fidelityString = modelCard.Settings?.First(s => s.Id == "detailLevel").Value as string;
|
||||
var fidelityString = modelCard.Settings?.FirstOrDefault(s => s.Id == "detailLevel")?.Value as string;
|
||||
if (
|
||||
fidelityString is not null
|
||||
&& DetailLevelSetting.GeometryFidelityMap.TryGetValue(fidelityString, out DetailLevelType fidelity)
|
||||
@@ -59,7 +59,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public Transform? GetReferencePointSetting(ModelCard modelCard)
|
||||
{
|
||||
var referencePointString = modelCard.Settings?.First(s => s.Id == "referencePoint").Value as string;
|
||||
var referencePointString = modelCard.Settings?.FirstOrDefault(s => s.Id == "referencePoint")?.Value as string;
|
||||
if (
|
||||
referencePointString is not null
|
||||
&& ReferencePointSetting.ReferencePointMap.TryGetValue(
|
||||
@@ -90,7 +90,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public bool GetSendParameterNullOrEmptyStringsSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.First(s => s.Id == "nullemptyparams").Value as bool?;
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "nullemptyparams")?.Value as bool?;
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_sendNullParamsCache.TryGetValue(modelCard.ModelCardId.NotNull(), out bool? previousValue))
|
||||
{
|
||||
@@ -108,7 +108,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
// TODO: Evaluate cache invalidation for GetLinkedModelsSetting
|
||||
public bool GetLinkedModelsSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.First(s => s.Id == "includeLinkedModels").Value as bool?;
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "includeLinkedModels")?.Value as bool?;
|
||||
var returnValue = value != null && value.NotNull();
|
||||
|
||||
if (_sendLinkedModelsCache.TryGetValue(modelCard.ModelCardId.NotNull(), out bool? previousValue))
|
||||
@@ -124,7 +124,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public bool GetSendRebarsAsVolumetric(SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.First(s => s.Id == "sendRebarsAsVolumetric").Value as bool?;
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "sendRebarsAsVolumetric")?.Value as bool?;
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_sendRebarsAsVolumetricCache.TryGetValue(modelCard.ModelCardId.NotNull(), out bool? previousValue))
|
||||
{
|
||||
|
||||
@@ -38,6 +38,10 @@ public class RevitThreadContext : ThreadContext
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is OperationCanceledException operation)
|
||||
{
|
||||
throw operation;
|
||||
}
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
@@ -61,6 +65,10 @@ public class RevitThreadContext : ThreadContext
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is OperationCanceledException operation)
|
||||
{
|
||||
throw operation;
|
||||
}
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
@@ -104,6 +112,11 @@ public class RevitThreadContext : ThreadContext
|
||||
ex = e;
|
||||
}
|
||||
});
|
||||
|
||||
if (ex is OperationCanceledException operation)
|
||||
{
|
||||
throw operation;
|
||||
}
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
|
||||
@@ -7,7 +7,7 @@ using Speckle.Sdk.Common;
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
#pragma warning disable CA1032
|
||||
public class SpeckleRevitTaskException(Exception exception) : SpeckleException("Revit operation failed", exception)
|
||||
public class SpeckleRevitTaskException(Exception exception) : SpeckleException(exception.Message, exception)
|
||||
#pragma warning restore CA1032
|
||||
{
|
||||
public static async Task ProcessException<T>(
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -325,9 +325,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -337,7 +337,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino7": {
|
||||
@@ -382,18 +382,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -403,14 +403,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,9 +325,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -337,13 +337,12 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"RhinoCommon": "[8.9.24194.18121, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -382,18 +381,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -403,14 +402,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -1,7 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using Grasshopper.Kernel;
|
||||
using Grasshopper.Kernel.Parameters;
|
||||
using Grasshopper.Kernel.Types;
|
||||
using Speckle.Connectors.GrasshopperShared.HostApp;
|
||||
using Speckle.Connectors.GrasshopperShared.Parameters;
|
||||
@@ -61,7 +60,7 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
var outputParams = new List<OutputParamWrapper>();
|
||||
if (objects.Count != 0)
|
||||
{
|
||||
var param = new Param_GenericObject()
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = "_objects",
|
||||
NickName = "_objs",
|
||||
@@ -94,7 +93,7 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
nickName += "..." + childWrapper.Name[^6..];
|
||||
}
|
||||
|
||||
var param = new Param_GenericObject()
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = childWrapper.Name,
|
||||
NickName = nickName,
|
||||
@@ -191,7 +190,7 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
|
||||
foreach (var newParam in outputParams)
|
||||
{
|
||||
var param = new Param_GenericObject
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = newParam.Param.Name,
|
||||
NickName = newParam.Param.NickName,
|
||||
@@ -214,7 +213,7 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
|
||||
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
|
||||
{
|
||||
var myParam = new Param_GenericObject
|
||||
var myParam = new SpeckleOutputParam
|
||||
{
|
||||
Name = GH_ComponentParamServer.InventUniqueNickname("ABCD", Params.Input),
|
||||
MutableNickName = true,
|
||||
@@ -227,4 +226,4 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
|
||||
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Output;
|
||||
}
|
||||
|
||||
public record OutputParamWrapper(Param_GenericObject Param, object Values, string? Topology);
|
||||
public record OutputParamWrapper(SpeckleOutputParam Param, object Values, string? Topology);
|
||||
|
||||
+290
-183
@@ -28,100 +28,185 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
public override Guid ComponentGuid => GetType().GUID;
|
||||
protected override Bitmap Icon => Resources.speckle_deconstruct;
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager) =>
|
||||
pManager.AddGenericParameter("Speckle Param", "SP", "Speckle param to deconstruct", GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
|
||||
|
||||
protected override void SolveInstance(IGH_DataAccess da)
|
||||
{
|
||||
object data = new();
|
||||
da.GetData(0, ref data);
|
||||
|
||||
List<OutputParamWrapper> outputParams = new();
|
||||
|
||||
switch (data)
|
||||
// on first iteration, discover all fields from all objects to create stable output structure
|
||||
if (da.Iteration == 0)
|
||||
{
|
||||
case SpeckleCollectionWrapperGoo collectionGoo when collectionGoo.Value != null:
|
||||
// get children elements from the wrapper to override the elements prop while parsing
|
||||
List<IGH_Goo> children = collectionGoo.Value.Elements.Select(o => ((SpeckleWrapper)o).CreateGoo()).ToList();
|
||||
outputParams = ParseSpeckleWrapper(collectionGoo.Value, children);
|
||||
break;
|
||||
case SpeckleDataObjectWrapperGoo dataObjectGoo when dataObjectGoo.Value != null:
|
||||
// get geometries from the wrapper to override the displayvalue prop while parsing
|
||||
List<IGH_Goo> display = dataObjectGoo.Value.Geometries.Select(o => o.CreateGoo()).ToList();
|
||||
outputParams = ParseSpeckleWrapper(dataObjectGoo.Value, null, display);
|
||||
break;
|
||||
case SpeckleGeometryWrapperGoo objectGoo when objectGoo.Value != null:
|
||||
outputParams = ParseSpeckleWrapper(objectGoo.Value);
|
||||
break;
|
||||
case SpeckleBlockInstanceWrapperGoo blockInstanceGoo when blockInstanceGoo.Value != null:
|
||||
outputParams = ParseSpeckleWrapper(blockInstanceGoo.Value);
|
||||
break;
|
||||
case SpeckleBlockDefinitionWrapperGoo blockDef:
|
||||
outputParams = ParseSpeckleWrapper(blockDef.Value);
|
||||
break;
|
||||
case SpeckleMaterialWrapperGoo materialGoo when materialGoo.Value != null:
|
||||
outputParams = ParseSpeckleWrapper(materialGoo.Value);
|
||||
break;
|
||||
var allFields = DiscoverAllFieldsFromInput();
|
||||
|
||||
case SpecklePropertyGroupGoo propGoo:
|
||||
Name = $"properties ({propGoo.Value.Count})";
|
||||
outputParams = new();
|
||||
foreach (var key in propGoo.Value.Keys)
|
||||
if (allFields.Count > 0)
|
||||
{
|
||||
var requiredOutputs = CreateOutputParamsFromFieldNames(allFields);
|
||||
|
||||
if (OutputMismatch(requiredOutputs))
|
||||
{
|
||||
ISpecklePropertyGoo value = propGoo.Value[key];
|
||||
object? outputValue = value is SpecklePropertyGoo prop
|
||||
? prop.Value
|
||||
: value is SpecklePropertyGroupGoo propGroup
|
||||
? propGroup
|
||||
: value;
|
||||
|
||||
OutputParamWrapper output =
|
||||
outputValue is IList
|
||||
? CreateOutputParamByKeyValue(key, outputValue, GH_ParamAccess.list)
|
||||
: CreateOutputParamByKeyValue(key, outputValue, GH_ParamAccess.item);
|
||||
outputParams.Add(output);
|
||||
OnPingDocument()?.ScheduleSolution(5, _ => CreateOutputs(requiredOutputs));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Type cannot be deconstructed: {data.GetType().Name}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// process current object normally
|
||||
object data = new();
|
||||
if (!da.GetData(0, ref data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var outputParams = DeconstructObject(data);
|
||||
if (outputParams == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// set component name based on the current object
|
||||
NickName = Name;
|
||||
|
||||
if (da.Iteration == 0 && OutputMismatch(outputParams))
|
||||
// set output data - fill missing fields with nulls for objects that don't have all fields
|
||||
SetOutputData(da, outputParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Discovers all unique field names and their access types from all input objects by looking at volatile data directly.
|
||||
/// </summary>
|
||||
/// <returns>A dictionary mapping field names to their required parameter access types.</returns>
|
||||
private IReadOnlyDictionary<string, GH_ParamAccess> DiscoverAllFieldsFromInput()
|
||||
{
|
||||
Dictionary<string, GH_ParamAccess> allFields = [];
|
||||
|
||||
foreach (var item in Params.Input[0].VolatileData.AllData(true))
|
||||
{
|
||||
OnPingDocument()
|
||||
.ScheduleSolution(
|
||||
5,
|
||||
_ =>
|
||||
{
|
||||
CreateOutputs(outputParams);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < outputParams.Count; i++)
|
||||
var objectOutputs = DeconstructObject(item);
|
||||
if (objectOutputs != null)
|
||||
{
|
||||
var outParam = Params.Output[i];
|
||||
var outParamWrapper = outputParams[i];
|
||||
switch (outParam.Access)
|
||||
foreach (var output in objectOutputs)
|
||||
{
|
||||
case GH_ParamAccess.item:
|
||||
da.SetData(i, outParamWrapper.Value);
|
||||
break;
|
||||
case GH_ParamAccess.list:
|
||||
da.SetDataList(i, outParamWrapper.Value as IList);
|
||||
break;
|
||||
string fieldName = output.Param.Name;
|
||||
allFields[fieldName] = output.Param.Access;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allFields;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates output parameter wrappers from field names and their corresponding access types.
|
||||
/// </summary>
|
||||
/// <param name="fieldAccessTypes">Dictionary mapping field names to their required parameter access types.</param>
|
||||
/// <returns>List of output parameter wrappers with correct access types.</returns>
|
||||
private List<OutputParamWrapper> CreateOutputParamsFromFieldNames(
|
||||
IReadOnlyDictionary<string, GH_ParamAccess> fieldAccessTypes
|
||||
) => fieldAccessTypes.Select(kvp => CreateOutputParamByKeyValue(kvp.Key, null, kvp.Value)).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Deconstructs a single object into its constituent fields/properties.
|
||||
/// </summary>
|
||||
private List<OutputParamWrapper>? DeconstructObject(object data) =>
|
||||
data switch
|
||||
{
|
||||
// get children elements from wrapper to override elements prop while parsing
|
||||
SpeckleCollectionWrapperGoo collectionGoo when collectionGoo.Value != null
|
||||
=> ParseSpeckleWrapper(
|
||||
collectionGoo.Value,
|
||||
collectionGoo.Value.Elements.Select(o => ((SpeckleWrapper)o).CreateGoo()).ToList()
|
||||
),
|
||||
|
||||
// get geometries from wrapper to override displayValue prop while parsing
|
||||
SpeckleDataObjectWrapperGoo dataObjectGoo when dataObjectGoo.Value != null
|
||||
=> ParseSpeckleWrapper(
|
||||
dataObjectGoo.Value,
|
||||
null,
|
||||
dataObjectGoo.Value.Geometries.Select(o => o.CreateGoo()).ToList()
|
||||
),
|
||||
|
||||
SpeckleGeometryWrapperGoo objectGoo when objectGoo.Value != null => ParseSpeckleWrapper(objectGoo.Value),
|
||||
|
||||
SpeckleBlockInstanceWrapperGoo blockInstanceGoo when blockInstanceGoo.Value != null
|
||||
=> ParseSpeckleWrapper(blockInstanceGoo.Value),
|
||||
|
||||
SpeckleBlockDefinitionWrapperGoo blockDef when blockDef.Value != null => ParseSpeckleWrapper(blockDef.Value),
|
||||
|
||||
SpeckleMaterialWrapperGoo materialGoo when materialGoo.Value != null => ParseSpeckleWrapper(materialGoo.Value),
|
||||
|
||||
SpecklePropertyGroupGoo propGoo when propGoo.Value != null => ParsePropertyGroup(propGoo),
|
||||
|
||||
_ => HandleUnsupportedType(data)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Handles SpecklePropertyGroupGoo objects by extracting their key-value pairs.
|
||||
/// </summary>
|
||||
private List<OutputParamWrapper> ParsePropertyGroup(SpecklePropertyGroupGoo propGoo)
|
||||
{
|
||||
Name = $"properties ({propGoo.Value.Count})";
|
||||
List<OutputParamWrapper> objectOutputs = new();
|
||||
|
||||
foreach (var key in propGoo.Value.Keys)
|
||||
{
|
||||
ISpecklePropertyGoo value = propGoo.Value[key];
|
||||
object? outputValue = value switch
|
||||
{
|
||||
SpecklePropertyGoo prop => prop.Value,
|
||||
SpecklePropertyGroupGoo propGroup => propGroup,
|
||||
_ => value
|
||||
};
|
||||
|
||||
// determine access type based on the value
|
||||
GH_ParamAccess access = outputValue is IList ? GH_ParamAccess.list : GH_ParamAccess.item;
|
||||
objectOutputs.Add(CreateOutputParamByKeyValue(key, outputValue, access));
|
||||
}
|
||||
|
||||
return objectOutputs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles unsupported object types by logging an error and returning null.
|
||||
/// </summary>
|
||||
private List<OutputParamWrapper>? HandleUnsupportedType(object data)
|
||||
{
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Type cannot be deconstructed: {data.GetType().Name}");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets output data for the current iteration, filling missing fields with null values.
|
||||
/// Uses a lookup dictionary for efficient field matching.
|
||||
/// </summary>
|
||||
private void SetOutputData(IGH_DataAccess da, List<OutputParamWrapper> currentOutputs)
|
||||
{
|
||||
if (Params.Output.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// create a lookup for current outputs by field name
|
||||
var outputLookup = currentOutputs.ToDictionary(o => o.Param.Name, o => o.Value);
|
||||
|
||||
// set data for each output parameter
|
||||
for (int i = 0; i < Params.Output.Count; i++)
|
||||
{
|
||||
var outputParam = Params.Output[i];
|
||||
|
||||
// set the value if it exists, otherwise set null
|
||||
object? value = outputLookup.TryGetValue(outputParam.Name, out var fieldValue) ? fieldValue : null;
|
||||
|
||||
switch (outputParam.Access)
|
||||
{
|
||||
case GH_ParamAccess.item:
|
||||
da.SetData(i, value);
|
||||
break;
|
||||
case GH_ParamAccess.list:
|
||||
da.SetDataList(i, value as IList ?? new List<object?>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<OutputParamWrapper> ParseSpeckleWrapper(
|
||||
@@ -146,128 +231,149 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
return result;
|
||||
}
|
||||
|
||||
// cycle through base props
|
||||
// process each property of the Base object
|
||||
foreach (var prop in @base.GetMembers(DynamicBaseMemberType.Instance | DynamicBaseMemberType.Dynamic))
|
||||
{
|
||||
// Convert and add to corresponding output structure
|
||||
var value = prop.Value;
|
||||
switch (value)
|
||||
// skip internal dynamic property keys
|
||||
if (prop.Key == nameof(Base.DynamicPropertyKeys))
|
||||
{
|
||||
case null:
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, null, GH_ParamAccess.item));
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
case IList list:
|
||||
List<object> nativeObjects = new();
|
||||
|
||||
// override list value if base is a collection and this is the elements prop, since this is empty if coming from a collectionwrapper
|
||||
if (@base is Collection && prop.Key == "elements" && elements != null)
|
||||
{
|
||||
list = elements;
|
||||
}
|
||||
|
||||
// override list value if base is a dataobject and this is the displayvalue prop, since this is empty if coming from a dataobject wrapper
|
||||
if (@base is Speckle.Objects.Data.DataObject && prop.Key == "displayValue" && displayValue != null)
|
||||
{
|
||||
list = displayValue;
|
||||
}
|
||||
|
||||
foreach (var x in list)
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case SpeckleWrapper wrapper:
|
||||
nativeObjects.Add(wrapper.CreateGoo());
|
||||
break;
|
||||
|
||||
case Base xBase:
|
||||
nativeObjects.AddRange(ConvertOrCreateWrapper(xBase));
|
||||
break;
|
||||
|
||||
default:
|
||||
nativeObjects.Add(x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, nativeObjects, GH_ParamAccess.list));
|
||||
break;
|
||||
|
||||
case Dictionary<string, object?> dict: // this should be treated a properties dict
|
||||
SpecklePropertyGroupGoo propertyGoo = new();
|
||||
propertyGoo.CastFrom(dict);
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, propertyGoo, GH_ParamAccess.item));
|
||||
break;
|
||||
|
||||
case SpeckleWrapper wrapper:
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, wrapper.CreateGoo(), GH_ParamAccess.item));
|
||||
break;
|
||||
|
||||
case Base baseValue:
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, ConvertOrCreateWrapper(baseValue), GH_ParamAccess.list));
|
||||
break;
|
||||
|
||||
default:
|
||||
// we don't want to output dynamic property keys
|
||||
if (prop.Key == nameof(Base.DynamicPropertyKeys))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(CreateOutputParamByKeyValue(prop.Key, prop.Value, GH_ParamAccess.item));
|
||||
break;
|
||||
var outputParam = CreateOutputParamForProperty(prop, @base, elements, displayValue);
|
||||
if (outputParam != null)
|
||||
{
|
||||
result.Add(outputParam);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an output parameter for a single property, handling different value types appropriately.
|
||||
/// </summary>
|
||||
private OutputParamWrapper CreateOutputParamForProperty(
|
||||
KeyValuePair<string, object?> prop,
|
||||
Base @base,
|
||||
List<IGH_Goo>? elements,
|
||||
List<IGH_Goo>? displayValue
|
||||
) =>
|
||||
prop.Value switch
|
||||
{
|
||||
null => CreateOutputParamByKeyValue(prop.Key, null, GH_ParamAccess.item),
|
||||
IList list => CreateListOutputParam(prop.Key, list, @base, elements, displayValue),
|
||||
Dictionary<string, object?> dict => CreateDictionaryOutputParam(prop.Key, dict),
|
||||
SpeckleWrapper wrapper => CreateOutputParamByKeyValue(prop.Key, wrapper.CreateGoo(), GH_ParamAccess.item),
|
||||
Base baseValue => CreateOutputParamByKeyValue(prop.Key, ConvertOrCreateWrapper(baseValue), GH_ParamAccess.list),
|
||||
_ => CreateOutputParamByKeyValue(prop.Key, prop.Value, GH_ParamAccess.item)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates an output parameter for list properties, with special handling for collection elements and display values.
|
||||
/// </summary>
|
||||
private OutputParamWrapper CreateListOutputParam(
|
||||
string key,
|
||||
IList list,
|
||||
Base @base,
|
||||
List<IGH_Goo>? elements,
|
||||
List<IGH_Goo>? displayValue
|
||||
)
|
||||
{
|
||||
// override list value for special cases
|
||||
IList actualList = key switch
|
||||
{
|
||||
"elements" when @base is Collection && elements != null => elements,
|
||||
"displayValue" when @base is Speckle.Objects.Data.DataObject && displayValue != null => displayValue,
|
||||
_ => list
|
||||
};
|
||||
|
||||
List<object> nativeObjects = new();
|
||||
foreach (var item in actualList)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case SpeckleWrapper wrapper:
|
||||
nativeObjects.Add(wrapper.CreateGoo());
|
||||
break;
|
||||
case Base baseItem:
|
||||
nativeObjects.AddRange(ConvertOrCreateWrapper(baseItem));
|
||||
break;
|
||||
default:
|
||||
nativeObjects.Add(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CreateOutputParamByKeyValue(key, nativeObjects, GH_ParamAccess.list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an output parameter for dictionary properties, converting them to SpecklePropertyGroupGoo.
|
||||
/// </summary>
|
||||
private OutputParamWrapper CreateDictionaryOutputParam(string key, Dictionary<string, object?> dict)
|
||||
{
|
||||
SpecklePropertyGroupGoo propertyGoo = new();
|
||||
propertyGoo.CastFrom(dict);
|
||||
return CreateOutputParamByKeyValue(key, propertyGoo, GH_ParamAccess.item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Speckle Base object to host geometry or creates a wrapper if conversion fails.
|
||||
/// Returns a list of SpeckleGeometryWrapperGoo objects.
|
||||
/// </summary>
|
||||
private List<SpeckleGeometryWrapperGoo> ConvertOrCreateWrapper(Base @base)
|
||||
{
|
||||
try
|
||||
{
|
||||
// convert the base and create a wrapper for each result
|
||||
// attempt conversion to host geometry
|
||||
List<(object, Base)> convertedBase = SpeckleConversionContext.Current.ConvertToHost(@base);
|
||||
List<SpeckleGeometryWrapperGoo> convertedWrappers = new();
|
||||
foreach ((object o, Base b) in convertedBase)
|
||||
{
|
||||
GeometryBase? g = o as GeometryBase;
|
||||
SpeckleGeometryWrapper convertedWrapper =
|
||||
new()
|
||||
{
|
||||
Base = b,
|
||||
GeometryBase = g,
|
||||
Name = b["name"] as string ?? "",
|
||||
Color = null,
|
||||
Material = null
|
||||
};
|
||||
|
||||
convertedWrappers.Add(new(convertedWrapper));
|
||||
}
|
||||
|
||||
return convertedWrappers;
|
||||
return convertedBase.Select(CreateGeometryWrapper).ToList();
|
||||
}
|
||||
catch (ConversionException)
|
||||
{
|
||||
// some classes, like RawEncoding, have no direct conversion or fallback value.
|
||||
// when this is the case, wrap it to allow users to further expand the object.
|
||||
SpeckleGeometryWrapper convertedWrapper =
|
||||
new()
|
||||
{
|
||||
Base = @base,
|
||||
GeometryBase = null,
|
||||
Name = @base[Constants.NAME_PROP] as string ?? "",
|
||||
Color = null,
|
||||
Material = null
|
||||
};
|
||||
|
||||
return new() { new SpeckleGeometryWrapperGoo(convertedWrapper) };
|
||||
// fallback: create wrapper without conversion for objects that can't be converted
|
||||
return new List<SpeckleGeometryWrapperGoo> { CreateFallbackWrapper(@base) };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a SpeckleGeometryWrapperGoo from a converted geometry and base object pair.
|
||||
/// </summary>
|
||||
private SpeckleGeometryWrapperGoo CreateGeometryWrapper((object geometry, Base @base) converted)
|
||||
{
|
||||
SpeckleGeometryWrapper wrapper =
|
||||
new()
|
||||
{
|
||||
Base = converted.@base,
|
||||
GeometryBase = converted.geometry as GeometryBase,
|
||||
Name = converted.@base["name"] as string ?? "",
|
||||
Color = null,
|
||||
Material = null
|
||||
};
|
||||
return new SpeckleGeometryWrapperGoo(wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a fallback wrapper for Base objects that cannot be converted to host geometry.
|
||||
/// </summary>
|
||||
private SpeckleGeometryWrapperGoo CreateFallbackWrapper(Base @base)
|
||||
{
|
||||
SpeckleGeometryWrapper wrapper =
|
||||
new()
|
||||
{
|
||||
Base = @base,
|
||||
GeometryBase = null,
|
||||
Name = @base[Constants.NAME_PROP] as string ?? "",
|
||||
Color = null,
|
||||
Material = null
|
||||
};
|
||||
return new SpeckleGeometryWrapperGoo(wrapper);
|
||||
}
|
||||
|
||||
private OutputParamWrapper CreateOutputParamByKeyValue(string key, object? value, GH_ParamAccess access)
|
||||
{
|
||||
Param_GenericObject param =
|
||||
SpeckleOutputParam param =
|
||||
new()
|
||||
{
|
||||
Name = key,
|
||||
@@ -297,22 +403,20 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
return myParam;
|
||||
}
|
||||
|
||||
public bool DestroyParameter(GH_ParameterSide side, int index)
|
||||
{
|
||||
return side == GH_ParameterSide.Output;
|
||||
}
|
||||
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Output;
|
||||
|
||||
private void CreateOutputs(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
// TODO: better, nicer handling of creation/removal
|
||||
// remove all existing output parameters
|
||||
while (Params.Output.Count > 0)
|
||||
{
|
||||
Params.UnregisterOutputParameter(Params.Output[^1]);
|
||||
}
|
||||
|
||||
// add new output parameters
|
||||
foreach (var newParam in outputParams)
|
||||
{
|
||||
var param = new Param_GenericObject
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = newParam.Param.Name,
|
||||
NickName = newParam.Param.NickName,
|
||||
@@ -322,11 +426,15 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
Params.RegisterOutputParam(param);
|
||||
}
|
||||
|
||||
// notify Grasshopper of parameter changes
|
||||
Params.OnParametersChanged();
|
||||
VariableParameterMaintenance();
|
||||
ExpireSolution(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the current output parameter structure differs from the required structure.
|
||||
/// </summary>
|
||||
private bool OutputMismatch(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
if (Params.Output.Count != outputParams.Count)
|
||||
@@ -334,10 +442,10 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
return true;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
foreach (var newParam in outputParams)
|
||||
for (int i = 0; i < outputParams.Count; i++)
|
||||
{
|
||||
var oldParam = Params.Output[count];
|
||||
var newParam = outputParams[i];
|
||||
var oldParam = Params.Output[i];
|
||||
if (
|
||||
oldParam.NickName != newParam.Param.NickName
|
||||
|| oldParam.Name != newParam.Param.Name
|
||||
@@ -346,7 +454,6 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
|
||||
{
|
||||
return true;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using Grasshopper.Kernel;
|
||||
using Speckle.Connectors.GrasshopperShared.Parameters;
|
||||
using Speckle.Connectors.GrasshopperShared.Properties;
|
||||
|
||||
namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
|
||||
|
||||
// NOTE: Why all this madness? The properties passthrough node is restrictive in output type being uniform
|
||||
// Properties whose values were lists were not being displayed and couldn't be given back to the user as native
|
||||
// lists. This was (it seemed) the only viable approach.
|
||||
// [CNX-2364](https://linear.app/speckle/issue/CNX-2364/grasshopper-properties-passthrough-does-not-handle-list-values)
|
||||
|
||||
[Guid("474F4699-D641-444F-BC78-E22AAF40B240")]
|
||||
public class ExpandSpeckleProperties : GH_Component, IGH_VariableParameterComponent
|
||||
{
|
||||
public ExpandSpeckleProperties()
|
||||
: base(
|
||||
"Expand Properties",
|
||||
"eP",
|
||||
"Expands Speckle Properties into their individual outputs with correct access types",
|
||||
ComponentCategories.PRIMARY_RIBBON,
|
||||
ComponentCategories.OBJECTS
|
||||
) { }
|
||||
|
||||
public override Guid ComponentGuid => GetType().GUID;
|
||||
protected override Bitmap Icon => Resources.speckle_properties_expand;
|
||||
public override GH_Exposure Exposure => GH_Exposure.secondary;
|
||||
|
||||
protected override void RegisterInputParams(GH_InputParamManager pManager)
|
||||
{
|
||||
pManager.AddParameter(
|
||||
new SpecklePropertyGroupParam(),
|
||||
"Properties",
|
||||
"P",
|
||||
"Speckle Properties to expand",
|
||||
GH_ParamAccess.item
|
||||
);
|
||||
}
|
||||
|
||||
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
|
||||
|
||||
protected override void SolveInstance(IGH_DataAccess da)
|
||||
{
|
||||
SpecklePropertyGroupGoo? properties = null;
|
||||
if (!da.GetData(0, ref properties) || properties?.Value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Name = $"Properties ({properties.Value.Count})";
|
||||
NickName = Name;
|
||||
|
||||
var outputParams = new List<OutputParamWrapper>();
|
||||
|
||||
foreach (var key in properties.Value.Keys)
|
||||
{
|
||||
ISpecklePropertyGoo value = properties.Value[key];
|
||||
object? outputValue = value switch
|
||||
{
|
||||
SpecklePropertyGoo prop => prop.Value,
|
||||
SpecklePropertyGroupGoo propGroup => propGroup,
|
||||
_ => value
|
||||
};
|
||||
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = key,
|
||||
NickName = key,
|
||||
Access = outputValue is IList ? GH_ParamAccess.list : GH_ParamAccess.item
|
||||
};
|
||||
|
||||
outputParams.Add(new OutputParamWrapper(param, outputValue));
|
||||
}
|
||||
|
||||
// handle parameter creation/update (only on first iteration)
|
||||
if (da.Iteration == 0 && OutputMismatch(outputParams))
|
||||
{
|
||||
OnPingDocument()?.ScheduleSolution(5, _ => CreateOutputs(outputParams));
|
||||
return; // exit early
|
||||
}
|
||||
// only set data if we have the correct parameter structure
|
||||
if (Params.Output.Count == outputParams.Count)
|
||||
{
|
||||
for (int i = 0; i < outputParams.Count; i++)
|
||||
{
|
||||
var outputParam = outputParams[i];
|
||||
switch (outputParam.Param.Access)
|
||||
{
|
||||
case GH_ParamAccess.item:
|
||||
da.SetData(i, outputParam.Value);
|
||||
break;
|
||||
case GH_ParamAccess.list:
|
||||
da.SetDataList(i, outputParam.Value as IList ?? new List<object?>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates output parameters based on discovered properties.
|
||||
/// </summary>
|
||||
private void CreateOutputs(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
// remove all existing output parameters
|
||||
while (Params.Output.Count > 0)
|
||||
{
|
||||
Params.UnregisterOutputParameter(Params.Output[^1]);
|
||||
}
|
||||
|
||||
// add new output parameters
|
||||
foreach (var newParam in outputParams)
|
||||
{
|
||||
var param = new SpeckleOutputParam
|
||||
{
|
||||
Name = newParam.Param.Name,
|
||||
NickName = newParam.Param.NickName,
|
||||
MutableNickName = false,
|
||||
Access = newParam.Param.Access
|
||||
};
|
||||
Params.RegisterOutputParam(param);
|
||||
}
|
||||
|
||||
// notify gh of parameter changes
|
||||
Params.OnParametersChanged();
|
||||
VariableParameterMaintenance();
|
||||
ExpireSolution(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the current output parameter structure differs from the required structure.
|
||||
/// </summary>
|
||||
private bool OutputMismatch(List<OutputParamWrapper> outputParams)
|
||||
{
|
||||
if (Params.Output.Count != outputParams.Count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < outputParams.Count; i++)
|
||||
{
|
||||
var newParam = outputParams[i];
|
||||
var oldParam = Params.Output[i];
|
||||
if (
|
||||
oldParam.NickName != newParam.Param.NickName
|
||||
|| oldParam.Name != newParam.Param.Name
|
||||
|| oldParam.Access != newParam.Param.Access
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// IGH_VariableParameterComponent implementation
|
||||
public bool CanInsertParameter(GH_ParameterSide side, int index) => false;
|
||||
|
||||
public bool CanRemoveParameter(GH_ParameterSide side, int index) => false;
|
||||
|
||||
public void VariableParameterMaintenance() { }
|
||||
|
||||
public IGH_Param CreateParameter(GH_ParameterSide side, int index) => new SpeckleOutputParam();
|
||||
|
||||
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Output;
|
||||
}
|
||||
|
||||
public record OutputParamWrapper(SpeckleOutputParam Param, object? Value);
|
||||
+24
-5
@@ -137,7 +137,10 @@ public class FilterSpeckleObjects : GH_Component
|
||||
|
||||
if (properties is not null)
|
||||
{
|
||||
foreach (string key in properties.Value.Keys)
|
||||
// use flattened properties to search ALL nested property keys
|
||||
// fix for [CNX-2512](https://linear.app/speckle/issue/CNX-2512/filter-objects-material-and-property-key-inputs-dont-work-as-expected)
|
||||
Dictionary<string, SpecklePropertyGoo> flattenedProps = properties.Flatten();
|
||||
foreach (string key in flattenedProps.Keys)
|
||||
{
|
||||
if (MatchesSearchPattern(property, key))
|
||||
{
|
||||
@@ -155,13 +158,29 @@ public class FilterSpeckleObjects : GH_Component
|
||||
}
|
||||
|
||||
// filter by material name
|
||||
if (wrapper is SpeckleGeometryWrapper geoWrapper)
|
||||
bool materialMatches = true;
|
||||
if (!string.IsNullOrEmpty(material))
|
||||
{
|
||||
if (!MatchesSearchPattern(material, geoWrapper.Material?.Name ?? ""))
|
||||
materialMatches = false;
|
||||
|
||||
if (wrapper is SpeckleGeometryWrapper geoWrapper)
|
||||
{
|
||||
removedObjects.Add(wrapper);
|
||||
continue;
|
||||
materialMatches = MatchesSearchPattern(material, geoWrapper.Material?.Name ?? "");
|
||||
}
|
||||
else if (wrapper is SpeckleDataObjectWrapper dataObjWrapper)
|
||||
{
|
||||
// check if ANY geometry in the data object has a matching material (not sure about this...)
|
||||
// fix for [CNX-2512](https://linear.app/speckle/issue/CNX-2512/filter-objects-material-and-property-key-inputs-dont-work-as-expected)
|
||||
materialMatches = dataObjWrapper.Geometries.Any(geo =>
|
||||
MatchesSearchPattern(material, geo.Material?.Name ?? "")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!materialMatches)
|
||||
{
|
||||
removedObjects.Add(wrapper);
|
||||
continue;
|
||||
}
|
||||
|
||||
// filter by application id
|
||||
|
||||
+26
-12
@@ -1,7 +1,5 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Grasshopper.Kernel;
|
||||
using Grasshopper.Kernel.Parameters;
|
||||
using Grasshopper.Kernel.Types;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.GrasshopperShared.HostApp;
|
||||
using Speckle.Connectors.GrasshopperShared.Parameters;
|
||||
@@ -40,8 +38,8 @@ public class QuerySpeckleObjects : GH_Component, IGH_VariableParameterComponent
|
||||
|
||||
pManager.AddTextParameter(
|
||||
"Path",
|
||||
"C",
|
||||
"Get the Speckle objects in the subcollection indicated by this path",
|
||||
"P",
|
||||
"Get the Speckle objects in the sub-collection indicated by this path",
|
||||
GH_ParamAccess.item
|
||||
);
|
||||
|
||||
@@ -137,10 +135,28 @@ public class QuerySpeckleObjects : GH_Component, IGH_VariableParameterComponent
|
||||
// Set output objects
|
||||
for (int i = 0; i < Params.Output.Count; i++)
|
||||
{
|
||||
List<SpeckleWrapper> outputValues =
|
||||
i == 0 ? filteredObjects : _filterDict[Filters[i - 1]].Select(o => (SpeckleWrapper)o).ToList();
|
||||
List<IGH_Goo> outputGoos = outputValues.Select(o => o.CreateGoo()).ToList();
|
||||
if (targetCollectionWrapper?.Topology is string topology && !string.IsNullOrEmpty(topology))
|
||||
// determine output values based on parameter type
|
||||
List<SpeckleWrapper> outputValues;
|
||||
if (i == 0)
|
||||
{
|
||||
outputValues = filteredObjects;
|
||||
}
|
||||
else if (
|
||||
Enum.TryParse(Params.Output[i].Name, out ObjectType filterType)
|
||||
&& _filterDict.TryGetValue(filterType, out var filteredList)
|
||||
)
|
||||
{
|
||||
outputValues = filteredList.Cast<SpeckleWrapper>().ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
outputValues = [];
|
||||
}
|
||||
|
||||
var outputGoos = outputValues.Select(o => o.CreateGoo()).ToList();
|
||||
|
||||
// only use topology for the first output when we have a path
|
||||
if (i == 0 && targetCollectionWrapper?.Topology is string topology && !string.IsNullOrEmpty(topology))
|
||||
{
|
||||
var tree = GrasshopperHelpers.CreateDataTreeFromTopologyAndItems(topology, outputGoos);
|
||||
dataAccess.SetDataTree(i, tree);
|
||||
@@ -244,7 +260,7 @@ public class QuerySpeckleObjects : GH_Component, IGH_VariableParameterComponent
|
||||
_outputFilterIndices = null;
|
||||
|
||||
ObjectType filter = previousFilterIndex is null ? Filters.First() : Filters[(int)previousFilterIndex + 1];
|
||||
return new Param_GenericObject
|
||||
return new SpeckleOutputParam
|
||||
{
|
||||
Name = filter.ToString(),
|
||||
NickName = GetFilterNickName(filter),
|
||||
@@ -273,10 +289,8 @@ public class QuerySpeckleObjects : GH_Component, IGH_VariableParameterComponent
|
||||
base.RemovedFromDocument(document);
|
||||
}
|
||||
|
||||
private void OnParameterSourceChanged(object sender, GH_ParamServerEventArgs args)
|
||||
{
|
||||
private void OnParameterSourceChanged(object sender, GH_ParamServerEventArgs args) =>
|
||||
// an empty filter dict will trigger the SortObjectsByGeometryBaseType method.
|
||||
// we only want to re-sort objects if an input has changed, not on every trigger of solve instance.
|
||||
_filterDict.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -84,7 +84,12 @@ public class SpeckleBlockDefinitionPassthrough()
|
||||
|
||||
// process the definition
|
||||
// deep copy so we don't mutate the object
|
||||
SpeckleBlockDefinitionWrapperGoo result = inputDefinition != null ? new(inputDefinition.Value.DeepCopy()) : new();
|
||||
SpeckleBlockDefinitionWrapperGoo result = new();
|
||||
if (inputDefinition != null)
|
||||
{
|
||||
result = new SpeckleBlockDefinitionWrapperGoo(inputDefinition.Value.DeepCopy());
|
||||
result.Value.Base.id = null; // ⚠️ TODO: Co-ordinate with SDK. We're having to do this otherwise the serializer won't recompute mutated objects
|
||||
}
|
||||
|
||||
// process geometry
|
||||
if (inputObjects.Count > 0)
|
||||
|
||||
+6
-2
@@ -151,8 +151,12 @@ public class SpeckleBlockInstancePassthrough()
|
||||
|
||||
// process the instance
|
||||
// deep copy so we don't mutate the incoming object
|
||||
SpeckleBlockInstanceWrapperGoo result =
|
||||
inputInstance != null ? new((SpeckleBlockInstanceWrapper)inputInstance.Value.DeepCopy()) : new();
|
||||
SpeckleBlockInstanceWrapperGoo result = new();
|
||||
if (inputInstance != null)
|
||||
{
|
||||
result = new SpeckleBlockInstanceWrapperGoo((SpeckleBlockInstanceWrapper)inputInstance.Value.DeepCopy());
|
||||
result.Value.Base.id = null; // ⚠️ TODO: Co-ordinate with SDK. We're having to do this otherwise the serializer won't recompute mutated objects
|
||||
}
|
||||
|
||||
// process definition
|
||||
if (inputDefinition != null)
|
||||
|
||||
+1
@@ -98,6 +98,7 @@ public class SpeckleDataObjectPassthrough()
|
||||
if (da.GetData(0, ref inputObject))
|
||||
{
|
||||
result = inputObject.Value.DeepCopy();
|
||||
result.Base.id = null; // ⚠️ TODO: Co-ordinate with SDK. We're having to do this otherwise the serializer won't recompute mutated objects
|
||||
}
|
||||
|
||||
List<SpeckleGeometryWrapperGoo> inputGeometry = new();
|
||||
|
||||
+1
@@ -125,6 +125,7 @@ public class SpeckleGeometryPassthrough()
|
||||
if (inputObject?.ToSpeckleGeometryWrapper() is SpeckleGeometryWrapper gooWrapper)
|
||||
{
|
||||
result = gooWrapper.DeepCopy();
|
||||
result.Base.id = null; // ⚠️ TODO: Co-ordinate with SDK. We're having to do this otherwise the serializer won't recompute mutated objects
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+2
-2
@@ -98,13 +98,13 @@ public class SpecklePropertiesPassthrough : SpeckleSolveInstance
|
||||
// validate that keys and values are of valid length
|
||||
if ((Mode == PropertyMode.Merge || Mode == PropertyMode.Replace) && inputKeys.Count != inputValues.Count)
|
||||
{
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Keys and values are mismatched in length");
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Keys and values are mismatched in length");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Mode == PropertyMode.Remove && (inputKeys.Count == 0 || inputValues.Count > 0))
|
||||
{
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Only input keys to remove");
|
||||
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Only input keys to remove");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -22,7 +22,7 @@ public class SpeckleOperationWizard
|
||||
|
||||
public Account? SelectedAccount { get; private set; }
|
||||
public List<Account>? Accounts { get; }
|
||||
public Workspace? SelectedWorkspace { get; private set; }
|
||||
public LimitedWorkspace? SelectedWorkspace { get; private set; }
|
||||
public Project? SelectedProject { get; private set; }
|
||||
public Model? SelectedModel { get; private set; }
|
||||
public Version? SelectedVersion { get; private set; }
|
||||
@@ -416,13 +416,17 @@ public class SpeckleOperationWizard
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using IClient client = _clientFactory.Create(SelectedAccount);
|
||||
var activeWorkspace = client.ActiveUser.GetActiveWorkspace().Result;
|
||||
Workspace? selectedWorkspace =
|
||||
|
||||
LimitedWorkspace? selectedWorkspace =
|
||||
SelectedWorkspace
|
||||
?? activeWorkspace
|
||||
?? (WorkspaceMenuHandler.Workspaces?.items.Count > 0 ? WorkspaceMenuHandler.Workspaces?.items[0] : null);
|
||||
|
||||
SelectedWorkspace = selectedWorkspace;
|
||||
|
||||
WorkspaceMenuHandler.RedrawMenuButton(SelectedWorkspace);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -3,9 +3,9 @@ using Speckle.Sdk.Api.GraphQL.Models;
|
||||
|
||||
namespace Speckle.Connectors.GrasshopperShared.Components.Operations.Wizard;
|
||||
|
||||
public class WorkspaceSelectedEventArgs(Workspace? model) : EventArgs
|
||||
public class WorkspaceSelectedEventArgs(LimitedWorkspace? model) : EventArgs
|
||||
{
|
||||
public Workspace? SelectedWorkspace { get; } = model;
|
||||
public LimitedWorkspace? SelectedWorkspace { get; } = model;
|
||||
}
|
||||
|
||||
public class WorkspaceMenuHandler
|
||||
@@ -15,7 +15,7 @@ public class WorkspaceMenuHandler
|
||||
public bool IsPersonalProjects { get; set; }
|
||||
private SearchToolStripMenuItem? _searchItem;
|
||||
private readonly Func<Task> _createWorkspace;
|
||||
private Workspace? SelectedWorkspace { get; set; }
|
||||
private LimitedWorkspace? SelectedWorkspace { get; set; }
|
||||
|
||||
public ResourceCollection<Workspace>? Workspaces { get; set; }
|
||||
public Bitmap? Logo { get; private set; }
|
||||
@@ -103,7 +103,7 @@ public class WorkspaceMenuHandler
|
||||
);
|
||||
}
|
||||
|
||||
private void OnWorkspaceSelected(Workspace? workspace)
|
||||
private void OnWorkspaceSelected(LimitedWorkspace? workspace)
|
||||
{
|
||||
IsPersonalProjects = workspace == null;
|
||||
_menu?.Close();
|
||||
@@ -112,7 +112,7 @@ public class WorkspaceMenuHandler
|
||||
WorkspaceSelected?.Invoke(this, new WorkspaceSelectedEventArgs(workspace));
|
||||
}
|
||||
|
||||
public void RedrawMenuButton(Workspace? workspace)
|
||||
public void RedrawMenuButton(LimitedWorkspace? workspace)
|
||||
{
|
||||
var suffix = WorkspaceContextMenuButton.Enabled
|
||||
? "Left-click to select another workspace."
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
using GH_IO.Serialization;
|
||||
using Grasshopper.Kernel;
|
||||
using Grasshopper.Kernel.Attributes;
|
||||
using Grasshopper.Kernel.Parameters;
|
||||
|
||||
namespace Speckle.Connectors.GrasshopperShared.Parameters;
|
||||
|
||||
/// <summary>
|
||||
/// Simple extension of Param_GenericObject that adds "Extract parameter" functionality.
|
||||
/// Follows the existing v3 codebase patterns.
|
||||
/// </summary>
|
||||
public class SpeckleOutputParam : Param_GenericObject
|
||||
{
|
||||
public override Guid ComponentGuid => new("D2B4713D-FE8B-4EF0-8445-B6096DB15B24");
|
||||
|
||||
public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
|
||||
{
|
||||
base.AppendAdditionalMenuItems(menu);
|
||||
|
||||
// only show extract parameter option for output parameters that have no connections
|
||||
if (Kind == GH_ParamKind.output && Recipients.Count == 0)
|
||||
{
|
||||
Menu_AppendSeparator(menu);
|
||||
Menu_AppendItem(menu, "Extract parameter", Menu_ExtractOutputParameterClicked, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract parameter implementation - taken from v2 legacy and simplified for v3.
|
||||
/// </summary>
|
||||
private void Menu_ExtractOutputParameterClicked(object sender, EventArgs e)
|
||||
{
|
||||
var archive = new GH_Archive();
|
||||
if (!archive.AppendObject(this, "Parameter"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newParam = new SpeckleOutputParam();
|
||||
newParam.CreateAttributes();
|
||||
|
||||
if (!archive.ExtractObject(newParam, "Parameter"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
newParam.NewInstanceGuid();
|
||||
newParam.Attributes.Selected = false;
|
||||
newParam.Attributes.PerformLayout();
|
||||
newParam.Attributes.Pivot = new PointF(
|
||||
Attributes.Parent.Bounds.Right + newParam.Attributes.Bounds.Width * 0.5f + 15,
|
||||
Attributes.Pivot.Y
|
||||
);
|
||||
newParam.MutableNickName = true;
|
||||
|
||||
if (newParam.Attributes is GH_FloatingParamAttributes floating)
|
||||
{
|
||||
floating.PerformLayout();
|
||||
}
|
||||
|
||||
var document = OnPingDocument();
|
||||
if (document != null)
|
||||
{
|
||||
document.AddObject(newParam, false);
|
||||
newParam.AddSource(this);
|
||||
newParam.ExpireSolution(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-9
@@ -22,21 +22,51 @@ public partial class SpecklePropertyGroupGoo : GH_Goo<Dictionary<string, ISpeckl
|
||||
return CastFromModelObject(modelObject.UserText);
|
||||
|
||||
case ModelUserText userText:
|
||||
Dictionary<string, ISpecklePropertyGoo> dictionary = new();
|
||||
foreach (KeyValuePair<string, string> entry in userText)
|
||||
{
|
||||
SpecklePropertyGoo value = new() { Value = entry.Value };
|
||||
dictionary.Add(entry.Key, value);
|
||||
}
|
||||
|
||||
Value = dictionary;
|
||||
return true;
|
||||
var processedDictionary = ConvertToNested(userText.ToDictionary(o => o.Key, o => (object)o.Value));
|
||||
return CastFrom(processedDictionary);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Property keys may already be concatenated with the `.` char, eg if baked from grasshopper.
|
||||
public Dictionary<string, object> ConvertToNested(Dictionary<string, object> flatDict)
|
||||
{
|
||||
var nestedDict = new Dictionary<string, object>();
|
||||
|
||||
foreach (string keyPath in flatDict.Keys)
|
||||
{
|
||||
var keys = keyPath.Split('.');
|
||||
var current = nestedDict;
|
||||
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
var key = keys[i];
|
||||
|
||||
if (i == keys.Length - 1)
|
||||
{
|
||||
current[key] = flatDict[keyPath];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!current.TryGetValue(key, out var next))
|
||||
{
|
||||
var newDict = new Dictionary<string, object>();
|
||||
current[key] = newDict;
|
||||
current = newDict;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = (Dictionary<string, object>)next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nestedDict;
|
||||
}
|
||||
|
||||
private bool CastToModelObject<T>(ref T target)
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
+11
-6
@@ -35,19 +35,20 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
|
||||
|
||||
private bool HandleModelObject(ModelObject modelObject)
|
||||
{
|
||||
modelObject.CastTo<GeometryBase>(out GeometryBase? geometryBase);
|
||||
if (geometryBase is null)
|
||||
modelObject.CastTo<IGH_GeometricGoo>(out IGH_GeometricGoo? geometryGoo);
|
||||
if (geometryGoo is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not retrieve geometry from model object.");
|
||||
}
|
||||
|
||||
GeometryBase geometryBase = geometryGoo.ToGeometryBase();
|
||||
Base converted = SpeckleConversionContext.Current.ConvertToSpeckle(geometryBase);
|
||||
|
||||
// get layer, props, color, and mat
|
||||
SpeckleCollectionWrapper? collection = GetLayerCollectionFromModelObject(modelObject);
|
||||
SpecklePropertyGroupGoo? props = GetPropsFromModelObjectAndAssignToBase(modelObject, converted);
|
||||
Color? color = GetColorFromModelObject(modelObject);
|
||||
SpeckleMaterialWrapper? material = GetMaterialFromModelObject(modelObject);
|
||||
Color? color = GetColorFromModelObject(modelObject, material);
|
||||
|
||||
// get the definition if this is an instance
|
||||
SpeckleBlockDefinitionWrapper? definition = GetBlockDefinition(geometryBase);
|
||||
@@ -189,6 +190,7 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
|
||||
Transform = instance.Xform,
|
||||
Definition = definition, // May be null in pure Grasshopper workflows
|
||||
Parent = parent,
|
||||
Path = parent?.Path ?? new(),
|
||||
Name = name,
|
||||
Color = color,
|
||||
Material = mat,
|
||||
@@ -200,6 +202,7 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
|
||||
GeometryBase = geometryBase,
|
||||
Base = @base,
|
||||
Parent = parent,
|
||||
Path = parent?.Path ?? new(),
|
||||
Name = name,
|
||||
Color = color,
|
||||
Material = mat,
|
||||
@@ -268,7 +271,7 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
|
||||
return null;
|
||||
}
|
||||
|
||||
private Color? GetColorFromModelObject(ModelObject modelObject)
|
||||
private Color? GetColorFromModelObject(ModelObject modelObject, SpeckleMaterialWrapper? material)
|
||||
{
|
||||
// we need to retrieve the actual color by the color source (otherwise will return default color for anything other than by object)
|
||||
int? argb = null;
|
||||
@@ -281,8 +284,10 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
|
||||
argb = modelObject.Display.Color?.Color.ToArgb();
|
||||
break;
|
||||
case ObjectColorSource.ColorFromMaterial:
|
||||
Rhino.Render.RenderMaterial? mat = GetRenderMaterial(modelObject);
|
||||
argb = mat?.ToMaterial(Rhino.Render.RenderTexture.TextureGeneration.Skip)?.DiffuseColor.ToArgb();
|
||||
if (material is not null)
|
||||
{
|
||||
argb = material.Material.diffuse;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+16
-4
@@ -330,10 +330,22 @@ namespace Speckle.Connectors.GrasshopperShared.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
public static System.Drawing.Bitmap speckle_properties_properties {
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
public static System.Drawing.Bitmap speckle_properties_expand
|
||||
{
|
||||
get
|
||||
{
|
||||
object obj = ResourceManager.GetObject("speckle_properties_expand", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
public static System.Drawing.Bitmap speckle_properties_properties {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("speckle_properties_properties", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
|
||||
@@ -208,4 +208,7 @@
|
||||
<data name="speckle_state_access" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\speckle_state_access.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="speckle_properties_expand" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\speckle_properties_expand.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
+2
-1
@@ -33,11 +33,12 @@ public class PriorityLoader : GH_AssemblyPriority
|
||||
|
||||
public static IServiceScope CreateScopeForActiveDocument()
|
||||
{
|
||||
// NOTE: introduction of AddVisualizationProperties setting not accounted for in GH, hence hardcoded as true (i.e. "as before")
|
||||
var scope = Container.CreateScope();
|
||||
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc, true));
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
+2
@@ -16,6 +16,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\CollectionPathsSelector.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\CreateCollection.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\ExpandCollection.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Objects\ExpandSpeckleProperties.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Objects\SpeckleBlockInstancePassthrough.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Objects\SpeckleBlockDefinitionPassthrough.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Components\Dev\TokenUrlComponent.cs" />
|
||||
@@ -65,6 +66,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SpeckleResource.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SpeckleResourceBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Parameters\SpeckleOutputParam.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Parameters\SpecklePropertyGroupParam.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleBlockInstanceWrapperParam.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleBlockInstanceWrapperGoo.cs" />
|
||||
|
||||
@@ -306,9 +306,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -341,7 +341,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino7": {
|
||||
@@ -401,18 +401,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -422,14 +422,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
},
|
||||
"System.Resources.Extensions": {
|
||||
"type": "CentralTransitive",
|
||||
|
||||
@@ -306,9 +306,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )",
|
||||
"Speckle.Sdk": "[3.4.6, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.4.8, )"
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -341,13 +341,12 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.4.6, )"
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"RhinoCommon": "[8.9.24194.18121, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -401,18 +400,18 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "JjCdW+gUWq7u1Tb5SlLaFCIYfmrMA9HbUzCdlSPDzyJkPuJFhwK3qKDwe4ggrAs7DuNuBhqL/VKCr/J29Wh2ng==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.4.6"
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.6, )",
|
||||
"resolved": "3.4.6",
|
||||
"contentHash": "YBa/RuwvBbymjWGv7sD2TwMSLhSjz3GYPOGVJtZzBZvev/zDQNZozvIlre+Lk7xpT2KPdH1FRfLkPWyW+qonMA==",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
@@ -422,14 +421,14 @@
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.4.6"
|
||||
"Speckle.Sdk.Dependencies": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.4.8, )",
|
||||
"resolved": "3.4.8",
|
||||
"contentHash": "bNpJc2NBvjtJmdYS3xb6Fv4eqI/xZ2URXfWeXUFaWPMfC1QXLTjlK6iFriQk9ptLwr/dt4UPDPYYHOBynY1f2A=="
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
},
|
||||
"System.Resources.Extensions": {
|
||||
"type": "CentralTransitive",
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
+42
@@ -0,0 +1,42 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!--This csproj is NOT designed to be run as a rhino plugin-->
|
||||
<!--This csproj is NOT the rhino importer-->
|
||||
<!--This csproj is the connector code used by the Speckle.Importers.Rhino project-->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<RhinoVersion>8</RhinoVersion>
|
||||
<DefineConstants>$(DefineConstants);RHINO8;RHINO7_OR_GREATER;RHINO8_OR_GREATER</DefineConstants>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UseWpf>true</UseWpf>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
|
||||
|
||||
<!-- .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-->
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.21.25188.17001"/>
|
||||
<PackageReference Include="RhinoWindows" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.21.25188.17001"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Rhino\Speckle.Converters.Rhino8\Speckle.Converters.Rhino8.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="EmbeddedResources\**\*" />
|
||||
<EmbeddedResource Include="Resources\**\*.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.RhinoShared\Speckle.Connectors.RhinoShared.projitems" Label="Shared" />
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Toolbars\Speckle.Connectors.Rhino.rui" Link="$(AssemblyName).rui" CopyToOutputDirectory="PreserveNewest"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,370 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0-windows7.0": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"RhinoCommon": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.21.25188.17001, )",
|
||||
"resolved": "8.21.25188.17001",
|
||||
"contentHash": "Wo6JXheyDBvilyIwDY6xZCQJC4170jzAlTSlMgh8yokUY+vYyCl4KJVXZofIOynNt/xx5wLqb2On5gZZekXR6w==",
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "7.0.0"
|
||||
}
|
||||
},
|
||||
"RhinoWindows": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.21.25188.17001, )",
|
||||
"resolved": "8.21.25188.17001",
|
||||
"contentHash": "9zqCorcLRBeiW/j1RTwUS4E7bnZetAdA9WDdtd/AQccjOpxdtw76wdN+ciyQ6qslseWkwZ9qSBeh7QaM800Ntw==",
|
||||
"dependencies": {
|
||||
"RhinoCommon": "[8.21.25188.17001]"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "7.0.0"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.5.3, )",
|
||||
"Speckle.Sdk": "[3.5.3, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.5.3, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "T3xwwoALVGmhIuEjlDrTdDXZ9haFILT32r8OACWrRUItU3xMkOWGyob51Ca1MHPmo8B5gvbk2Gnm8AgReGnxWg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "o+HefwtPZBqyuUHEnKF+qb/ctCAlNc2BYIw3ULEsZ93zweHt5wOMvOeuPxIXR0Gvj3fg6yNlY2nUcdFEduIXYA==",
|
||||
"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.5.3"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.5.3, )",
|
||||
"resolved": "3.5.3",
|
||||
"contentHash": "kC15SE4yZoVTasgywCm0SpY9yjBsQeUIDt4qoscYAgbn9pe0jj3uM0hZeJUCxn9Fdoj64OfQBpCKzR7VqhkwHQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ=="
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "7.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Rhino.DocObjects.Tables;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
using Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Bindings;
|
||||
|
||||
/// <summary>
|
||||
/// Binding for managing Rhino object mappings to Revit categories.
|
||||
/// </summary>
|
||||
public class RhinoMapperBinding : IBinding
|
||||
{
|
||||
private const string MAPPINGS_CHANGED_EVENT = "mappingsChanged";
|
||||
private const string LAYERS_CHANGED_EVENT = "layersChanged";
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IBasicConnectorBinding _basicConnectorBinding;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly RevitMappingResolver _revitMappingResolver;
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
private readonly RhinoObjectHelper _rhinoObjectHelper;
|
||||
public string Name => "revitMapperBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public RhinoMapperBinding(
|
||||
DocumentModelStore store,
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IBasicConnectorBinding basicConnectorBinding,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
RevitMappingResolver revitMappingResolver,
|
||||
RhinoLayerHelper rhinoLayerHelper,
|
||||
RhinoObjectHelper rhinoObjectHelper
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
Parent = parent;
|
||||
_basicConnectorBinding = basicConnectorBinding;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_revitMappingResolver = revitMappingResolver;
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
_rhinoObjectHelper = rhinoObjectHelper;
|
||||
|
||||
// Subscribe to Rhino events so we know about changes
|
||||
// Events fire on delete, undo delete, add and modify objects
|
||||
RhinoDoc.DeleteRhinoObject += OnObjectChanged;
|
||||
RhinoDoc.UndeleteRhinoObject += OnObjectChanged;
|
||||
RhinoDoc.AddRhinoObject += OnObjectChanged;
|
||||
RhinoDoc.ModifyObjectAttributes += OnObjectAttributesChanged;
|
||||
|
||||
// Subscribe to layer events so we know about layer changes
|
||||
RhinoDoc.LayerTableEvent += OnLayerTableEvent;
|
||||
|
||||
// Subscribe to document changes to refresh mappings when switching documents
|
||||
_store.DocumentChanged += OnDocumentChanged;
|
||||
}
|
||||
|
||||
#region UI Methods - General
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of available layers for the UI dropdown.
|
||||
/// </summary>
|
||||
public LayerOption[] GetAvailableLayers()
|
||||
{
|
||||
var doc = RhinoDoc.ActiveDoc;
|
||||
if (doc == null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return doc
|
||||
.Layers.Where(layer => !layer.IsDeleted)
|
||||
.Select(layer => new LayerOption(layer.Id.ToString(), _rhinoLayerHelper.GetFullLayerPath(layer)))
|
||||
.OrderBy(layer => layer.Name)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects/highlights specific objects in Rhino.
|
||||
/// </summary>
|
||||
public async Task HighlightObjects(string[] objectIds) => await _basicConnectorBinding.HighlightObjects(objectIds);
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Methods - Object Mapping Methods
|
||||
|
||||
/// <summary>
|
||||
/// Assigns selected objects to a specific Revit category.
|
||||
/// </summary>
|
||||
public void AssignObjectsToCategory(string[] objectIds, string categoryValue)
|
||||
{
|
||||
foreach (var objectIdString in objectIds)
|
||||
{
|
||||
// NOTE: should we be checking if key already exists?
|
||||
// For POC, straightforward set on object
|
||||
var rhinoObject = _rhinoObjectHelper.GetRhinoObject(objectIdString);
|
||||
var attrs = rhinoObject?.Attributes.Duplicate();
|
||||
attrs?.SetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY, categoryValue);
|
||||
RhinoDoc.ActiveDoc.Objects.ModifyAttributes(rhinoObject, attrs, true);
|
||||
}
|
||||
|
||||
// Trigger single update after all changes
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes category assignments from specific objects.
|
||||
/// </summary>
|
||||
public void ClearObjectsCategoryAssignment(string[] objectIds)
|
||||
{
|
||||
foreach (var objectIdString in objectIds)
|
||||
{
|
||||
var rhinoObject = _rhinoObjectHelper.GetRhinoObject(objectIdString);
|
||||
var attrs = rhinoObject?.Attributes.Duplicate();
|
||||
attrs?.DeleteUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY);
|
||||
RhinoDoc.ActiveDoc.Objects.ModifyAttributes(rhinoObject, attrs, true);
|
||||
}
|
||||
|
||||
// Trigger single update after all changes
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all category assignments in the doc.
|
||||
/// </summary>
|
||||
public void ClearAllObjectsCategoryAssignments()
|
||||
{
|
||||
foreach (var rhinoObject in RhinoDoc.ActiveDoc.Objects)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(rhinoObject.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY)))
|
||||
{
|
||||
var attrs = rhinoObject.Attributes.Duplicate();
|
||||
attrs.DeleteUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY);
|
||||
RhinoDoc.ActiveDoc.Objects.ModifyAttributes(rhinoObject, attrs, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger single update
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all current mappings to show in the UI table.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CategoryMapping[] GetCurrentObjectsMappings()
|
||||
{
|
||||
var mappedObjects = RhinoDoc
|
||||
.ActiveDoc.Objects.Where(obj =>
|
||||
!string.IsNullOrEmpty(obj.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
)
|
||||
.GroupBy(obj => obj.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
.Select(group => new CategoryMapping(
|
||||
group.Key,
|
||||
group.Key,
|
||||
group.Select(obj => obj.Id.ToString()).ToArray(),
|
||||
group.Count()
|
||||
))
|
||||
.ToArray();
|
||||
|
||||
return mappedObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets category mappings for specific object IDs.
|
||||
/// </summary>
|
||||
public string[] GetCategoryMappingsForObjects(string[] objectIds) =>
|
||||
objectIds
|
||||
.Select(id =>
|
||||
_rhinoObjectHelper.GetRhinoObject(id)?.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY)
|
||||
)
|
||||
.Where(category => category != null)
|
||||
.Cast<string>()
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Methods - Layer Mapping Methods
|
||||
|
||||
/// <summary>
|
||||
/// Assigns selected layers to a specific Revit category.
|
||||
/// </summary>
|
||||
public void AssignLayerToCategory(string[] layerIds, string categoryValue)
|
||||
{
|
||||
foreach (var layerId in layerIds)
|
||||
{
|
||||
var layer = _rhinoLayerHelper.GetLayer(layerId);
|
||||
layer?.SetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY, categoryValue);
|
||||
}
|
||||
|
||||
// Trigger single update
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes category assignments from specific layer(s).
|
||||
/// </summary>
|
||||
public void ClearLayerCategoryAssignment(string[] layerIds)
|
||||
{
|
||||
foreach (var layerId in layerIds)
|
||||
{
|
||||
// NOTE: clear user string by setting to null. Layer has not DeleteUserString() method 🙄
|
||||
var layer = _rhinoLayerHelper.GetLayer(layerId);
|
||||
layer?.SetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY, null);
|
||||
}
|
||||
|
||||
// Trigger single update
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all layer category assignments in the doc.
|
||||
/// </summary>
|
||||
public void ClearAllLayerCategoryAssignments()
|
||||
{
|
||||
foreach (var layer in RhinoDoc.ActiveDoc.Layers)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(layer.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY)))
|
||||
{
|
||||
// NOTE: clear user string by setting to null. Layer has not DeleteUserString() method 🙄
|
||||
layer.SetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger single update
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all current layer mappings to show in the UI table.
|
||||
/// Layers with the same category mapping are grouped together.
|
||||
/// </summary>
|
||||
public LayerCategoryMapping[] GetCurrentLayerMappings()
|
||||
{
|
||||
var mappedLayers = RhinoDoc
|
||||
.ActiveDoc.Layers.Where(layer =>
|
||||
!layer.IsDeleted && !string.IsNullOrEmpty(layer.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
)
|
||||
.GroupBy(layer => layer.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
.Select(group => new LayerCategoryMapping(
|
||||
group.Key,
|
||||
group.Key,
|
||||
group.Select(layer => layer.Id.ToString()).ToArray(),
|
||||
group.Select(layer => _rhinoLayerHelper.GetFullLayerPath(layer)).ToArray(),
|
||||
group.Count()
|
||||
))
|
||||
.ToArray();
|
||||
|
||||
return mappedLayers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets category mappings for specific layer IDs.
|
||||
/// </summary>
|
||||
public string[] GetCategoryMappingsForLayers(string[] layerIds) =>
|
||||
layerIds
|
||||
.Select(id => _rhinoLayerHelper.GetLayer(id)?.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
.Where(category => !string.IsNullOrEmpty(category))
|
||||
.Cast<string>()
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
public string[] GetEffectiveObjectsForLayerMapping(string[] layerIds, string categoryValue) =>
|
||||
_revitMappingResolver.GetEffectiveObjectsForLayerMapping(layerIds, categoryValue);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handling
|
||||
|
||||
/// <summary>
|
||||
/// Called when objects are added, deleted, or undeleted in Rhino.
|
||||
/// </summary>
|
||||
private void OnObjectChanged(object? sender, RhinoObjectEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rhinoObject = e.TheObject;
|
||||
if (!string.IsNullOrEmpty(rhinoObject.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY)))
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when object attributes are modified in Rhino.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Includes detection for when objects move between layers with mappings.
|
||||
/// </remarks>
|
||||
private void OnObjectAttributesChanged(object? sender, RhinoModifyObjectAttributesEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rhinoObject = e.RhinoObject;
|
||||
|
||||
// check if mapping user string changed (added, removed, or modified)
|
||||
var oldMapping = e.OldAttributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY);
|
||||
var newMapping = rhinoObject.Attributes.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY);
|
||||
bool mappingChanged = !string.Equals(oldMapping, newMapping, StringComparison.Ordinal);
|
||||
|
||||
// check if layer change affects mappings
|
||||
bool hasOldLayerMapping = _rhinoLayerHelper.HasLayerMapping(e.OldAttributes.LayerIndex);
|
||||
bool hasNewLayerMapping = _rhinoLayerHelper.HasLayerMapping(rhinoObject.Attributes.LayerIndex);
|
||||
|
||||
// refresh if mapping changed OR layer change affects mapped layers
|
||||
if (mappingChanged || hasOldLayerMapping || hasNewLayerMapping)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the document changes (e.g., switching to a different Rhino model).
|
||||
/// Refreshes the mappings table and defined layers to reflect the new document's state.
|
||||
/// </summary>
|
||||
private void OnDocumentChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh mappings for the new document
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
|
||||
// Refresh layer list for the new document
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyLayersChanged), NotifyLayersChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when layer table events occur in Rhino.
|
||||
/// Refreshes layer list when layer structure changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Layer mapping changes are handled by OnObjectAttributesChanged
|
||||
/// </remarks>
|
||||
private void OnLayerTableEvent(object? sender, LayerTableEventArgs e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh layer list for structural changes
|
||||
if (
|
||||
e.EventType == LayerTableEventType.Added
|
||||
|| e.EventType == LayerTableEventType.Deleted
|
||||
|| e.EventType == LayerTableEventType.Modified
|
||||
)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyLayersChanged), NotifyLayersChanged);
|
||||
}
|
||||
|
||||
// Refresh mappings when layers are deleted or modified
|
||||
// This ensures that mappings table updates when mapped layers are removed
|
||||
if (e.EventType == LayerTableEventType.Deleted || e.EventType == LayerTableEventType.Modified)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(NotifyMappingsChanged), NotifyMappingsChanged);
|
||||
}
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Sends updated mappings to the frontend.
|
||||
/// </summary>
|
||||
private void NotifyMappingsChanged()
|
||||
{
|
||||
var currentMappings = GetCurrentObjectsMappings();
|
||||
Parent.Send(MAPPINGS_CHANGED_EVENT, currentMappings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends updated layer list to the frontend.
|
||||
/// </summary>
|
||||
private void NotifyLayersChanged()
|
||||
{
|
||||
var availableLayers = GetAvailableLayers();
|
||||
Parent.Send(LAYERS_CHANGED_EVENT, availableLayers);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -24,6 +24,7 @@ public class RhinoReceiveBinding(
|
||||
|
||||
public async Task Receive(string modelCardId)
|
||||
{
|
||||
// NOTE: introduction of AddVisualizationProperties setting not accounted for in receive pipeline, hence hardcoded as true (i.e. "as before")
|
||||
using var manager = receiveOperationManagerFactory.Create();
|
||||
await manager.Process(
|
||||
Commands,
|
||||
@@ -31,7 +32,7 @@ public class RhinoReceiveBinding(
|
||||
(sp, card) =>
|
||||
{
|
||||
sp.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
|
||||
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc, true));
|
||||
},
|
||||
async (modelName, processor) =>
|
||||
{
|
||||
|
||||
@@ -13,7 +13,9 @@ using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
using Speckle.Connectors.Rhino.Operations.Send.Filters;
|
||||
using Speckle.Connectors.Rhino.Operations.Send.Settings;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -29,11 +31,13 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ToSpeckleSettingsManager _toSpeckleSettingsManager;
|
||||
private readonly ILogger<RhinoSendBinding> _logger;
|
||||
private readonly IRhinoConversionSettingsFactory _rhinoConversionSettingsFactory;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Objects in this list will be reconverted.
|
||||
@@ -59,21 +63,25 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ToSpeckleSettingsManager toSpeckleSettingsManager,
|
||||
ILogger<RhinoSendBinding> logger,
|
||||
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
ISendOperationManagerFactory sendOperationManagerFactory
|
||||
ISendOperationManagerFactory sendOperationManagerFactory,
|
||||
RhinoLayerHelper rhinoLayerHelper
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_toSpeckleSettingsManager = toSpeckleSettingsManager;
|
||||
_logger = logger;
|
||||
_rhinoConversionSettingsFactory = rhinoConversionSettingsFactory;
|
||||
Parent = parent;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_sendOperationManagerFactory = sendOperationManagerFactory;
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
Commands = new SendBindingUICommands(parent); // POC: Commands are tightly coupled with their bindings, at least for now, saves us injecting a factory.
|
||||
PreviousUnitSystem = RhinoDoc.ActiveDoc.ModelUnitSystem;
|
||||
SubscribeToRhinoEvents();
|
||||
@@ -271,9 +279,9 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() =>
|
||||
[new RhinoSelectionFilter() { IsDefault = true }, new RhinoLayersFilter()];
|
||||
[new RhinoSelectionFilter() { IsDefault = true }, new RhinoLayersFilter(_rhinoLayerHelper)];
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
public List<ICardSetting> GetSendSettings() => [new AddVisualizationProperties(false)];
|
||||
|
||||
public async Task Send(string modelCardId)
|
||||
{
|
||||
@@ -282,9 +290,14 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
await manager.Process(
|
||||
Commands,
|
||||
modelCardId,
|
||||
(sp, _) =>
|
||||
(sp, card) =>
|
||||
sp.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
.Initialize(_rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc)),
|
||||
.Initialize(
|
||||
_rhinoConversionSettingsFactory.Create(
|
||||
RhinoDoc.ActiveDoc,
|
||||
_toSpeckleSettingsManager.GetAddVisualizationPropertiesSetting(card)
|
||||
)
|
||||
),
|
||||
card =>
|
||||
{
|
||||
return Task.FromResult<IReadOnlyList<RhinoObject>>(
|
||||
|
||||
+91
-7
@@ -1,5 +1,7 @@
|
||||
using Rhino;
|
||||
using Rhino.Collections;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp.Properties;
|
||||
@@ -9,12 +11,84 @@ namespace Speckle.Connectors.Rhino.HostApp.Properties;
|
||||
/// </summary>
|
||||
public class PropertiesExtractor
|
||||
{
|
||||
private readonly RevitMappingResolver _revitMappingResolver;
|
||||
|
||||
public PropertiesExtractor(RevitMappingResolver revitMappingResolver)
|
||||
{
|
||||
_revitMappingResolver = revitMappingResolver;
|
||||
}
|
||||
|
||||
public Dictionary<string, object?> GetProperties(RhinoObject rhObject)
|
||||
{
|
||||
Dictionary<string, object?> properties = new();
|
||||
var userStrings = rhObject.Attributes.GetUserStrings();
|
||||
foreach (var key in userStrings.AllKeys)
|
||||
Dictionary<string, object?> properties = GetUserStrings(rhObject);
|
||||
|
||||
Dictionary<string, object?> userDict = GetUserDict(rhObject);
|
||||
if (userDict.Count > 0)
|
||||
{
|
||||
properties["User Dictionary"] = userDict;
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private Dictionary<string, object?> GetUserDict(RhinoObject rhObject)
|
||||
{
|
||||
Dictionary<string, object?> userDict = new();
|
||||
if (rhObject.Attributes.UserDictionary != null && rhObject.Attributes.UserDictionary.Count > 0)
|
||||
{
|
||||
ParseArchivableToDictionary(userDict, rhObject.Attributes.UserDictionary);
|
||||
}
|
||||
|
||||
return userDict;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies an ArchivableDictionary to a Dictionary
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="dict"></param>
|
||||
private void ParseArchivableToDictionary(Dictionary<string, object?> target, ArchivableDictionary dict)
|
||||
{
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
var obj = dict[key];
|
||||
switch (obj)
|
||||
{
|
||||
case ArchivableDictionary o:
|
||||
Dictionary<string, object?> nested = new();
|
||||
ParseArchivableToDictionary(nested, o);
|
||||
target[key] = nested;
|
||||
continue;
|
||||
|
||||
case double:
|
||||
case bool:
|
||||
case int:
|
||||
case string:
|
||||
case IEnumerable<double>:
|
||||
case IEnumerable<bool>:
|
||||
case IEnumerable<int>:
|
||||
case IEnumerable<string>:
|
||||
target[key] = obj;
|
||||
continue;
|
||||
|
||||
default:
|
||||
target[key] = obj.ToString();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, object?> GetUserStrings(RhinoObject rhObject)
|
||||
{
|
||||
Dictionary<string, object?> userStringDict = new();
|
||||
var userStrings = rhObject.Attributes.GetUserStrings();
|
||||
foreach (string? key in userStrings.AllKeys)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (key == "$block-instance-original-object-id$") // skip: this seems to be an invisible user string that shows up on block instances
|
||||
@@ -22,10 +96,10 @@ public class PropertiesExtractor
|
||||
continue;
|
||||
}
|
||||
|
||||
if (userStrings[key].StartsWith("%<"))
|
||||
if (userStrings[key]?.StartsWith("%<") ?? false)
|
||||
{
|
||||
var value = RhinoApp.ParseTextField(userStrings[key], rhObject, null);
|
||||
properties[key] = value;
|
||||
userStringDict[key] = value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -34,9 +108,19 @@ public class PropertiesExtractor
|
||||
// Shh. We can fail silently here - it's not even worth logging. I expect users will complain properties are missing.
|
||||
}
|
||||
|
||||
properties[key] = userStrings[key];
|
||||
userStringDict[key] = userStrings[key];
|
||||
}
|
||||
|
||||
return properties;
|
||||
// NOTE: if no mapping was found on the object, check layer(s) recursively
|
||||
if (!userStringDict.ContainsKey(RevitMappingConstants.CATEGORY_USER_STRING_KEY))
|
||||
{
|
||||
var layerMapping = _revitMappingResolver.SearchLayerHierarchyForMapping(rhObject);
|
||||
if (!string.IsNullOrEmpty(layerMapping))
|
||||
{
|
||||
userStringDict[RevitMappingConstants.CATEGORY_USER_STRING_KEY] = layerMapping;
|
||||
}
|
||||
}
|
||||
|
||||
return userStringDict;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class RhinoGroupBaker
|
||||
Dictionary<string, IReadOnlyCollection<string>> applicationIdMap
|
||||
)
|
||||
{
|
||||
if (applicationIdMap.TryGetValue(oldObjId, out IReadOnlyCollection<string> value))
|
||||
if (applicationIdMap.TryGetValue(oldObjId, out IReadOnlyCollection<string>? value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -13,14 +13,17 @@ namespace Speckle.Connectors.Rhino.HostApp;
|
||||
public class RhinoInstanceUnpacker : IInstanceUnpacker<RhinoObject>
|
||||
{
|
||||
private readonly IInstanceObjectsManager<RhinoObject, List<string>> _instanceObjectsManager;
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
private readonly ILogger<RhinoInstanceUnpacker> _logger;
|
||||
|
||||
public RhinoInstanceUnpacker(
|
||||
IInstanceObjectsManager<RhinoObject, List<string>> instanceObjectsManager,
|
||||
RhinoLayerHelper rhinoLayerHelper,
|
||||
ILogger<RhinoInstanceUnpacker> logger
|
||||
)
|
||||
{
|
||||
_instanceObjectsManager = instanceObjectsManager;
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -109,7 +112,12 @@ public class RhinoInstanceUnpacker : IInstanceUnpacker<RhinoObject>
|
||||
|
||||
_instanceObjectsManager.AddDefinitionProxy(instance.InstanceDefinition.Id.ToString(), definition);
|
||||
|
||||
foreach (var obj in instance.InstanceDefinition.GetObjects())
|
||||
// NOTE: InstanceDefinition.GetObjects() returns all constituent objects of a block, but those constituent
|
||||
// objects can be on layers, that are not visible. The publish should respect that.
|
||||
// See request: [CNX-2254](https://linear.app/speckle/issue/CNX-2254/rhino-publish-blocks-with-hidden-objects)
|
||||
var allDefinitionObjects = instance.InstanceDefinition.GetObjects();
|
||||
var visibleDefinitionObjects = _rhinoLayerHelper.FilterByLayerVisibility(allDefinitionObjects);
|
||||
foreach (var obj in visibleDefinitionObjects)
|
||||
{
|
||||
definition.objects.Add(obj.Id.ToString());
|
||||
if (obj is InstanceObject localInstance)
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for common Rhino layer and object operations.
|
||||
/// Consolidates layer utilities to eliminate duplication across the codebase.
|
||||
/// </summary>
|
||||
public class RhinoLayerHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets list of available layers for UI dropdowns.
|
||||
/// </summary>
|
||||
public LayerOption[] GetAvailableLayers()
|
||||
{
|
||||
var doc = RhinoDoc.ActiveDoc;
|
||||
if (doc == null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return doc
|
||||
.Layers.Where(layer => !layer.IsDeleted)
|
||||
.Select(layer => new LayerOption(layer.Id.ToString(), GetFullLayerPath(layer)))
|
||||
.OrderBy(layer => layer.Name)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full layer path with / delimiter
|
||||
/// </summary>
|
||||
public string GetFullLayerPath(Layer layer)
|
||||
{
|
||||
string fullPath = layer.Name;
|
||||
Guid parentIndex = layer.ParentLayerId;
|
||||
while (parentIndex != Guid.Empty)
|
||||
{
|
||||
Layer? parentLayer = RhinoDoc.ActiveDoc.Layers.FindId(parentIndex);
|
||||
if (parentLayer == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fullPath = parentLayer.Name + "/" + fullPath; // use "/" delimiter
|
||||
parentIndex = parentLayer.ParentLayerId;
|
||||
}
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string layer ID to a Layer.
|
||||
/// </summary>
|
||||
/// <returns>Layer if found and valid, null otherwise</returns>
|
||||
public Layer? GetLayer(string layerIdString) =>
|
||||
Guid.TryParse(layerIdString, out var layerId) ? RhinoDoc.ActiveDoc.Layers.FindId(layerId) : null;
|
||||
|
||||
/// <summary>
|
||||
/// Helper to check if a layer (by index) has a category mapping.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is arguably a very specific method pertaining to mapper and maybe shouldn't be in this class?
|
||||
/// </remarks>
|
||||
public bool HasLayerMapping(int layerIndex)
|
||||
{
|
||||
if (layerIndex < 0 || layerIndex >= RhinoDoc.ActiveDoc.Layers.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var layer = RhinoDoc.ActiveDoc.Layers[layerIndex];
|
||||
return !string.IsNullOrEmpty(layer.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all RhinoObjects in the specified layer and all its child layers recursively.
|
||||
/// </summary>
|
||||
public IEnumerable<RhinoObject> GetObjectsInLayerHierarchy(Layer rootLayer)
|
||||
{
|
||||
var allObjects = new List<RhinoObject>();
|
||||
var layersToSearch = GetLayerAndAllChildren(rootLayer);
|
||||
|
||||
foreach (var layer in layersToSearch)
|
||||
{
|
||||
var objectsOnLayer = RhinoDoc.ActiveDoc.Objects.FindByLayer(layer);
|
||||
allObjects.AddRange(objectsOnLayer);
|
||||
}
|
||||
|
||||
return allObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified layer and all its child layers recursively.
|
||||
/// </summary>
|
||||
public IEnumerable<Layer> GetLayerAndAllChildren(Layer rootLayer)
|
||||
{
|
||||
// Return the root layer itself
|
||||
yield return rootLayer;
|
||||
|
||||
// Get all child layers recursively
|
||||
foreach (var childLayer in GetAllChildLayers(rootLayer))
|
||||
{
|
||||
yield return childLayer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recursively gets all child layers of the specified parent layer.
|
||||
/// </summary>
|
||||
public IEnumerable<Layer> GetAllChildLayers(Layer parentLayer)
|
||||
{
|
||||
var doc = RhinoDoc.ActiveDoc;
|
||||
if (doc?.Layers == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Find all direct child layers
|
||||
var directChildren = doc.Layers.Where(layer => layer.ParentLayerId == parentLayer.Id);
|
||||
|
||||
foreach (var childLayer in directChildren)
|
||||
{
|
||||
// Return the direct child
|
||||
yield return childLayer;
|
||||
|
||||
// Recursively get grandchildren
|
||||
foreach (var grandChild in GetAllChildLayers(childLayer))
|
||||
{
|
||||
yield return grandChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a layer is visible by its index.
|
||||
/// </summary>
|
||||
public bool IsLayerVisible(int layerIndex)
|
||||
{
|
||||
if (layerIndex < 0 || layerIndex >= RhinoDoc.ActiveDoc.Layers.Count)
|
||||
{
|
||||
return true; // default to visible for invalid indices (safe fallback)
|
||||
}
|
||||
|
||||
var layer = RhinoDoc.ActiveDoc.Layers[layerIndex];
|
||||
return layer != null && !layer.IsDeleted && layer.IsVisible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters a collection of objects to only include those on visible layers.
|
||||
/// </summary>
|
||||
public IEnumerable<T> FilterByLayerVisibility<T>(IEnumerable<T> objects)
|
||||
where T : RhinoObject => objects.Where(obj => IsLayerVisible(obj.Attributes.LayerIndex));
|
||||
}
|
||||
@@ -14,6 +14,7 @@ namespace Speckle.Connectors.Rhino.HostApp;
|
||||
/// </summary>
|
||||
public class RhinoLayerUnpacker
|
||||
{
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
private readonly Dictionary<int, Collection> _layerCollectionCache = new();
|
||||
|
||||
private static readonly string s_pathSeparator =
|
||||
@@ -24,6 +25,11 @@ public class RhinoLayerUnpacker
|
||||
#endif
|
||||
private static readonly string[] s_pathSeparatorSplit = [s_pathSeparator];
|
||||
|
||||
public RhinoLayerUnpacker(RhinoLayerHelper rhinoLayerHelper)
|
||||
{
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this method to get all of the layers that correspond to collection created in the root collection.
|
||||
/// </summary>
|
||||
@@ -31,20 +37,16 @@ public class RhinoLayerUnpacker
|
||||
/// <exception cref="SpeckleException">Throws when a layer could not be retrieved from a stored collection application id</exception>
|
||||
public IEnumerable<Layer> GetUsedLayers()
|
||||
{
|
||||
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
|
||||
|
||||
foreach (string layerId in _layerCollectionCache.Values.Select(o => o.applicationId ?? string.Empty).ToList())
|
||||
{
|
||||
if (Guid.TryParse(layerId, out Guid layerGuid))
|
||||
var layer = _rhinoLayerHelper.GetLayer(layerId);
|
||||
if (layer != null)
|
||||
{
|
||||
if (currentDoc.Layers.FindId(layerGuid) is Layer layer)
|
||||
{
|
||||
yield return layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SpeckleException($"Could not retrieve layer with guid: {layerId}.");
|
||||
}
|
||||
yield return layer;
|
||||
}
|
||||
else if (Guid.TryParse(layerId, out _))
|
||||
{
|
||||
throw new SpeckleException($"Could not retrieve layer with guid: {layerId}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -177,7 +177,7 @@ public class RhinoMaterialUnpacker
|
||||
}
|
||||
|
||||
// converts a rhino material to a rhino render material
|
||||
private RenderMaterial? ConvertMaterialToRenderMaterial(Material material)
|
||||
private static RenderMaterial? ConvertMaterialToRenderMaterial(Material material)
|
||||
{
|
||||
// get physically based render material
|
||||
Material pbMaterial = material;
|
||||
@@ -188,7 +188,18 @@ public class RhinoMaterialUnpacker
|
||||
pbMaterial.ToPhysicallyBased();
|
||||
}
|
||||
|
||||
return RenderMaterial.FromMaterial(pbMaterial, null);
|
||||
var result = RenderMaterial.FromMaterial(pbMaterial, null);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
// We're seeing some weird behaviour running in the File Importer
|
||||
// where RenderMaterial.FromMaterial returns null.
|
||||
// Could be related to headless RhinoDoc or windowless RhinoCore (unsure the cause)
|
||||
// CreateBasicMaterial appears to work, so we'll use it as fall back
|
||||
result = RenderMaterial.CreateBasicMaterial(pbMaterial, null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SpeckleRenderMaterial ConvertRenderMaterialToSpeckle(RenderMaterial renderMaterial)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for common Rhino object operations.
|
||||
/// </summary>
|
||||
public class RhinoObjectHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a string object ID to a RhinoObject.
|
||||
/// </summary>
|
||||
/// <returns>RhinoObject if found and valid, null otherwise</returns>
|
||||
public RhinoObject? GetRhinoObject(string objectIdString) =>
|
||||
Guid.TryParse(objectIdString, out var objectId) ? RhinoDoc.ActiveDoc.Objects.FindId(objectId) : null;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a group of objects that are all assigned to the same category.
|
||||
/// </summary>
|
||||
public record CategoryMapping(
|
||||
string CategoryValue,
|
||||
string CategoryLabel,
|
||||
IReadOnlyList<string> ObjectIds,
|
||||
int ObjectCount
|
||||
);
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
/// <summary>
|
||||
/// Represents layers that are all assigned to the same category.
|
||||
/// </summary>
|
||||
public record LayerCategoryMapping(
|
||||
string CategoryValue,
|
||||
string CategoryLabel,
|
||||
IReadOnlyList<string> LayerIds,
|
||||
IReadOnlyList<string> LayerNames,
|
||||
int LayerCount
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a layer option for the UI dropdown.
|
||||
/// </summary>
|
||||
public record LayerOption(string Id, string Name);
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
/// <summary>
|
||||
/// Shared constants for the Rhino-to-Revit mapping system.
|
||||
/// Centralizes string constant(s) to avoid duplication across three using classes.
|
||||
/// </summary>
|
||||
public static class RevitMappingConstants
|
||||
{
|
||||
public const string CATEGORY_USER_STRING_KEY = "builtInCategory";
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for resolving category mappings from layer hierarchy.
|
||||
/// Used by the send pipeline to resolve mappings during property extraction.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This gets called when no mapping found on the object level.
|
||||
/// </remarks>
|
||||
public class RevitMappingResolver
|
||||
{
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
|
||||
public RevitMappingResolver(RhinoLayerHelper rhinoLayerHelper)
|
||||
{
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all objects that would effectively receive the specified layer mapping during send.
|
||||
/// Takes into account hierarchical resolution - only returns objects that would actually
|
||||
/// resolve to this specific category value through the layer hierarchy.
|
||||
/// </summary>
|
||||
public string[] GetEffectiveObjectsForLayerMapping(string[] layerIds, string categoryValue)
|
||||
{
|
||||
var effectiveObjects = new List<string>();
|
||||
|
||||
foreach (var layerId in layerIds)
|
||||
{
|
||||
var layer = _rhinoLayerHelper.GetLayer(layerId);
|
||||
if (layer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get all objects in this layer and its child layers
|
||||
var allObjectsInHierarchy = _rhinoLayerHelper.GetObjectsInLayerHierarchy(layer);
|
||||
|
||||
foreach (var obj in allObjectsInHierarchy)
|
||||
{
|
||||
// Since we're in Layer mode, objects don't have direct mappings
|
||||
// Check what category this object would actually resolve to through layer hierarchy
|
||||
var resolvedCategory = SearchLayerHierarchyForMapping(obj);
|
||||
|
||||
// Only include if it resolves to THIS specific category
|
||||
if (resolvedCategory == categoryValue)
|
||||
{
|
||||
effectiveObjects.Add(obj.Id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return effectiveObjects.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traverses layer hierarchy, returns first mapping found or null
|
||||
/// </summary>
|
||||
public string? SearchLayerHierarchyForMapping(RhinoObject rhinoObject)
|
||||
{
|
||||
// NOTE: we agreed on a hierarchical resolution strategy:
|
||||
// - Object-level mappings have highest precedence
|
||||
// - Layer-level mappings are fallback when no object mapping exists
|
||||
// - Traverses layer hierarchy and stops at first mapping found
|
||||
|
||||
var layer = GetLayerByIndex(rhinoObject.Attributes.LayerIndex);
|
||||
while (layer != null)
|
||||
{
|
||||
var layerMapping = layer.GetUserString(RevitMappingConstants.CATEGORY_USER_STRING_KEY);
|
||||
if (!string.IsNullOrEmpty(layerMapping))
|
||||
{
|
||||
return layerMapping; // returns first mapping found
|
||||
}
|
||||
|
||||
// move to parent layer
|
||||
layer = GetParentLayer(layer);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a layer by its index from the active doc.
|
||||
/// </summary>
|
||||
private Layer? GetLayerByIndex(int layerIndex)
|
||||
{
|
||||
var doc = RhinoDoc.ActiveDoc;
|
||||
if (doc?.Layers == null || layerIndex < 0 || layerIndex >= doc.Layers.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return doc.Layers[layerIndex];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent layer of the given layer.
|
||||
/// </summary>
|
||||
private Layer? GetParentLayer(Layer layer)
|
||||
{
|
||||
if (layer.ParentLayerId == Guid.Empty)
|
||||
{
|
||||
return null; // no parent layer
|
||||
}
|
||||
|
||||
var doc = RhinoDoc.ActiveDoc;
|
||||
return doc?.Layers?.FindId(layer.ParentLayerId);
|
||||
}
|
||||
}
|
||||
+12
-27
@@ -2,11 +2,14 @@ using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Operations.Send.Filters;
|
||||
|
||||
public class RhinoLayersFilter : DiscriminatedObject, ISendFilter
|
||||
{
|
||||
private readonly RhinoLayerHelper _rhinoLayerHelper;
|
||||
|
||||
public string Id { get; set; } = "rhinoLayers";
|
||||
public string Name { get; set; } = "Layers";
|
||||
public string Type { get; set; } = "Select";
|
||||
@@ -19,7 +22,10 @@ public class RhinoLayersFilter : DiscriminatedObject, ISendFilter
|
||||
public List<SendFilterSelectItem> SelectedItems { get; set; }
|
||||
public List<SendFilterSelectItem> Items => GetFilterItems();
|
||||
|
||||
public RhinoLayersFilter() { }
|
||||
public RhinoLayersFilter(RhinoLayerHelper rhinoLayerHelper)
|
||||
{
|
||||
_rhinoLayerHelper = rhinoLayerHelper;
|
||||
}
|
||||
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
@@ -32,14 +38,11 @@ public class RhinoLayersFilter : DiscriminatedObject, ISendFilter
|
||||
|
||||
foreach (var item in SelectedItems)
|
||||
{
|
||||
if (Guid.TryParse(item.Id, out Guid layerId))
|
||||
Layer? layer = _rhinoLayerHelper.GetLayer(item.Id);
|
||||
if (layer != null)
|
||||
{
|
||||
Layer layer = doc.Layers.FindId(layerId);
|
||||
if (layer != null)
|
||||
{
|
||||
var objectIds = doc.Objects.FindByLayer(layer).Select(obj => obj.Id.ToString());
|
||||
SelectedObjectIds.AddRange(objectIds);
|
||||
}
|
||||
var objectIds = doc.Objects.FindByLayer(layer).Select(obj => obj.Id.ToString());
|
||||
SelectedObjectIds.AddRange(objectIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,28 +62,10 @@ public class RhinoLayersFilter : DiscriminatedObject, ISendFilter
|
||||
{
|
||||
if (!layer.IsDeleted)
|
||||
{
|
||||
filterItems.Add(new SendFilterSelectItem(layer.Id.ToString(), GetFullLayerPath(layer)));
|
||||
filterItems.Add(new SendFilterSelectItem(layer.Id.ToString(), _rhinoLayerHelper.GetFullLayerPath(layer)));
|
||||
}
|
||||
}
|
||||
|
||||
return filterItems;
|
||||
}
|
||||
|
||||
private string GetFullLayerPath(Layer layer)
|
||||
{
|
||||
string fullPath = layer.Name;
|
||||
Guid parentIndex = layer.ParentLayerId;
|
||||
while (parentIndex != Guid.Empty)
|
||||
{
|
||||
Layer parentLayer = RhinoDoc.ActiveDoc.Layers.FindId(parentIndex);
|
||||
if (parentLayer == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fullPath = parentLayer.Name + "/" + fullPath;
|
||||
parentIndex = parentLayer.ParentLayerId;
|
||||
}
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Operations.Send.Settings;
|
||||
|
||||
public class AddVisualizationProperties(bool value) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "addVisualizationProperties";
|
||||
public string? Title { get; set; } = "Add visualization properties for meshes (will increase model size)";
|
||||
public string? Type { get; set; } = "boolean";
|
||||
public object? Value { get; set; } = value;
|
||||
public List<string>? Enum { get; set; }
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Operations.Send.Settings;
|
||||
|
||||
public class ToSpeckleSettingsManager
|
||||
{
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly Dictionary<string, bool?> _addVisualizationPropertiesCache = [];
|
||||
|
||||
public ToSpeckleSettingsManager(ISendConversionCache sendConversionCache)
|
||||
{
|
||||
_sendConversionCache = sendConversionCache;
|
||||
}
|
||||
|
||||
public bool GetAddVisualizationPropertiesSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "addVisualizationProperties")?.Value as bool?;
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_addVisualizationPropertiesCache.TryGetValue(modelCard.ModelCardId.NotNull(), out bool? previousValue))
|
||||
{
|
||||
if (previousValue != returnValue)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
|
||||
_addVisualizationPropertiesCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
|
||||
_sendConversionCache.EvictObjects(objectIds);
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -17,8 +17,10 @@ using Speckle.Connectors.Rhino.Bindings;
|
||||
using Speckle.Connectors.Rhino.Filters;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
using Speckle.Connectors.Rhino.HostApp.Properties;
|
||||
using Speckle.Connectors.Rhino.Mapper.Revit;
|
||||
using Speckle.Connectors.Rhino.Operations.Receive;
|
||||
using Speckle.Connectors.Rhino.Operations.Send;
|
||||
using Speckle.Connectors.Rhino.Operations.Send.Settings;
|
||||
using Speckle.Connectors.Rhino.Plugin;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
|
||||
@@ -34,10 +36,10 @@ public static class ServiceRegistration
|
||||
serviceCollection.AddSingleton<PlugIn>(SpeckleConnectorsRhinoPlugin.Instance);
|
||||
serviceCollection.AddSingleton<Command>(SpeckleConnectorsRhinoCommand.Instance);
|
||||
serviceCollection.AddDUI<DefaultThreadContext, RhinoDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
}
|
||||
|
||||
serviceCollection.AddConnectors();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
serviceCollection.AddSingleton<IBinding, TestBinding>();
|
||||
@@ -50,11 +52,15 @@ public static class ServiceRegistration
|
||||
serviceCollection.AddSingleton<IBinding, RhinoSelectionBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, RhinoSendBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, RhinoReceiveBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, RhinoMapperBinding>();
|
||||
|
||||
// register send filters
|
||||
serviceCollection.AddScoped<ISendFilter, RhinoSelectionFilter>();
|
||||
serviceCollection.AddScoped<IHostObjectBuilder, RhinoHostObjectBuilder>();
|
||||
|
||||
// register send settings
|
||||
serviceCollection.AddScoped<ToSpeckleSettingsManager>();
|
||||
|
||||
// register send conversion cache
|
||||
serviceCollection.AddSingleton<ISendConversionCache, SendConversionCache>();
|
||||
serviceCollection.AddSingleton<IAppIdleManager, RhinoIdleManager>();
|
||||
@@ -86,6 +92,11 @@ public static class ServiceRegistration
|
||||
serviceCollection.AddScoped<RhinoColorUnpacker>();
|
||||
|
||||
serviceCollection.AddScoped<PropertiesExtractor>();
|
||||
serviceCollection.AddScoped<RevitMappingResolver>();
|
||||
|
||||
// register helpers
|
||||
serviceCollection.AddScoped<RhinoLayerHelper>();
|
||||
serviceCollection.AddScoped<RhinoObjectHelper>();
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user