Compare commits

..

1 Commits

Author SHA1 Message Date
JR-Morgan 4fef78143d blobs-poc 2025-11-13 10:08:21 +03:00
206 changed files with 3102 additions and 6491 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -20,7 +20,7 @@ jobs:
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
- name: Cache Nuget
uses: actions/cache@v5
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
+3 -3
View File
@@ -16,7 +16,7 @@ jobs:
file_version: ${{ steps.set-version.outputs.file_version }}
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -26,7 +26,7 @@ jobs:
dotnet-version: 8.0.4xx # Align with global.json (including roll forward rules)
- name: Cache Nuget
uses: actions/cache@v5
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
@@ -35,7 +35,7 @@ jobs:
run: ./build.ps1 zip
- name: ⬆️ Upload artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v5
with:
name: output-${{ env.SEMVER }}
path: output/*.*
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -312,9 +292,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -353,15 +356,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -312,9 +292,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -353,15 +356,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -313,9 +293,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -155,25 +155,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -229,8 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -262,9 +244,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -303,15 +306,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
"net8.0-windows7.0/win-x64": {
@@ -155,25 +155,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -229,8 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -262,9 +244,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -303,15 +306,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
"net8.0-windows7.0/win-x64": {
@@ -178,27 +178,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -289,8 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -322,9 +302,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -363,15 +366,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -178,27 +178,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -289,8 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -322,9 +302,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -363,15 +366,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -178,27 +178,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -289,8 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -322,9 +302,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -363,15 +366,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -164,25 +164,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -238,8 +219,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -272,9 +254,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -313,15 +316,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
"net8.0-windows7.0/win-x64": {
@@ -164,25 +164,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -238,8 +219,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -272,9 +254,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -313,15 +316,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
"net8.0-windows7.0/win-x64": {
@@ -153,7 +153,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
requestedResultTypes,
objectSelectionSummary
);
rootObjectCollection[RootKeys.ANALYSIS_RESULTS] = analysisResults;
rootObjectCollection["analysisResults"] = analysisResults;
}
catch (Exception ex)
{
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.etabs21": {
@@ -314,6 +294,29 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -352,15 +355,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -155,25 +155,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -229,8 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -254,7 +236,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.etabs22": {
@@ -263,6 +245,27 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -301,15 +304,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
+17 -47
View File
@@ -2,63 +2,33 @@
<Project>
<PropertyGroup>
<UseWpf>true</UseWpf>
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
<Authors>$(Authors) jonathon@speckle.systems</Authors>
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworks.bundle</PluginBundleTarget>
<PluginVersionContentTarget>$(PluginBundleTarget)\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworks.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
<RootNamespace>Speckle.Connector.Navisworks</RootNamespace>
</PropertyGroup>
<Target Name="PostBuild"
AfterTargets="Build"
Condition="'$(OS)' == 'Windows_NT' and '$(NavisworksVersion)' != ''">
<!-- Post Builds -->
<ItemGroup>
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
<AllFiles Include="$(OutDir)*"/>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="Build" Condition="'$(NavisworksVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<Message Text="Navisworks Version $(NavisworksVersion)" Importance="high"/>
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
<MakeDir Directories="
$(PluginBundleTarget);
$(PluginBundleTarget)\Contents;
$(PluginVersionContentTarget);
$(PluginVersionContentTarget)\en-US;
$(PluginVersionContentTarget)\Resources"/>
<!-- Re-evaluate outputs at execution time -->
<ItemGroup>
<PackageXml Include="$(OutDir)Plugin\PackageContents.xml"/>
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
<ResourceFiles Include="$(OutDir)Resources\**\*.png;$(OutDir)Resources\**\*.ico"/>
<AllFiles Include="$(OutDir)**\*.*"/>
<Message Text="AllFiles count: @(AllFiles->Count())" Importance="high"/>
<Warning Condition="'@(AllFiles)' == ''" Text="No files in $(OutDir) at PostBuild time."/>
</ItemGroup>
<Copy SourceFiles="@(PackageXml)"
DestinationFolder="$(PluginBundleTarget)\"
SkipUnchangedFiles="true"/>
<Copy SourceFiles="@(RibbonFiles)"
DestinationFolder="$(PluginVersionContentTarget)\en-US\"
SkipUnchangedFiles="true"/>
<Copy SourceFiles="@(ResourceFiles)"
DestinationFiles="@(ResourceFiles->'$(PluginVersionContentTarget)\Resources\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"/>
<Copy SourceFiles="@(AllFiles)"
DestinationFiles="@(AllFiles->'$(PluginVersionContentTarget)\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"/>
<Message Text="Copied build to $(PluginVersionContentTarget)" Importance="high"/>
</Target>
<Target Name="ValidateNavisworksVersion" BeforeTargets="PostBuild"
Condition="'$(NavisworksVersion)' == '' and '$(OS)' == 'Windows_NT'">
<Error Text="NavisworksVersion property is required for PostBuild packaging."/>
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
</Target>
</Project>
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2020": {
@@ -316,6 +296,29 @@
"Speckle.Navisworks.API": "[2020.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2021": {
@@ -316,6 +296,29 @@
"Speckle.Navisworks.API": "[2021.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2022": {
@@ -316,6 +296,29 @@
"Speckle.Navisworks.API": "[2022.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2023": {
@@ -316,6 +296,29 @@
"Speckle.Navisworks.API": "[2023.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2024": {
@@ -316,6 +296,29 @@
"Speckle.Navisworks.API": "[2024.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -175,27 +175,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -286,8 +265,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -311,7 +291,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2025": {
@@ -322,6 +302,29 @@
"Speckle.Navisworks.API": "[2025.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -354,15 +357,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -184,27 +184,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -287,8 +266,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -312,7 +292,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.navisworks2026": {
@@ -324,6 +304,29 @@
"System.Reactive": "[6.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -356,15 +359,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -15,7 +15,6 @@ using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.WebView;
using Speckle.Converter.Navisworks.Services;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk.Models.GraphTraversal;
@@ -53,9 +52,6 @@ public static class NavisworksConnectorServiceRegistration
serviceCollection.AddScoped<NavisworksMaterialUnpacker>();
serviceCollection.AddScoped<NavisworksColorUnpacker>();
// Register dual shared geometry stores for instancing pattern
serviceCollection.AddScoped<InstanceStoreManager>();
serviceCollection.AddSingleton<IAppIdleManager, NavisworksIdleManager>();
// Sending operations
@@ -16,13 +16,7 @@ public class NavisworksColorUnpacker(
IElementSelectionService selectionService
)
{
private static T SelectByRepresentationMode<T>(
RepresentationMode mode,
T active,
T permanent,
T original,
T defaultValue
) =>
private static T Select<T>(RepresentationMode mode, T active, T permanent, T original, T defaultValue) =>
mode switch
{
RepresentationMode.Active => active,
@@ -77,14 +71,14 @@ public class NavisworksColorUnpacker(
using var defaultColor = new NAV.Color(1.0, 1.0, 1.0);
var representationColor = SelectByRepresentationMode(
var representationColor = Select(
mode,
geometry.ActiveColor,
geometry.PermanentColor,
geometry.OriginalColor,
defaultColor
);
var colorId = SelectByRepresentationMode(
var colorId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
$"{geometry.PermanentColor.GetHashCode()}_{geometry.PermanentTransparency}".GetHashCode(),
@@ -130,49 +124,30 @@ public class NavisworksColorUnpacker(
var comSelection = ComBridge.ToInwOpSelection([modelItem]);
try
{
var pathsCollection = comSelection.Paths();
try
foreach (ComApi.InwOaPath path in comSelection.Paths())
{
foreach (ComApi.InwOaPath path in pathsCollection)
{
var fragmentsCollection = path.Fragments();
try
{
foreach (ComApi.InwOaFragment3 fragment in fragmentsCollection.OfType<ComApi.InwOaFragment3>())
{
fragment.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, primitiveChecker);
GC.KeepAlive(path);
if (primitiveChecker.HasTriangles)
{
return false;
}
}
}
finally
foreach (ComApi.InwOaFragment3 fragment in path.Fragments())
{
GC.KeepAlive(fragment);
fragment.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, primitiveChecker);
// Exit early if triangles are found
if (primitiveChecker.HasTriangles)
{
if (fragmentsCollection != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(fragmentsCollection);
}
return false;
}
}
}
return primitiveChecker.HasLines || primitiveChecker.HasPoints || primitiveChecker.HasSnapPoints;
}
finally
{
if (pathsCollection != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(pathsCollection);
}
}
// Return true if any 2D primitives are found
return primitiveChecker.HasLines || primitiveChecker.HasPoints || primitiveChecker.HasSnapPoints;
}
finally
{
if (comSelection != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
}
}
}
@@ -1,11 +1,7 @@
using Autodesk.Navisworks.Api.ComApi;
using Autodesk.Navisworks.Api.Interop.ComApi;
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Constants;
using Speckle.Converter.Navisworks.Helpers;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converter.Navisworks.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Objects.Other;
using Speckle.Sdk;
@@ -15,17 +11,12 @@ namespace Speckle.Connector.Navisworks.HostApp;
public class NavisworksMaterialUnpacker(
ILogger<NavisworksMaterialUnpacker> logger,
IConverterSettingsStore<NavisworksConversionSettings> converterSettings,
IElementSelectionService selectionService,
GeometryToSpeckleConverter converter
IElementSelectionService selectionService
)
{
private static T SelectByRepresentationMode<T>(
RepresentationMode mode,
T active,
T permanent,
T original,
T defaultValue
) =>
// Helper function to select a property based on the representation mode
// Selector method for individual properties
private static T Select<T>(RepresentationMode mode, T active, T permanent, T original, T defaultValue) =>
mode switch
{
RepresentationMode.Active => active,
@@ -73,87 +64,26 @@ public class NavisworksMaterialUnpacker(
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
string hashId = "";
try
{
var item = selectionService.GetModelItemFromPath(finalId);
var comSelection = ComApiBridge.ToInwOpSelection([item]);
try
{
var paths = comSelection.Paths();
try
{
if (paths.Count > 0)
{
var firstPath = paths.OfType<InwOaPath>().FirstOrDefault();
if (firstPath != null)
{
var fragments = firstPath.Fragments();
try
{
if (fragments.Count > 1)
{
var fragmentId = converter.GenerateFragmentId(paths);
hashId = $"{InstanceConstants.GEOMETRY_ID_PREFIX}{fragmentId}";
}
}
finally
{
if (fragments != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(fragments);
}
}
}
}
}
finally
{
if (paths != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(paths);
}
}
}
finally
{
if (comSelection != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
}
}
}
catch (Exception ex) when (!ex.IsFatal())
{ // If COM interop fails during hash generation, fall back to using finalId
logger.LogWarning(
ex,
"Failed to generate fragment hash ID for item {ItemId}, using finalId as fallback",
finalId
);
hashId = "";
}
var geometry = navisworksObject.Geometry;
var mode = converterSettings.Current.User.VisualRepresentationMode;
using var defaultColor = new NAV.Color(1.0, 1.0, 1.0);
var renderColor = SelectByRepresentationMode(
var renderColor = Select(
mode,
geometry.ActiveColor,
geometry.PermanentColor,
geometry.OriginalColor,
defaultColor
);
var renderTransparency = SelectByRepresentationMode(
var renderTransparency = Select(
mode,
geometry.ActiveTransparency,
geometry.PermanentTransparency,
geometry.OriginalTransparency,
0.0
);
var renderMaterialId = SelectByRepresentationMode(
var renderMaterialId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
$"{geometry.PermanentColor.GetHashCode()}_{geometry.PermanentTransparency}".GetHashCode(),
@@ -162,8 +92,9 @@ public class NavisworksMaterialUnpacker(
);
var materialName =
$"{MaterialConstants.DEFAULT_MATERIAL_NAME_PREFIX}{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";
$"NavisworksMaterial_{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";
// Check Item category for material name
var itemCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Item");
if (itemCategory != null)
{
@@ -175,6 +106,7 @@ public class NavisworksMaterialUnpacker(
}
}
// Check Material category for material name
var materialPropertyCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Material");
if (materialPropertyCategory != null)
{
@@ -188,14 +120,19 @@ public class NavisworksMaterialUnpacker(
if (renderMaterialProxies.TryGetValue(renderMaterialId.ToString(), out RenderMaterialProxy? value))
{
value.objects.Add(!string.IsNullOrEmpty(hashId) ? hashId : finalId);
value.objects.Add(finalId);
}
else
{
renderMaterialProxies[renderMaterialId.ToString()] = new RenderMaterialProxy()
{
value = CreateRenderMaterial(materialName, renderTransparency, renderColor, renderMaterialId),
objects = [!string.IsNullOrEmpty(hashId) ? hashId : finalId]
value = ConvertRenderColorAndTransparencyToSpeckle(
materialName,
renderTransparency,
renderColor,
renderMaterialId
),
objects = [finalId]
};
}
}
@@ -208,7 +145,7 @@ public class NavisworksMaterialUnpacker(
return renderMaterialProxies.Values.ToList();
}
private static RenderMaterial CreateRenderMaterial(
private static RenderMaterial ConvertRenderColorAndTransparencyToSpeckle(
string name,
double transparency,
NAV.Color navisworksColor,
@@ -219,9 +156,7 @@ public class NavisworksMaterialUnpacker(
var speckleRenderMaterial = new RenderMaterial()
{
name = !string.IsNullOrEmpty(name)
? name
: $"{MaterialConstants.DEFAULT_MATERIAL_NAME_PREFIX}{Math.Abs(color.ToArgb())}",
name = !string.IsNullOrEmpty(name) ? name : $"NavisworksMaterial_{Math.Abs(color.ToArgb())}",
opacity = 1 - transparency,
metalness = 0,
roughness = 1,
@@ -6,7 +6,6 @@ using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Operations;
using Speckle.Converter.Navisworks.Helpers;
using Speckle.Converter.Navisworks.Services;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Objects.Data;
@@ -26,9 +25,7 @@ public class NavisworksRootObjectBuilder(
ISdkActivityFactory activityFactory,
NavisworksMaterialUnpacker materialUnpacker,
NavisworksColorUnpacker colorUnpacker,
IElementSelectionService elementSelectionService,
IUiUnitsCache uiUnitsCache,
InstanceStoreManager instanceStoreManager
IElementSelectionService elementSelectionService
) : IRootObjectBuilder<NAV.ModelItem>
{
private bool SkipNodeMerging { get; set; }
@@ -43,45 +40,32 @@ public class NavisworksRootObjectBuilder(
)
{
#if DEBUG
SkipNodeMerging = true;
// This is a temporary workaround to disable node merging for debugging purposes - false is default, true is for debugging
SkipNodeMerging = false;
#endif
using var activity = activityFactory.Start("Build");
ValidateInputs(navisworksModelItems, projectId, onOperationProgressed);
// 2. Initialize root collection
var rootCollection = InitializeRootCollection();
(Dictionary<string, Base?> convertedElements, List<SendConversionResult> conversionResults) =
await ConvertModelItemsAsync(navisworksModelItems, projectId, onOperationProgressed, cancellationToken);
// 3. Convert all model items and store results
var (convertedElements, conversionResults) = await ConvertModelItemsAsync(
navisworksModelItems,
projectId,
onOperationProgressed,
cancellationToken
);
ValidateConversionResults(conversionResults);
var groupedNodes = SkipNodeMerging ? [] : GroupSiblingGeometryNodes(navisworksModelItems);
var finalElements = BuildFinalElements(convertedElements, groupedNodes);
List<Base> geometryDefinitions = instanceStoreManager.GetGeometryDefinitions();
await AddProxiesToCollection(rootCollection, navisworksModelItems, groupedNodes);
var geometryDefinitionsCollection = new Collection
{
name = "Geometry Definitions",
["units"] = converterSettings.Current.Derived.SpeckleUnits,
elements = geometryDefinitions
};
var mainElementsCollection = new Collection
{
name = rootCollection.name,
["units"] = converterSettings.Current.Derived.SpeckleUnits,
elements = finalElements
};
rootCollection.elements = [mainElementsCollection];
if (geometryDefinitions.Count > 0)
{
rootCollection.elements.Add(geometryDefinitionsCollection);
}
rootCollection.elements = finalElements;
return new RootObjectBuilderResult(rootCollection, conversionResults);
}
@@ -153,10 +137,12 @@ public class NavisworksRootObjectBuilder(
Dictionary<string, List<NAV.ModelItem>> groupedNodes
)
{
// First build the grouped nodes as before
var finalElements = new List<Base>();
var processedPaths = new HashSet<string>();
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
// If hierarchy mode is enabled, reorganize into proper nested structure
if (converterSettings.Current.User.PreserveModelHierarchy)
{
var hierarchyBuilder = new NavisworksHierarchyBuilder(
@@ -165,9 +151,12 @@ public class NavisworksRootObjectBuilder(
elementSelectionService
);
return hierarchyBuilder.BuildHierarchy();
var hierarchy = hierarchyBuilder.BuildHierarchy();
return hierarchy;
}
// Otherwise continue with flat mode
AddRemainingElements(finalElements, convertedBases, processedPaths);
return finalElements;
}
@@ -224,17 +213,24 @@ public class NavisworksRootObjectBuilder(
}
}
private (string name, string path) GetElementNameAndPath(string applicationId)
private (string name, string path) GetContext(string applicationId)
{
var modelItem = elementSelectionService.GetModelItemFromPath(applicationId);
var context = HierarchyHelper.ExtractContext(modelItem);
return (context.Name, context.Path);
}
/// <summary>
/// Processes and adds any remaining non-grouped elements.
/// </summary>
/// <remarks>
/// Handles both Collection and Base type elements differently.
/// Only processes elements that weren't handled in grouped processing.
/// </remarks>
private NavisworksObject CreateNavisworksObject(string groupKey, List<Base> siblingBases)
{
string cleanParentPath = ElementSelectionHelper.GetCleanPath(groupKey);
(string name, string path) = GetElementNameAndPath(cleanParentPath);
(string name, string path) = GetContext(cleanParentPath);
return new NavisworksObject
{
@@ -242,11 +238,16 @@ public class NavisworksRootObjectBuilder(
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
units = converterSettings.Current.Derived.SpeckleUnits,
applicationId = groupKey,
applicationId = groupKey, // Use the full composite key as applicationId to preserve uniqueness
["path"] = path
};
}
/// <summary>
/// Creates a NavisworksObject from a single converted base.
/// </summary>
/// <param name="convertedBase">The converted Speckle Base object.</param>
/// <returns>A new NavisworksObject containing the converted data.</returns>
private NavisworksObject? CreateNavisworksObject(Base convertedBase)
{
if (convertedBase.applicationId == null)
@@ -254,16 +255,14 @@ public class NavisworksRootObjectBuilder(
return null;
}
(string name, string path) = GetElementNameAndPath(convertedBase.applicationId);
var units = uiUnitsCache.Ensure();
(string name, string path) = GetContext(convertedBase.applicationId);
return new NavisworksObject
{
name = name,
displayValue = convertedBase["displayValue"] as List<Base> ?? [],
properties = convertedBase["properties"] as Dictionary<string, object?> ?? [],
units = units.ToString(),
units = converterSettings.Current.Derived.SpeckleUnits,
applicationId = convertedBase.applicationId,
["path"] = path
};
@@ -289,16 +288,18 @@ public class NavisworksRootObjectBuilder(
rootCollection[ProxyKeys.COLOR] = colors;
}
var instanceDefinitionProxies = instanceStoreManager.GetInstanceDefinitionProxies();
if (instanceDefinitionProxies.Count > 0)
{
rootCollection[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies.ToList();
}
return Task.CompletedTask;
}
/// <summary>
/// Converts a single Navisworks item to a Speckle object.
/// </summary>
/// <remarks>
/// Attempts to retrieve from cache first.
/// Falls back to fresh conversion if not cached.
/// Logs errors but doesn't throw exceptions.
/// </remarks>
/// <returns>A SendConversionResult indicating success or failure.</returns>
private SendConversionResult ConvertNavisworksItem(
NAV.ModelItem navisworksItem,
Dictionary<string, Base?> convertedBases,
@@ -191,27 +191,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -302,8 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -326,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.revit2022": {
@@ -336,6 +316,29 @@
"Speckle.Revit.API": "[2022.0.2.1, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -369,15 +372,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"Speckle.Revit.API": {
"type": "CentralTransitive",
"requested": "[2023.0.0, )",
@@ -191,27 +191,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -302,8 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -326,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.revit2023": {
@@ -336,6 +316,29 @@
"Speckle.Revit.API": "[2023.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -369,15 +372,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"Speckle.Revit.API": {
"type": "CentralTransitive",
"requested": "[2023.0.0, )",
@@ -191,27 +191,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -302,8 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -326,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.revit2024": {
@@ -336,6 +316,29 @@
"Speckle.Revit.API": "[2024.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -369,15 +372,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"Speckle.Revit.API": {
"type": "CentralTransitive",
"requested": "[2023.0.0, )",
@@ -171,25 +171,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -245,8 +226,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -269,7 +251,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.revit2025": {
@@ -279,6 +261,27 @@
"Speckle.Revit.API": "[2025.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -312,15 +315,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"Speckle.Revit.API": {
"type": "CentralTransitive",
"requested": "[2023.0.0, )",
@@ -164,25 +164,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -238,8 +219,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -262,7 +244,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.revit2026": {
@@ -272,6 +254,27 @@
"Speckle.Revit.API": "[2026.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -296,15 +299,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"Speckle.Revit.API": {
"type": "CentralTransitive",
"requested": "[2023.0.0, )",
@@ -94,7 +94,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
public List<ISendFilter> GetSendFilters() =>
[
new RevitSelectionFilter { IsDefault = true },
new RevitSelectionFilter() { IsDefault = true },
new RevitViewsFilter(_revitContext),
new RevitCategoriesFilter(_revitContext)
];
@@ -58,7 +58,6 @@ public static class ServiceRegistration
serviceCollection.AddScoped<SendOperation<DocumentToConvert>>();
serviceCollection.AddScoped<ElementUnpacker>();
serviceCollection.AddScoped<LevelUnpacker>();
serviceCollection.AddScoped<ViewUnpacker>();
serviceCollection.AddScoped<SendCollectionManager>();
serviceCollection.AddScoped<IRootObjectBuilder<DocumentToConvert>, RevitRootObjectBuilder>();
serviceCollection.AddSingleton<ISendConversionCache, SendConversionCache>();
@@ -75,6 +74,7 @@ public static class ServiceRegistration
serviceCollection.AddSingleton<RevitUtils>();
serviceCollection.AddSingleton<IFailuresPreprocessor, HideWarningsFailuresPreprocessor>();
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());
serviceCollection.AddScoped<LocalToGlobalConverterUtils>();
// operation progress manager
@@ -1,6 +1,5 @@
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Speckle.Converters.RevitShared.Extensions;
namespace Speckle.Connectors.Revit.HostApp;
@@ -24,11 +23,11 @@ public class ElementUnpacker
// Step 1: unpack groups
var atomicObjects = UnpackElements(selectionElements, doc);
// Step 2: Deduplicate parent-child elements in selection
// Removes child elements (mullions, panels, top rails, stacked wall members) when
// their parent element is also selected, since parents include children in their conversion.
// Children are only converted independently when their parent is NOT in the selection.
return RemoveKnownChildElementsWhenParentPresent(atomicObjects, doc);
// Step 2: pack curtain wall elements, once we know the full extent of our flattened item list.
// The behaviour we're looking for:
// If parent wall is part of selection, does not select individual elements out. Otherwise, selects individual elements (Panels, Mullions) as atomic objects.
// NOTE: this also conditionally "packs" stacked wall elements if their parent is present. See detailed note inside the function.
return PackCurtainWallElementsAndStackedWalls(atomicObjects, doc);
}
/// <summary>
@@ -109,7 +108,7 @@ public class ElementUnpacker
// We use the nullable document (happiness level 5/10) for the sake of linked models - bc we use this function in 2 different places
// 1- RootObjectBuilder with linked model document - otherwise we cannot unpack elements from correct document.
// 2- Evicting the cache while introducing the settings
private List<Element> RemoveKnownChildElementsWhenParentPresent(List<Element> elements, Document doc)
private List<Element> PackCurtainWallElementsAndStackedWalls(List<Element> elements, Document doc)
{
//just used for contains so use ToHashSet
var ids = elements.Select(el => el.Id).ToHashSet();
@@ -132,37 +131,64 @@ public class ElementUnpacker
// If you wonder why revit is driving people to insanity, this is one of those moments.
// See [CNX-851: Stacked Wall Duplicate Geometry or Materials not applied](https://linear.app/speckle/issue/CNX-851/stacked-wall-duplicate-geometry-or-materials-not-applied)
|| (element is Wall { IsStackedWallMember: true } wall && ids.Contains(wall.StackedWallOwnerId))
// Railings: Remove TopRail when parent railing is selected
// Prevents duplication since railing converter includes TopRail as a child element
// TODO: Consider adding HandRail support (also inherits from ContinuousRail)
|| (
element is TopRail topRail
&& doc.GetElement(topRail.HostRailingId) is Railing railing
&& ids.Contains(railing.Id)
)
);
return elements;
}
/// <summary>
/// Returns element IDs and their known child element IDs for cache tracking.
/// Uses <see cref="ElementExtensions.GetKnownChildrenElements"/> to determine which children to include.
/// Given a set of atomic elements, it will return a list of all their ids as well as their subelements. This currently handles <b>curtain walls</b> and <b>stacked walls</b>.
/// This might not be an exhaustive list of valid objects with "subelements" in revit, and will need revisiting.
/// </summary>
/// <param name="elements">Elements to process</param>
/// <returns>Flattened list of parent and child element IDs</returns>
/// <param name="elements"></param>
/// <returns></returns>
public List<string> GetElementsAndSubelementIdsFromAtomicObjects(List<Element> elements)
{
var ids = new HashSet<string>();
foreach (var element in elements)
{
// add the element's own ID
ids.Add(element.Id.ToString());
// add all known children IDs using the extension method. trying to consolidate duplication here with converter
foreach (var childId in element.GetKnownChildrenElements())
switch (element)
{
ids.Add(childId.ToString());
case Wall wall:
if (wall.CurtainGrid is { } grid)
{
foreach (var mullionId in grid.GetMullionIds())
{
ids.Add(mullionId.ToString());
}
foreach (var panelId in grid.GetPanelIds())
{
ids.Add(panelId.ToString());
}
}
else if (wall.IsStackedWall)
{
foreach (var stackedWallId in wall.GetStackedWallMemberIds())
{
ids.Add(stackedWallId.ToString());
}
}
break;
case FootPrintRoof footPrintRoof:
if (footPrintRoof.CurtainGrids is { } gs)
{
foreach (CurtainGrid roofGrid in gs)
{
foreach (var mullionId in roofGrid.GetMullionIds())
{
ids.Add(mullionId.ToString());
}
foreach (var panelId in roofGrid.GetPanelIds())
{
ids.Add(panelId.ToString());
}
}
}
break;
default:
break;
}
ids.Add(element.Id.ToString());
}
return ids.ToList();
@@ -1,87 +0,0 @@
using Autodesk.Revit.DB;
using Microsoft.Extensions.Logging;
using Speckle.Objects.Other;
using Speckle.Sdk;
namespace Speckle.Connectors.Revit.HostApp;
/// <summary>
/// Unpacks Revit Views for sending
/// </summary>
public class ViewUnpacker
{
private readonly ILogger<ViewUnpacker> _logger;
private readonly Converters.Common.IRootToSpeckleConverter _rootToSpeckleConverter;
public ViewUnpacker(Converters.Common.IRootToSpeckleConverter rootToSpeckleConverter, ILogger<ViewUnpacker> logger)
{
_rootToSpeckleConverter = rootToSpeckleConverter;
_logger = logger;
}
private Camera? ConvertViewToCamera(View3D view)
{
try
{
var converted = (Camera)_rootToSpeckleConverter.Convert(view);
if (converted is null)
{
_logger.LogError("Failed to create a view from {view}", view.Name);
return null;
}
return converted;
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to create a view from {view}", view.Name);
return null;
}
}
/// <summary>
/// Iterates through the 3D views in the provided document to create cameras
/// </summary>
/// <param name="doc">Document to retrieve 3D views from</param>
/// <returns></returns>
public List<Camera> Unpack(Document doc)
{
List<Camera> cameras = new();
using FilteredElementCollector collector = new(doc);
List<View> views = collector
.WhereElementIsNotElementType()
.OfCategory(BuiltInCategory.OST_Views)
.Cast<View>()
.Where(x => x.ViewType == ViewType.ThreeD)
.ToList();
foreach (View view in views)
{
if (view is not View3D view3D)
{
continue;
}
// not supporting parallel project yet, since it is too complex to match in the viewer for now
try
{
if (!view3D.IsPerspective)
{
continue;
}
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
{
continue; // some threed views will throw an exception: returns true if view is not a view template
}
if (ConvertViewToCamera(view3D) is Camera camera)
{
cameras.Add(camera);
}
}
return cameras;
}
}
@@ -66,8 +66,8 @@ public sealed class RevitHostObjectBuilder(
// TODO: formalise getting transform info from rootObject. this dict access is gross.
Autodesk.Revit.DB.Transform? referencePointTransformFromRootObject = null;
if (
rootObject.DynamicPropertyKeys.Contains(RootKeys.REFERENCE_POINT_TRANSFORM)
&& rootObject[RootKeys.REFERENCE_POINT_TRANSFORM] is Dictionary<string, object> transformDict
rootObject.DynamicPropertyKeys.Contains(ReferencePointHelper.REFERENCE_POINT_TRANSFORM_KEY)
&& rootObject[ReferencePointHelper.REFERENCE_POINT_TRANSFORM_KEY] is Dictionary<string, object> transformDict
&& transformDict.TryGetValue("transform", out var transformValue)
)
{
@@ -24,7 +24,6 @@ public class RevitRootObjectBuilder(
ISendConversionCache sendConversionCache,
ElementUnpacker elementUnpacker,
LevelUnpacker levelUnpacker,
ViewUnpacker viewUnpacker,
IThreadContext threadContext,
SendCollectionManager sendCollectionManager,
ILogger<RevitRootObjectBuilder> logger,
@@ -42,11 +41,7 @@ public class RevitRootObjectBuilder(
() => Task.FromResult(BuildSync(documentElementContexts, projectId, onOperationProgressed, ct))
);
#pragma warning disable CA1506
#pragma warning disable CA1502
private RootObjectBuilderResult BuildSync(
#pragma warning restore CA1506
#pragma warning restore CA1502
IReadOnlyList<DocumentToConvert> documentElementContexts,
string projectId,
IProgress<CardProgress> onOperationProgressed,
@@ -60,9 +55,6 @@ public class RevitRootObjectBuilder(
throw new SpeckleException("Family Environment documents are not supported.");
}
// create a new send pipeline
using var sendPipeline = new Speckle.Sdk.Pipeline.Send();
// init the root
Collection rootObject =
new() { name = converterSettings.Current.Document.PathName.Split('\\').Last().Split('.').First() };
@@ -191,12 +183,10 @@ public class RevitRootObjectBuilder(
// non-transformed elements can safely rely on cache
// TODO: Potential here to transform cached objects and NOT reconvert,
// TODO: we wont do !hasTransform here, and re-set application id before this
bool wasCached = false;
if (!hasTransform && sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
{
// TODO: cahce hit
converted = value;
wasCached = true;
cacheHitCount++;
}
// not in cache means we convert
@@ -215,12 +205,6 @@ public class RevitRootObjectBuilder(
converted.applicationId = applicationId;
}
var reference = sendPipeline.Process(converted).Result; // .Wait(cancellationToken);//.ConfigureAwait(false);
if (!wasCached)
{
sendConversionCache.AppendSendResult(projectId, applicationId, reference);
}
var collection = sendCollectionManager.GetAndCreateObjectHostCollection(
revitElement,
rootObject,
@@ -228,7 +212,7 @@ public class RevitRootObjectBuilder(
modelDisplayName
);
collection.elements.Add(reference);
collection.elements.Add(converted);
results.Add(new(Status.SUCCESS, applicationId, sourceType, converted));
}
catch (Exception ex) when (!ex.IsFatal())
@@ -256,7 +240,6 @@ public class RevitRootObjectBuilder(
throw new SpeckleException("Failed to convert all objects.");
}
// STEP 5: Unpack proxies to attach to root collection
var flatElements = atomicObjectsByDocumentAndTransform.SelectMany(t => t.Elements).ToList();
var idsAndSubElementIds = elementUnpacker.GetElementsAndSubelementIdsFromAtomicObjects(flatElements);
@@ -269,27 +252,13 @@ public class RevitRootObjectBuilder(
rootObject[ProxyKeys.INSTANCE_DEFINITION] = revitToSpeckleCacheSingleton.GetInstanceDefinitionProxiesForObjects(
idsAndSubElementIds
);
// NOTE: i might be overdoing things in here, but tldr:
// - all instance objects (meshes) are processed individually
// - process their collection individually, and then attach it to the root collection
// we could, theoretically, just process the collection as a whole (but it can be big?)
// note/ask: do these need to go in the conversion cache? or not?
var instanceObjects = revitToSpeckleCacheSingleton.GetBaseObjectsForObjects(idsAndSubElementIds);
var instanceReferences = new Collection("revitInstancedObjects");
foreach (var instanceObject in instanceObjects)
{
var referenceInstanceObject = sendPipeline.Process(instanceObject).Result;
instanceReferences.elements.Add(referenceInstanceObject);
}
var instanceReferenceCollection = sendPipeline.Process(instanceReferences).Result;
rootObject.elements.Add(instanceReferenceCollection);
// STEP 6: Unpack all other objects to attach to root collection
List<Objects.Other.Camera> views = viewUnpacker.Unpack(converterSettings.Current.Document);
if (views.Count > 0)
{
rootObject[RootKeys.VIEW] = views;
}
rootObject.elements.Add(
new Collection()
{
elements = revitToSpeckleCacheSingleton.GetBaseObjectsForObjects(idsAndSubElementIds),
name = "revitInstancedObjects"
}
);
// NOTE: these are currently not used anywhere, we'll skip them until someone calls for it back
// rootObject[ProxyKeys.PARAMETER_DEFINITIONS] = _parameterDefinitionHandler.Definitions;
@@ -298,13 +267,9 @@ public class RevitRootObjectBuilder(
if (converterSettings.Current.ReferencePointTransform is Transform transform)
{
var transformMatrix = ReferencePointHelper.CreateTransformDataForRootObject(transform);
rootObject[RootKeys.REFERENCE_POINT_TRANSFORM] = transformMatrix;
rootObject[ReferencePointHelper.REFERENCE_POINT_TRANSFORM_KEY] = transformMatrix;
}
// NOTE: could be
sendPipeline.Process(rootObject).Wait(cancellationToken);
sendPipeline.WaitForUpload().Wait(cancellationToken);
return new RootObjectBuilderResult(new Collection() { name = "ignore" }, results);
return new RootObjectBuilderResult(rootObject, results);
}
}
@@ -24,7 +24,6 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\LevelUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\LinkedModelHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RevitMaterialBaker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\ViewUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SupportedCategoriesUtils.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RevitViewManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\HideWarningsFailuresPreprocessor.cs" />
@@ -61,4 +60,4 @@
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCefPlugin.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleRevitTaskException.cs" />
</ItemGroup>
</Project>
</Project>
@@ -202,27 +202,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -346,8 +325,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
@@ -357,7 +337,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.rhino7": {
@@ -367,6 +347,29 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -399,15 +402,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -29,8 +29,8 @@
<ItemGroup>
<PackageReference Include="GrasshopperAsyncComponent" />
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.9.24194.18121"/>
<PackageReference Include="Grasshopper" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.9.24194.18121"/>
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" />
<PackageReference Include="Grasshopper" IncludeAssets="compile; build" PrivateAssets="all" />
<PackageReference Include="System.Resources.Extensions" />
</ItemGroup>
@@ -202,27 +202,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -346,8 +325,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
@@ -357,7 +337,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.rhino8": {
@@ -366,6 +346,29 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -398,15 +401,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -47,11 +47,6 @@ public class CollectionPathsSelector : ValueSet<IGH_Goo>
// note: we are skipping the input collection, to make the output paths more intuitive
foreach (var element in wrapper.Elements)
{
if (element is null)
{
continue; // skip nulls (CNX-2855)
}
if (element is SpeckleCollectionWrapper childCollectionWrapper)
{
paths.AddRange(GetPaths(childCollectionWrapper));
@@ -75,15 +70,11 @@ public class CollectionPathsSelector : ValueSet<IGH_Goo>
void GetPathsInternal(SpeckleCollectionWrapper w)
{
currentPath.Add(w.Name);
var subCols = w
.Elements.Where(e => e != null) // skip nulls (CNX-2855)
.OfType<SpeckleCollectionWrapper>()
.ToList();
var subCols = w.Elements.OfType<SpeckleCollectionWrapper>().ToList();
// NOTE: here we're basically outputting only paths that correspond to a collection
// that has values inside of it.
var nonNullElementCount = w.Elements.Count(e => e != null);
if (subCols.Count != nonNullElementCount)
if (subCols.Count != w.Elements.Count)
{
allPaths.Add(string.Join(Constants.LAYER_PATH_DELIMITER, currentPath));
}
@@ -48,7 +48,6 @@ public class CreateCollection : VariableParameterComponentBase
protected override void SolveInstance(IGH_DataAccess dataAccess)
{
var rootCollection = CreateRootCollection();
bool hasAnyInput = false;
foreach (var inputParam in Params.Input)
{
@@ -58,7 +57,6 @@ public class CreateCollection : VariableParameterComponentBase
continue;
}
hasAnyInput = true;
var childCollection = ProcessInputParameter(inputParam, data, rootCollection.Name);
if (childCollection != null)
{
@@ -66,46 +64,19 @@ public class CreateCollection : VariableParameterComponentBase
}
}
// Skip validation if no input provided
if (!hasAnyInput)
{
return;
}
// validate for duplicate application IDs across the entire collection hierarchy
if (HasDuplicateApplicationIds(rootCollection))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The same object(s) cannot appear in multiple collections");
return;
}
// validate collection isn't empty (CNX-2855)
if (rootCollection.Elements.Count == 0 || !rootCollection.Elements.Any(HasAnyValidContent))
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Error,
"Collection contains no valid geometry. All input objects are unsupported types."
);
return;
return; // error already added in validation method
}
dataAccess.SetData(0, new SpeckleCollectionWrapperGoo(rootCollection));
}
/// <summary>
/// Recursively checks if collection or any descendants contain valid geometry/data objects
/// </summary>
private bool HasAnyValidContent(ISpeckleCollectionObject? element) =>
element switch
{
SpeckleGeometryWrapper => true,
SpeckleDataObjectWrapper => true,
SpeckleCollectionWrapper collection => collection.Elements.Any(HasAnyValidContent),
_ => false
};
private SpeckleCollectionWrapper CreateRootCollection() =>
new()
private SpeckleCollectionWrapper CreateRootCollection()
{
return new SpeckleCollectionWrapper
{
Base = new Collection(),
Name = "Unnamed",
@@ -114,6 +85,7 @@ public class CreateCollection : VariableParameterComponentBase
Material = null,
ApplicationId = InstanceGuid.ToString()
};
}
private SpeckleCollectionWrapper? ProcessInputParameter(IGH_Param inputParam, List<IGH_Goo> data, string rootName)
{
@@ -168,10 +140,7 @@ public class CreateCollection : VariableParameterComponentBase
// Check for duplicate names within this collection
foreach (
var subCollectionName in collectionGoo
.Value.Elements.Where(e => e != null) // skip nulls (CNX-2855)
.OfType<SpeckleCollectionWrapper>()
.Select(c => c.Name)
var subCollectionName in collectionGoo.Value.Elements.OfType<SpeckleCollectionWrapper>().Select(c => c.Name)
)
{
if (!duplicateNames.Add(subCollectionName))
@@ -194,8 +163,6 @@ public class CreateCollection : VariableParameterComponentBase
List<string> childPath
)
{
int skippedCount = 0;
foreach (var obj in objects)
{
// handle data objects directly (deep copy to avoid mutations)
@@ -217,20 +184,9 @@ public class CreateCollection : VariableParameterComponentBase
}
else
{
// add null placeholder to preserve topology (CNX-2855)
parentCollection.Elements.Add(null);
skippedCount++;
AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"{obj?.GetType().Name} type cannot be added to collections.");
}
}
// add warning if objects were skipped (CNX-2855)
if (skippedCount > 0)
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
$"Skipped {skippedCount} unsupported object(s) (Leaders, TextDots, Dimensions, etc.)"
);
}
}
/// <summary>
@@ -266,8 +222,6 @@ public class CreateCollection : VariableParameterComponentBase
{
switch (element)
{
case null:
break; // skip nulls (CNX-2855)
case SpeckleCollectionWrapper childCollection:
// recurse into child collections
ProcessAndCheckForDuplicateApplicationIds(childCollection, seenIds, duplicateIds);
@@ -51,14 +51,11 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
Name = wrapper.Name;
NickName = wrapper.Name;
// Separate objects and collections (skip nulls for non-topology outputs)
// Separate objects and collections
// Note: SpeckleBlockInstanceWrapper inherits from SpeckleObjectWrapper,
// so it will be included in objects
List<SpeckleWrapper> objects = wrapper.GetAtomicObjects().ToList();
List<SpeckleCollectionWrapper> collections = wrapper
.Elements.Where(e => e != null)
.OfType<SpeckleCollectionWrapper>()
.ToList();
List<SpeckleCollectionWrapper> collections = wrapper.Elements.OfType<SpeckleCollectionWrapper>().ToList();
var outputParams = new List<OutputParamWrapper>();
if (objects.Count != 0)
@@ -72,14 +69,22 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
Access = GH_ParamAccess.list
};
// Don't use topology for _objects output (always list)
// Create appropriate Goo types for each object (downside of the inheritance refactor)
List<IGH_Goo> atomicObjectGoos = objects.Select(obj => obj.CreateGoo()).ToList();
outputParams.Add(new OutputParamWrapper(param, atomicObjectGoos, null));
}
foreach (SpeckleCollectionWrapper childWrapper in collections)
{
var hasInnerCollections = childWrapper.Elements.Where(e => e != null).Any(el => el is SpeckleCollectionWrapper);
/* POC: we shouldn't skip empty, people would probably expect to see what they see in browser.
if (childWrapper.Elements.Count == 0)
{
continue;
}
*/
var hasInnerCollections = childWrapper.Elements.Any(el => el is SpeckleCollectionWrapper);
var topology = childWrapper.Topology;
var nickName = childWrapper.Name;
if (nickName.Length > 16)
@@ -106,11 +111,8 @@ public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
}
else
{
// If topology exists, include nulls to match topology count (CNX-2855)
List<IGH_Goo> childObjectGoos =
topology != null
? childWrapper.ToGooListWithNulls()
: childWrapper.GetAtomicObjects().Select(obj => obj.CreateGoo()).ToList();
// Create appropriate Goo types for child objects
List<IGH_Goo> childObjectGoos = childWrapper.GetAtomicObjects().Select(obj => obj.CreateGoo()).ToList();
outputValue = childObjectGoos;
}
@@ -115,7 +115,7 @@ public class DeconstructSpeckleParam : GH_Component, IGH_VariableParameterCompon
SpeckleCollectionWrapperGoo collectionGoo when collectionGoo.Value != null
=> ParseSpeckleWrapper(
collectionGoo.Value,
collectionGoo.Value.Elements.Select(o => ((SpeckleWrapper)o!).CreateGoo()).ToList()
collectionGoo.Value.Elements.Select(o => ((SpeckleWrapper)o).CreateGoo()).ToList()
),
// get geometries from wrapper to override displayValue prop while parsing
@@ -15,7 +15,7 @@ public class TokenUrlComponent : GH_Component
{
public TokenUrlComponent()
: base(
"Speckle Model URL with Token",
"Speckle Model URL",
"URL",
"Create a Speckle model link using URL and developer token",
ComponentCategories.PRIMARY_RIBBON,
@@ -27,7 +27,8 @@ public class ExpandSpeckleProperties : GH_Component, IGH_VariableParameterCompon
protected override Bitmap Icon => Resources.speckle_properties_expand;
public override GH_Exposure Exposure => GH_Exposure.secondary;
protected override void RegisterInputParams(GH_InputParamManager pManager) =>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(
new SpecklePropertyGroupParam(),
"Properties",
@@ -35,6 +36,7 @@ public class ExpandSpeckleProperties : GH_Component, IGH_VariableParameterCompon
"Speckle Properties to expand",
GH_ParamAccess.item
);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
@@ -155,11 +155,10 @@ public class QuerySpeckleObjects : GH_Component, IGH_VariableParameterComponent
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))
{
// include nulls to match topology count (CNX-2855)
var outputGoosWithNulls = targetCollectionWrapper.ToGooListWithNulls();
var tree = GrasshopperHelpers.CreateDataTreeFromTopologyAndItems(topology, outputGoosWithNulls);
var tree = GrasshopperHelpers.CreateDataTreeFromTopologyAndItems(topology, outputGoos);
dataAccess.SetDataTree(i, tree);
}
else
@@ -47,13 +47,15 @@ public class ReceiveAsyncComponent : GH_AsyncComponent<ReceiveAsyncComponent>
public bool JustPastedIn { get; set; }
public string LastVersionDate { get; set; }
public string LastInfoMessage { get; set; }
public SpeckleUrlModelResource? UrlModelResource { get; set; }
public HostApp.SpeckleUrlModelResource? UrlModelResource { get; set; }
// DI props
public IClient ApiClient { get; private set; }
protected override void RegisterInputParams(GH_InputParamManager pManager) =>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam(GH_ParamAccess.item));
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
@@ -64,14 +66,6 @@ public class ReceiveAsyncComponent : GH_AsyncComponent<ReceiveAsyncComponent>
"The model collection of the loaded version",
GH_ParamAccess.item
);
pManager.AddParameter(
new SpecklePropertyGroupParam(),
"Properties",
"properties",
"Model-wide properties from the root collection",
GH_ParamAccess.item
);
}
protected override void SolveInstance(IGH_DataAccess da)
@@ -130,7 +124,7 @@ public class ReceiveAsyncComponent : GH_AsyncComponent<ReceiveAsyncComponent>
{
var autoReceiveMi = Menu_AppendItem(
menu,
"Load new versions automatically",
"Load automatically",
(s, e) =>
{
AutoReceive = !AutoReceive;
@@ -291,7 +285,7 @@ public class ReceiveAsyncComponent : GH_AsyncComponent<ReceiveAsyncComponent>
Account? account = urlResource.Account.GetAccount(scope);
if (account is null)
{
throw new SpeckleAccountManagerException("No default account was found");
throw new SpeckleAccountManagerException($"No default account was found");
}
ApiClient?.Dispose();
@@ -344,7 +338,6 @@ public sealed class ReceiveComponentWorker : WorkerInstance<ReceiveAsyncComponen
public Base Root { get; set; }
public SpeckleUrlModelResource? UrlModelResource { get; set; }
public SpeckleCollectionWrapperGoo Result { get; set; }
public SpecklePropertyGroupGoo? RootProperties { get; private set; }
private List<(GH_RuntimeMessageLevel, string)> RuntimeMessages { get; } = new();
public override WorkerInstance<ReceiveAsyncComponent> Duplicate(string id, CancellationToken cancellationToken)
@@ -381,7 +374,6 @@ public sealed class ReceiveComponentWorker : WorkerInstance<ReceiveAsyncComponen
}
da.SetData(0, Result);
da.SetData(1, RootProperties);
}
public override async Task DoWork(Action<string, double> reportProgress, Action done)
@@ -447,89 +439,66 @@ public sealed class ReceiveComponentWorker : WorkerInstance<ReceiveAsyncComponen
}
using var scope = PriorityLoader.CreateScopeForActiveDocument();
try
Root = await scope
.Get<GrasshopperReceiveOperation>()
.ReceiveCommitObject(receiveInfo, progress, CancellationToken)
.ConfigureAwait(false);
CancellationToken.ThrowIfCancellationRequested();
// Step 2 - CONVERT
//receiveComponent.Message = $"Unpacking...";
TraversalContextUnpacker traversalContextUnpacker = new();
var unpackedRoot = scope.Get<RootObjectUnpacker>().Unpack(Root);
// separate atomic objects from block instances
var (atomicObjects, blockInstances) = scope
.Get<RootObjectUnpacker>()
.SplitAtomicObjectsAndInstances(unpackedRoot.ObjectsToConvert);
// initialize unpackers and collection builder
var colorUnpacker = new GrasshopperColorUnpacker(unpackedRoot);
var materialUnpacker = new GrasshopperMaterialUnpacker(unpackedRoot);
var collectionRebuilder = new GrasshopperCollectionRebuilder(
(Root as Collection) ?? new Collection { name = "unnamed" }
);
// convert atomic objects directly
var mapHandler = new LocalToGlobalMapHandler(
traversalContextUnpacker,
collectionRebuilder,
colorUnpacker,
materialUnpacker
);
foreach (var atomicContext in atomicObjects)
{
Root = await scope
.Get<GrasshopperReceiveOperation>()
.ReceiveCommitObject(receiveInfo, progress, CancellationToken)
.ConfigureAwait(false);
CancellationToken.ThrowIfCancellationRequested();
SpecklePropertyGroupGoo? rootPropertiesGoo = null;
if (Root is RootCollection rootCollection && rootCollection.properties.Count > 0)
{
rootPropertiesGoo = new SpecklePropertyGroupGoo(rootCollection.properties);
}
// Step 2 - CONVERT
//receiveComponent.Message = $"Unpacking...";
SpeckleConversionContext.SetupCurrent(scope);
var unpackedRoot = scope.Get<RootObjectUnpacker>().Unpack(Root);
// separate atomic objects from block instances
var (atomicObjects, blockInstances) = scope
.Get<RootObjectUnpacker>()
.SplitAtomicObjectsAndInstances(unpackedRoot.ObjectsToConvert);
// initialize unpackers and collection builder (data holders - created with new)
var colorUnpacker = new GrasshopperColorUnpacker(unpackedRoot);
var materialUnpacker = new GrasshopperMaterialUnpacker(unpackedRoot);
var collectionRebuilder = new GrasshopperCollectionRebuilder(
(Root as Collection) ?? new Collection { name = "unnamed" }
);
// get handler from DI and initialize with per-operation data
var mapHandler = scope
.Get<LocalToGlobalMapHandler>()
.Initialize(
scope.Get<TraversalContextUnpacker>(),
colorUnpacker,
materialUnpacker,
collectionRebuilder,
unpackedRoot.DefinitionProxies
);
// handler deals with two-pass conversion: normal objects first, then DataObjects with InstanceProxies
mapHandler.ConvertAtomicObjects(atomicObjects);
// process block instances using converted atomic objects
// internally filters out InstanceProxies that belong to registered DataObjects
// block processing needs converted objects, but object filtering needs block definitions.
mapHandler.ConvertBlockInstances(blockInstances);
Result = new SpeckleCollectionWrapperGoo(collectionRebuilder.RootCollectionWrapper);
RootProperties = rootPropertiesGoo;
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
var customProperties = new Dictionary<string, object>()
{
{ "isAsync", true },
{ "sourceHostApp", HostApplications.GetSlugFromHostAppNameAndVersion(receiveInfo.SourceApplication) },
{ "auto", Parent.AutoReceive }
};
if (receiveInfo.WorkspaceId != null)
{
customProperties.Add("workspace_id", receiveInfo.WorkspaceId);
}
if (receiveInfo.SelectedVersionUserId != null)
{
customProperties.Add(
"isMultiplayer",
receiveInfo.SelectedVersionUserId != Parent.ApiClient.Account.userInfo.id
);
}
await scope
.Get<IMixPanelManager>()
.TrackEvent(MixPanelEvents.Receive, Parent.ApiClient.Account, customProperties);
mapHandler.ConvertAtomicObject(atomicContext);
}
finally
// process block instances using converted atomic objects
// block processing needs converted objects, but object filtering needs block definitions.
mapHandler.ConvertBlockInstances(blockInstances, unpackedRoot.DefinitionProxies);
Result = new SpeckleCollectionWrapperGoo(collectionRebuilder.RootCollectionWrapper);
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
var customProperties = new Dictionary<string, object>()
{
SpeckleConversionContext.EndCurrent();
{ "isAsync", true },
{ "sourceHostApp", HostApplications.GetSlugFromHostAppNameAndVersion(receiveInfo.SourceApplication) },
{ "auto", Parent.AutoReceive }
};
if (receiveInfo.WorkspaceId != null)
{
customProperties.Add("workspace_id", receiveInfo.WorkspaceId);
}
if (receiveInfo.SelectedVersionUserId != null)
{
customProperties.Add("isMultiplayer", receiveInfo.SelectedVersionUserId != Parent.ApiClient.Account.userInfo.id);
}
await scope.Get<IMixPanelManager>().TrackEvent(MixPanelEvents.Receive, Parent.ApiClient.Account, customProperties);
}
}
@@ -37,7 +37,6 @@ public class ReceiveComponentOutput
/// Made nullable as output can be null when Run = false or on error
/// </remarks>
public SpeckleCollectionWrapperGoo? RootObject { get; set; }
public SpecklePropertyGroupGoo? RootProperties { get; set; }
}
public class ReceiveComponent : SpeckleTaskCapableComponent<ReceiveComponentInput, ReceiveComponentOutput>
@@ -72,14 +71,6 @@ public class ReceiveComponent : SpeckleTaskCapableComponent<ReceiveComponentInpu
"The model collection of the loaded version",
GH_ParamAccess.item
);
pManager.AddParameter(
new SpecklePropertyGroupParam(),
"Properties",
"properties",
"Model-wide properties from the root collection",
GH_ParamAccess.item
);
}
protected override ReceiveComponentInput GetInput(IGH_DataAccess da)
@@ -115,8 +106,6 @@ public class ReceiveComponent : SpeckleTaskCapableComponent<ReceiveComponentInpu
else
{
da.SetData(0, result.RootObject);
da.SetData(1, result.RootProperties);
Message = _apiClient != null ? "Loaded" : "Done";
}
}
@@ -143,102 +132,88 @@ public class ReceiveComponent : SpeckleTaskCapableComponent<ReceiveComponentInpu
}
using var scope = PriorityLoader.CreateScopeForActiveDocument();
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
var receiveOperation = scope.ServiceProvider.GetRequiredService<GrasshopperReceiveOperation>();
try
// Do the thing 👇🏼
Account? account = input.Resource.Account.GetAccount(scope);
if (account is null)
{
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
var receiveOperation = scope.ServiceProvider.GetRequiredService<GrasshopperReceiveOperation>();
// Do the thing 👇🏼
Account? account = input.Resource.Account.GetAccount(scope);
if (account is null)
{
throw new SpeckleAccountManagerException("No default account was found");
}
using var client = clientFactory.Create(account);
var receiveInfo = await input.Resource.GetReceiveInfo(client, cancellationToken).ConfigureAwait(false);
// store version id for tracking
_lastVersionId = receiveInfo.SelectedVersionId;
var progress = new Progress<CardProgress>(_ =>
{
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
// Message = $"{progress.Status}: {progress.Progress}";
});
var root = await receiveOperation
.ReceiveCommitObject(receiveInfo, progress, cancellationToken)
.ConfigureAwait(false);
// extract model-wide root properties (see cnx-2722)
SpecklePropertyGroupGoo? rootPropertiesGoo = null;
if (root is RootCollection rootCollection && rootCollection.properties.Count > 0)
{
rootPropertiesGoo = new SpecklePropertyGroupGoo(rootCollection.properties);
}
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
var customProperties = new Dictionary<string, object>
{
{ "isAsync", false },
{ "sourceHostApp", HostApplications.GetSlugFromHostAppNameAndVersion(receiveInfo.SourceApplication) }
};
if (receiveInfo.WorkspaceId != null)
{
customProperties.Add("workspace_id", receiveInfo.WorkspaceId);
}
if (receiveInfo.SelectedVersionUserId != null)
{
customProperties.Add("isMultiplayer", receiveInfo.SelectedVersionUserId != client.Account.userInfo.id);
}
var mixpanel = PriorityLoader.Container.GetRequiredService<IMixPanelManager>();
await mixpanel.TrackEvent(MixPanelEvents.Receive, account, customProperties);
// Setup conversion context BEFORE unpacking (which triggers DataObjectConverter)
SpeckleConversionContext.SetupCurrent(scope);
var rootObjectUnpacker = scope.ServiceProvider.GetService<RootObjectUnpacker>();
var unpackedRoot = rootObjectUnpacker.Unpack(root);
// split atomic objects from block components before conversion
var (atomicObjects, blockInstances) = rootObjectUnpacker.SplitAtomicObjectsAndInstances(
unpackedRoot.ObjectsToConvert
);
// Initialize unpackers and collection builder (data holders - created with new)
var colorUnpacker = new GrasshopperColorUnpacker(unpackedRoot);
var materialUnpacker = new GrasshopperMaterialUnpacker(unpackedRoot);
var collectionRebuilder = new GrasshopperCollectionRebuilder(
(root as Collection) ?? new Collection { name = "unnamed" }
);
// get handler from DI and initialize with per-operation data
var mapHandler = scope
.ServiceProvider.GetRequiredService<LocalToGlobalMapHandler>()
.Initialize(
scope.ServiceProvider.GetRequiredService<TraversalContextUnpacker>(),
colorUnpacker,
materialUnpacker,
collectionRebuilder,
unpackedRoot.DefinitionProxies
);
// two-pass conversion: normal objects first, then DataObjects with InstanceProxies
mapHandler.ConvertAtomicObjects(atomicObjects);
// process block instances (internally filters InstanceProxies belonging to registered DataObjects)
mapHandler.ConvertBlockInstances(blockInstances);
var goo = new SpeckleCollectionWrapperGoo(collectionRebuilder.RootCollectionWrapper);
return new ReceiveComponentOutput { RootObject = goo, RootProperties = rootPropertiesGoo };
throw new SpeckleAccountManagerException($"No default account was found");
}
finally
using var client = clientFactory.Create(account);
var receiveInfo = await input.Resource.GetReceiveInfo(client, cancellationToken).ConfigureAwait(false);
// store version id for tracking
_lastVersionId = receiveInfo.SelectedVersionId;
var progress = new Progress<CardProgress>(_ =>
{
SpeckleConversionContext.EndCurrent();
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
// Message = $"{progress.Status}: {progress.Progress}";
});
var root = await receiveOperation
.ReceiveCommitObject(receiveInfo, progress, cancellationToken)
.ConfigureAwait(false);
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
var customProperties = new Dictionary<string, object>()
{
{ "isAsync", false },
{ "sourceHostApp", HostApplications.GetSlugFromHostAppNameAndVersion(receiveInfo.SourceApplication) }
};
if (receiveInfo.WorkspaceId != null)
{
customProperties.Add("workspace_id", receiveInfo.WorkspaceId);
}
if (receiveInfo.SelectedVersionUserId != null)
{
customProperties.Add("isMultiplayer", receiveInfo.SelectedVersionUserId != client.Account.userInfo.id);
}
var mixpanel = PriorityLoader.Container.GetRequiredService<IMixPanelManager>();
await mixpanel.TrackEvent(MixPanelEvents.Receive, account, customProperties);
// We need to rethink these lovely unpackers, there's a bit too many of 'em
var rootObjectUnpacker = scope.ServiceProvider.GetService<RootObjectUnpacker>();
var traversalContextUnpacker = new TraversalContextUnpacker();
var unpackedRoot = rootObjectUnpacker.Unpack(root);
// split atomic objects from block components before conversion
var (atomicObjects, blockInstances) = rootObjectUnpacker.SplitAtomicObjectsAndInstances(
unpackedRoot.ObjectsToConvert
);
// Initialize unpackers and collection builder
var colorUnpacker = new GrasshopperColorUnpacker(unpackedRoot);
var materialUnpacker = new GrasshopperMaterialUnpacker(unpackedRoot);
var collectionRebuilder = new GrasshopperCollectionRebuilder(
(root as Collection) ?? new Collection { name = "unnamed" }
);
// convert atomic objects directly
var mapHandler = new LocalToGlobalMapHandler(
traversalContextUnpacker,
collectionRebuilder,
colorUnpacker,
materialUnpacker
);
foreach (var atomicContext in atomicObjects)
{
mapHandler.ConvertAtomicObject(atomicContext);
}
// process block instances using converted atomic objects
// block processing needs converted objects, but object filtering needs block definitions.
mapHandler.ConvertBlockInstances(blockInstances, unpackedRoot.DefinitionProxies);
// var x = new SpeckleCollectionGoo { Value = collGen.RootCollection };
var goo = new SpeckleCollectionWrapperGoo(collectionRebuilder.RootCollectionWrapper);
return new ReceiveComponentOutput { RootObject = goo };
}
private void SetupSubscription(SpeckleUrlModelResource resource)
@@ -51,7 +51,6 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
public IClient ApiClient { get; set; }
public HostApp.SpeckleUrlModelResource? UrlModelResource { get; set; }
public SpeckleCollectionWrapperGoo? RootCollectionWrapper { get; set; }
public SpecklePropertyGroupGoo? RootProperties { get; private set; }
public SpeckleUrlModelResource? OutputParam { get; set; }
public bool HasMultipleInputs { get; set; }
@@ -59,10 +58,7 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
// speckle model
pManager.AddParameter(new SpeckleUrlModelResourceParam());
// collection
pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.item),
"Collection",
@@ -72,16 +68,6 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
);
pManager.AddTextParameter("Version Message", "versionMessage", "The version message", GH_ParamAccess.item);
pManager[2].Optional = true;
// model-wide props (see cnx-2722)
pManager.AddParameter(
new SpecklePropertyGroupParam(),
"Properties",
"properties",
"Optional model-wide properties to attach to the root collection",
GH_ParamAccess.item
);
pManager[3].Optional = true;
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
@@ -294,19 +280,6 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
string? versionMessage = null;
da.GetData(2, ref versionMessage);
VersionMessage = versionMessage;
SpecklePropertyGroupGoo? rootPropsGoo = null;
da.GetData(3, ref rootPropsGoo);
// validate single properties group
// we can't support a list input here, what does that even mean? grafting the collection to each props entry?? scary.
if (Params.Input[3].VolatileData.DataCount > 1)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Only one Model Properties group is allowed");
return;
}
RootProperties = rootPropsGoo;
}
}
@@ -422,13 +395,6 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
throw new InvalidOperationException("Root Collection was null");
}
// safe to always create new wrapper since users cannot create SpeckleRootCollectionWrapper directly - it's only
// constructed here from the Collection + Model Properties inputs.
// if this changes, then we need to update below!
var rootWrapper = new SpeckleRootCollectionWrapper(rootCollectionWrapper.Value, Parent.RootProperties?.Unwrap());
rootCollectionWrapper = new SpeckleRootCollectionWrapperGoo(rootWrapper);
// Step 1 - SEND TO SERVER
var sendInfo = await urlModelResource.GetSendInfo(Parent.ApiClient, CancellationToken).ConfigureAwait(false);
@@ -442,7 +408,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
var sendOperation = scope.ServiceProvider.GetRequiredService<SendOperation<SpeckleCollectionWrapperGoo>>();
SendOperationResult? result = await sendOperation
.Execute(
new List<SpeckleCollectionWrapperGoo> { rootCollectionWrapper },
new List<SpeckleCollectionWrapperGoo>() { rootCollectionWrapper },
sendInfo,
Parent.VersionMessage,
progress,
@@ -20,19 +20,12 @@ public class SendComponentInput
public SpeckleUrlModelResource Resource { get; }
public SpeckleCollectionWrapperGoo Input { get; }
public bool Run { get; }
public SpecklePropertyGroupGoo? RootProperties { get; }
public SendComponentInput(
SpeckleUrlModelResource resource,
SpeckleCollectionWrapperGoo input,
bool run,
SpecklePropertyGroupGoo? rootProperties
)
public SendComponentInput(SpeckleUrlModelResource resource, SpeckleCollectionWrapperGoo input, bool run)
{
Resource = resource;
Input = input;
Run = run;
RootProperties = rootProperties;
}
}
@@ -43,11 +36,6 @@ public class SendComponentOutput(SpeckleUrlModelResource? resource)
public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, SendComponentOutput>
{
public override Guid ComponentGuid => new("0CF0D173-BDF0-4AC2-9157-02822B90E9FB");
public string? Url { get; private set; }
public string? VersionMessage { get; private set; }
protected override Bitmap Icon => Resources.speckle_operations_syncpublish;
public SendComponent()
: base(
"(Sync) Publish",
@@ -57,12 +45,17 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
ComponentCategories.DEVELOPER
) { }
public override Guid ComponentGuid => new("0CF0D173-BDF0-4AC2-9157-02822B90E9FB");
public string? Url { get; private set; }
public string? VersionMessage { get; private set; }
protected override Bitmap Icon => Resources.speckle_operations_syncpublish;
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
// speckle model
pManager.AddParameter(new SpeckleUrlModelResourceParam());
// collection
pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.item),
"Collection",
@@ -72,22 +65,13 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
);
pManager.AddTextParameter("Version Message", "versionMessage", "The version message", GH_ParamAccess.item);
pManager[2].Optional = true;
// model-wide props (see cnx-2722)
pManager.AddParameter(
new SpecklePropertyGroupParam(),
"Properties",
"properties",
"Optional model-wide properties to attach to the root collection",
GH_ParamAccess.item
);
pManager[3].Optional = true;
pManager.AddBooleanParameter("Run", "r", "Run the publish operation", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager) =>
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam());
}
protected override SendComponentInput GetInput(IGH_DataAccess da)
{
@@ -109,20 +93,10 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
da.GetData(2, ref versionMessage);
VersionMessage = versionMessage;
SpecklePropertyGroupGoo? rootPropsGoo = null;
da.GetData(3, ref rootPropsGoo);
// validate single properties group
// we can't support a list input here, what does that even mean? grafting the collection to each props entry?? scary.
if (Params.Input[3].VolatileData.DataCount > 1)
{
throw new SpeckleException("Only one Model Properties group is allowed");
}
bool run = false;
da.GetData(4, ref run);
da.GetData(3, ref run);
return new SendComponentInput(resource.NotNull(), rootCollectionWrapper, run, rootPropsGoo);
return new SendComponentInput(resource.NotNull(), rootCollectionWrapper, run);
}
protected override void SetOutput(IGH_DataAccess da, SendComponentOutput result)
@@ -147,7 +121,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
{
Menu_AppendSeparator(menu);
Menu_AppendItem(menu, "View created model online ↗", (s, e) => Open(Url));
Menu_AppendItem(menu, $"View created model online ↗", (s, e) => Open(Url));
}
static void Open(string url)
@@ -192,12 +166,6 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
return new(null);
}
// safe to always create new wrapper since users cannot create SpeckleRootCollectionWrapper directly - it's only
// constructed here from the Collection + Model Properties inputs.
// if this changes, then we need to update below!
var rootWrapper = new SpeckleRootCollectionWrapper(input.Input.Value, input.RootProperties?.Unwrap());
var collectionToSend = new SpeckleRootCollectionWrapperGoo(rootWrapper);
using var scope = PriorityLoader.CreateScopeForActiveDocument();
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
var sendOperation = scope.ServiceProvider.GetRequiredService<SendOperation<SpeckleCollectionWrapperGoo>>();
@@ -205,7 +173,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
Account? account = input.Resource.Account.GetAccount(scope);
if (account is null)
{
throw new SpeckleAccountManagerException("No default account was found");
throw new SpeckleAccountManagerException($"No default account was found");
}
var progress = new Progress<CardProgress>(_ =>
@@ -218,7 +186,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
var sendInfo = await input.Resource.GetSendInfo(client, cancellationToken).ConfigureAwait(false);
await sendOperation
.Execute(
new List<SpeckleCollectionWrapperGoo> { collectionToSend },
new List<SpeckleCollectionWrapperGoo>() { input.Input },
sendInfo,
VersionMessage,
progress,
@@ -227,7 +195,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
.ConfigureAwait(false);
// TODO: If we have NodeRun events later, better to have `ComponentTracker` to use across components
var customProperties = new Dictionary<string, object> { { "isAsync", false } };
var customProperties = new Dictionary<string, object>() { { "isAsync", false } };
if (sendInfo.WorkspaceId != null)
{
customProperties.Add("workspace_id", sendInfo.WorkspaceId);
@@ -107,14 +107,17 @@ public static class GrasshopperHelpers
M12 = rhinoTransform.M01,
M13 = rhinoTransform.M02,
M14 = rhinoTransform.M03 * conversionFactor,
M21 = rhinoTransform.M10,
M22 = rhinoTransform.M11,
M23 = rhinoTransform.M12,
M24 = rhinoTransform.M13 * conversionFactor,
M31 = rhinoTransform.M20,
M32 = rhinoTransform.M21,
M33 = rhinoTransform.M22,
M34 = rhinoTransform.M23 * conversionFactor,
M41 = rhinoTransform.M30,
M42 = rhinoTransform.M31,
M43 = rhinoTransform.M32,
@@ -136,8 +139,6 @@ public static class GrasshopperHelpers
{
switch (element)
{
case null:
break; // skip nulls (CNX-2855)
case SpeckleDataObjectWrapper dataObject:
yield return dataObject;
break;
@@ -152,7 +153,8 @@ public static class GrasshopperHelpers
yield return subElement;
}
}
break;
default:
break;
}
}
@@ -171,9 +173,11 @@ public static class GrasshopperHelpers
{
return instanceGoo.Value;
}
SpeckleGeometryWrapperGoo objGoo = new();
return objGoo.CastFrom(goo) ? objGoo.Value : null;
else
{
SpeckleGeometryWrapperGoo objGoo = new();
return objGoo.CastFrom(goo) ? objGoo.Value : null;
}
}
/// <summary>
@@ -266,9 +270,7 @@ public static class GrasshopperHelpers
for (int i = 0; i < elCount; i++)
{
var item = subset[subsetCount + i];
// GH_ObjectWrapper accepts null to preserve tree structure for failed conversions (CNX-2855)
tree.EnsurePath(myPath).Add(item != null ? new GH_ObjectWrapper(item) : new GH_ObjectWrapper(null!));
tree.EnsurePath(myPath).Add(new Grasshopper.Kernel.Types.GH_ObjectWrapper(subset[subsetCount + i]));
}
subsetCount += elCount;
@@ -291,13 +293,6 @@ public static class GrasshopperHelpers
{
topology += myPath.ToString(false) + "-" + param.VolatileData.get_Branch(myPath).Count + " ";
}
return topology;
}
/// <summary>
/// Converts Elements to Goo list, converting nulls to GH_ObjectWrapper(null) for topology preservation (CNX-2855)
/// </summary>
public static List<IGH_Goo> ToGooListWithNulls(this SpeckleCollectionWrapper coll) =>
coll.Elements.Select(e => e == null ? new GH_ObjectWrapper(null!) : ((SpeckleWrapper)e).CreateGoo()).ToList();
}
@@ -4,7 +4,6 @@ using Speckle.Connectors.GrasshopperShared.Registration;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
namespace Speckle.Connectors.GrasshopperShared.HostApp;
@@ -30,13 +29,13 @@ public class SpeckleConversionContext(IRootToSpeckleConverter speckleConverter,
}
}
public static void SetupCurrent(IServiceScope? scope = null)
public static void SetupCurrent()
{
if (s_currentContext != null)
{
return;
}
s_scope = scope ?? PriorityLoader.CreateScopeForActiveDocument();
s_scope = PriorityLoader.CreateScopeForActiveDocument();
s_currentContext = s_scope.Get<SpeckleConversionContext>();
}
@@ -51,21 +50,7 @@ public class SpeckleConversionContext(IRootToSpeckleConverter speckleConverter,
s_scope = null;
}
public Base? ConvertToSpeckle(object geo)
{
try
{
return speckleConverter.Convert(geo);
}
catch (ConversionException ex)
{
// changed as of CNX-2855
// log for debugging but don't throw - let caller handle null return
// we don't want to throw and fail whole operation, but want a way to signal to component that sumting wong
System.Diagnostics.Debug.WriteLine($"Conversion failed for {geo.GetType().Name}: {ex.Message}");
return null;
}
}
public Base ConvertToSpeckle(object geo) => speckleConverter.Convert(geo);
public List<(object, Base)> ConvertToHost(Base input)
{
@@ -75,7 +60,6 @@ public class SpeckleConversionContext(IRootToSpeckleConverter speckleConverter,
{
GeometryBase geometry => [(geometry, input)],
List<GeometryBase> geometryList => geometryList.Select(o => ((object)o, input)).ToList(),
List<(GeometryBase, Base)> pairList when pairList.Count == 0 => [],
IEnumerable<(GeometryBase, Base)> fallbackConversionResult
=> fallbackConversionResult.Select(o => ((object)o.Item1, o.Item2)).ToList(),
object obj => [(obj, input)],
@@ -1,20 +1,12 @@
using Microsoft.Extensions.Logging;
using Rhino.Geometry;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.GrasshopperShared.HostApp;
using Speckle.Connectors.GrasshopperShared.Operations.Receive;
using Speckle.Connectors.GrasshopperShared.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Common.ToHost;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.GraphTraversal;
using Speckle.Sdk.Models.Instances;
using DataObject = Speckle.Objects.Data.DataObject;
namespace Speckle.Connectors.GrasshopperShared.Operations.Receive;
/// <summary>
/// Handles conversion of atomic objects from TraversalContexts into Grasshopper wrapper objects.
@@ -27,404 +19,184 @@ namespace Speckle.Connectors.GrasshopperShared.Operations.Receive;
internal sealed class LocalToGlobalMapHandler
{
public Dictionary<string, SpeckleGeometryWrapper> ConvertedObjectsMap { get; } = new();
public readonly GrasshopperCollectionRebuilder CollectionRebuilder;
// injected via constructor (DI-managed)
private readonly IDataObjectInstanceRegistry _dataObjectInstanceRegistry;
private readonly ILogger<LocalToGlobalMapHandler> _logger;
private readonly IConverterSettingsStore<RhinoConversionSettings> _settingsStore;
// set via Initialize() method (per-operation data)
private TraversalContextUnpacker _traversalContextUnpacker = null!;
private GrasshopperColorUnpacker _colorUnpacker = null!;
private GrasshopperMaterialUnpacker _materialUnpacker = null!;
private IReadOnlyCollection<InstanceDefinitionProxy>? _definitionProxies;
// auto property (fixes IDE0032)
public GrasshopperCollectionRebuilder CollectionRebuilder { get; private set; } = null!;
private readonly TraversalContextUnpacker _traversalContextUnpacker;
private readonly GrasshopperColorUnpacker _colorUnpacker;
private readonly GrasshopperMaterialUnpacker _materialUnpacker;
public LocalToGlobalMapHandler(
IDataObjectInstanceRegistry dataObjectInstanceRegistry,
ILogger<LocalToGlobalMapHandler> logger,
IConverterSettingsStore<RhinoConversionSettings> settingsStore
)
{
_dataObjectInstanceRegistry = dataObjectInstanceRegistry;
_logger = logger;
_settingsStore = settingsStore;
}
/// <summary>
/// Initializes the handler with per-operation data.
/// Must be called before using ConvertAtomicObjects or ConvertBlockInstances.
/// </summary>
public LocalToGlobalMapHandler Initialize(
TraversalContextUnpacker traversalContextUnpacker,
GrasshopperColorUnpacker colorUnpacker,
GrasshopperMaterialUnpacker materialUnpacker,
GrasshopperCollectionRebuilder collectionRebuilder,
IReadOnlyCollection<InstanceDefinitionProxy>? definitionProxies
GrasshopperColorUnpacker colorUnpacker,
GrasshopperMaterialUnpacker materialUnpacker
)
{
_traversalContextUnpacker = traversalContextUnpacker;
_colorUnpacker = colorUnpacker;
_materialUnpacker = materialUnpacker;
CollectionRebuilder = collectionRebuilder;
_definitionProxies = definitionProxies;
return this;
}
/// <summary>
/// Converts all atomic objects in two passes:
/// Pass 1 - Convert normal objects and populate ConvertedObjectsMap
/// Pass 2 - Resolve registered DataObjects with InstanceProxies using the populated map
/// Converts atomic object from TraversalContext to SpeckleObjectWrapper.
/// </summary>
public void ConvertAtomicObjects(IEnumerable<TraversalContext> atomicContexts)
{
// Cache to avoid re-iterating for registered check
var atomicList = atomicContexts as IList<TraversalContext> ?? atomicContexts.ToList();
// Pass 1: Convert all non-registered DataObjects to populate ConvertedObjectsMap
foreach (var atomicContext in atomicList)
{
ConvertObjectToCache(atomicContext);
}
// Pass 2: Process registered DataObjects (definitions now available in ConvertedObjectsMap)
foreach (var atomicContext in atomicList)
{
if (atomicContext.Current is DataObject dataObject)
{
var dataObjectId = dataObject.applicationId ?? dataObject.id;
if (dataObjectId is not null && _dataObjectInstanceRegistry.IsRegistered(dataObjectId))
{
ResolveDataObjectInstanceProxies(atomicContext);
}
}
}
}
/// <summary>
/// Converts and caches an atomic object for later lookup.
/// Skips registered DataObjects (displayValue is InstanceProxy) - they are resolved in ResolveDataObjectInstanceProxies.
/// </summary>
private void ConvertObjectToCache(TraversalContext atomicContext)
public void ConvertAtomicObject(TraversalContext atomicContext)
{
var obj = atomicContext.Current;
var objId = obj.applicationId ?? obj.id;
if (objId is null || ConvertedObjectsMap.ContainsKey(objId))
if (objId == null || ConvertedObjectsMap.ContainsKey(objId))
{
return;
}
// skip registered DataObjects - they'll be processed in second pass
if (obj is DataObject dataObject)
{
var id = dataObject.applicationId ?? dataObject.id.NotNull();
if (_dataObjectInstanceRegistry.IsRegistered(id))
{
return;
}
}
try
{
List<(object, Base)> converted = SpeckleConversionContext.Current.ConvertToHost(obj);
// get path and collection
var path = _traversalContextUnpacker.GetCollectionPath(atomicContext).ToList();
var objectCollection = CollectionRebuilder.GetOrCreateSpeckleCollectionFromPath(
path,
_colorUnpacker,
_materialUnpacker
);
// nothing converted - nothing to do
if (converted.Count == 0)
{
return;
}
// handle normal DataObject (has converted geometry)
if (obj is DataObject normalDataObject)
{
var geometries = ConvertToGeometryWrappers(converted);
var dataObjectWrapper = CreateDataObjectWrapper(normalDataObject, geometries, path, objectCollection);
CollectionRebuilder.AppendSpeckleGrasshopperObject(dataObjectWrapper, path, _colorUnpacker, _materialUnpacker);
return;
}
// handle normal geometry (not DataObject)
SpecklePropertyGroupGoo propertyGroup = new();
if (obj[Constants.PROPERTIES_PROP] is Dictionary<string, object?> props)
{
propertyGroup.CastFrom(props);
}
foreach ((object convertedObj, Base original) in converted)
{
if (convertedObj is GeometryBase geometryBase)
{
var wrapper = new SpeckleGeometryWrapper()
{
Base = original,
Path = path.Select(p => p.name).ToList(),
Parent = objectCollection,
GeometryBase = geometryBase,
Properties = propertyGroup,
Name = obj[Constants.NAME_PROP] as string ?? "",
Color = _colorUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjColor)
? cachedObjColor
: null,
Material = _materialUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjMaterial)
? cachedObjMaterial
: null,
ApplicationId = objId
};
ConvertedObjectsMap[objId] = wrapper;
CollectionRebuilder.AppendSpeckleGrasshopperObject(wrapper, path, _colorUnpacker, _materialUnpacker);
}
}
}
catch (Exception ex) when (!ex.IsFatal())
{
// don't throw - continue processing other objects
_logger.LogError(ex, "Failed to convert object {objectId} of type {objectType}", objId, obj.speckle_type);
}
}
/// <summary>
/// Resolves a registered DataObject by transforming its InstanceProxy definition objects.
/// Requires definition objects to exist in ConvertedObjectsMap (populated by ConvertObjectToCache).
/// </summary>
private void ResolveDataObjectInstanceProxies(TraversalContext atomicContext)
{
var obj = atomicContext.Current;
if (obj is not DataObject dataObject)
{
return;
}
var dataObjectId = dataObject.applicationId ?? dataObject.id.NotNull();
if (!_dataObjectInstanceRegistry.IsRegistered(dataObjectId))
{
return;
}
try
{
var path = _traversalContextUnpacker.GetCollectionPath(atomicContext).ToList();
// Always create collection - consumed objects will be cleaned up later
var objectCollection = CollectionRebuilder.GetOrCreateSpeckleCollectionFromPath(
path,
_colorUnpacker,
_materialUnpacker
);
var entry = _dataObjectInstanceRegistry.GetEntries()[dataObjectId];
var resolvedGeometries = ResolveInstanceProxiesToGeometries(entry.InstanceProxies);
var dataObjectWrapper = CreateDataObjectWrapper(dataObject, resolvedGeometries, path, objectCollection);
if (obj is Speckle.Objects.Data.DataObject dataObject)
{
// get color and mat on dataobject first
Color? dataObjColor = _colorUnpacker.Cache.TryGetValue(
dataObject.applicationId ?? "",
out var cachedDataObjColor
)
? cachedDataObjColor
: null;
CollectionRebuilder.AppendSpeckleGrasshopperObject(dataObjectWrapper, path, _colorUnpacker, _materialUnpacker);
SpeckleMaterialWrapper? dataObjMat = _materialUnpacker.Cache.TryGetValue(
dataObject.applicationId ?? "",
out var cachedDataObjMaterial
)
? cachedDataObjMaterial
: null;
// get geometries
List<SpeckleGeometryWrapper> geometries = new();
foreach ((object convertedObj, Base original) in converted)
{
if (convertedObj is GeometryBase geometryBase)
{
SpeckleGeometryWrapper wrapper =
new()
{
Base = original,
GeometryBase = geometryBase,
Color = _colorUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjColor)
? cachedObjColor
: dataObjColor,
Material = _materialUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjMaterial)
? cachedObjMaterial
: dataObjMat,
};
geometries.Add(wrapper);
}
}
SpecklePropertyGroupGoo propertyGroup = new();
propertyGroup.CastFrom(dataObject.properties);
// remove the displayvalue of the original dataobject since these are now processed and stored on the wrapper
// to prevent storing of duplicate Base
dataObject.displayValue.Clear();
var dataObjectWrapper = new SpeckleDataObjectWrapper()
{
Base = dataObject,
Geometries = geometries,
Path = path.Select(p => p.name).ToList(),
Parent = objectCollection,
Name = dataObject.name,
Properties = propertyGroup,
ApplicationId = dataObject.applicationId,
};
// Add to collections (not to map since these won't be definition objects)
CollectionRebuilder.AppendSpeckleGrasshopperObject(dataObjectWrapper, path, _colorUnpacker, _materialUnpacker);
}
else
{
SpecklePropertyGroupGoo propertyGroup = new();
if (obj[Constants.PROPERTIES_PROP] is Dictionary<string, object?> props)
{
propertyGroup.CastFrom(props);
}
foreach ((object convertedObj, Base original) in converted)
{
if (convertedObj is GeometryBase geometryBase)
{
var wrapper = new SpeckleGeometryWrapper()
{
Base = original,
Path = path.Select(p => p.name).ToList(),
Parent = objectCollection,
GeometryBase = geometryBase,
Properties = propertyGroup,
Name = obj[Constants.NAME_PROP] as string ?? "",
Color = _colorUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjColor)
? cachedObjColor
: null,
Material = _materialUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjMaterial)
? cachedObjMaterial
: null,
ApplicationId = objId
};
// Always add to both map and collections
ConvertedObjectsMap[objId] = wrapper;
CollectionRebuilder.AppendSpeckleGrasshopperObject(wrapper, path, _colorUnpacker, _materialUnpacker);
}
}
}
}
catch (Exception ex) when (!ex.IsFatal())
{
// don't throw - continue processing other DataObjects
_logger.LogError(ex, "Failed to resolve DataObject {dataObjectId} with InstanceProxies", dataObjectId);
// TODO: throw?
}
}
/// <summary>
/// Converts block instances and definitions from traversal contexts into Grasshopper wrapper objects.
/// Automatically filters out InstanceProxies belonging to registered DataObjects.
/// Automatically handles cleanup of consumed objects from the collection hierarchy.
/// </summary>
public void ConvertBlockInstances(IReadOnlyCollection<TraversalContext> blockInstances)
/// <remarks>
/// Deliberately handles both block conversion AND consumed object cleanup in a single operation.
/// Too much, I know, BUT it ensures the cleanup always occurs immediately after block processing without
/// requiring receive components to call a separate cleanup method in the correct order.
/// </remarks>
public void ConvertBlockInstances(
IReadOnlyCollection<TraversalContext> blocks,
IReadOnlyCollection<InstanceDefinitionProxy>? definitionProxies
)
{
// build set of registered InstanceProxy IDs for fast lookup
var registeredProxyIds = new HashSet<string>();
foreach (var entry in _dataObjectInstanceRegistry.GetEntries().Values)
{
foreach (var proxy in entry.InstanceProxies)
{
var proxyId = proxy.applicationId ?? proxy.id;
if (proxyId is not null)
{
registeredProxyIds.Add(proxyId);
}
}
}
// filter out InstanceProxies that belong to registered DataObjects
var filteredBlockInstances = blockInstances
.Where(tc =>
{
if (tc.Current is InstanceProxy proxy)
{
var proxyId = proxy.applicationId ?? proxy.id;
return proxyId is null || !registeredProxyIds.Contains(proxyId);
}
return true;
})
.ToList();
var blockUnpacker = new GrasshopperBlockUnpacker(_traversalContextUnpacker, _colorUnpacker, _materialUnpacker);
// get consumed object IDs from unpacker
// Get consumed object IDs from unpacker
var consumedObjectIds = blockUnpacker.UnpackBlocks(
filteredBlockInstances,
_definitionProxies,
blocks,
definitionProxies,
ConvertedObjectsMap,
CollectionRebuilder
);
// clean up consumed objects from collections
// Clean up consumed objects from collections
CollectionRebuilder.RemoveConsumedObjects(consumedObjectIds);
}
/// <summary>
/// Creates a DataObjectWrapper from a DataObject and its geometries.
/// Handles color/material inheritance and property extraction.
/// </summary>
private SpeckleDataObjectWrapper CreateDataObjectWrapper(
DataObject dataObject,
List<SpeckleGeometryWrapper> geometries,
List<Collection> path,
SpeckleCollectionWrapper objectCollection
)
{
// Get color and material on DataObject
Color? dataObjColor = _colorUnpacker.Cache.TryGetValue(dataObject.applicationId ?? "", out var cachedDataObjColor)
? cachedDataObjColor
: null;
SpeckleMaterialWrapper? dataObjMat = _materialUnpacker.Cache.TryGetValue(
dataObject.applicationId ?? "",
out var cachedDataObjMaterial
)
? cachedDataObjMaterial
: null;
// Apply DataObject color/material to geometries that don't have their own
foreach (var geometry in geometries)
{
geometry.Color ??= dataObjColor;
geometry.Material ??= dataObjMat;
}
// Create property group
SpecklePropertyGroupGoo propertyGroup = new();
propertyGroup.CastFrom(dataObject.properties);
// Clear the displayValue to prevent storing duplicate Base
dataObject.displayValue.Clear();
return new SpeckleDataObjectWrapper()
{
Base = dataObject,
Geometries = geometries,
Path = path.Select(p => p.name).ToList(),
Parent = objectCollection,
Name = dataObject.name,
Properties = propertyGroup,
ApplicationId = dataObject.applicationId,
};
}
/// <summary>
/// Resolves InstanceProxy displayValues to transformed geometries.
/// Returns the list of resolved geometries that can be used as DataObject displayValue replacements.
/// </summary>
private List<SpeckleGeometryWrapper> ResolveInstanceProxiesToGeometries(List<InstanceProxy> instanceProxies)
{
var resolvedGeometries = new List<SpeckleGeometryWrapper>();
// build a lookup of definitionId -> definition objects for quick access
var definitionObjectsMap = new Dictionary<string, List<string>>();
if (_definitionProxies is not null)
{
foreach (var defProxy in _definitionProxies)
{
var defId = defProxy.applicationId ?? defProxy.id;
if (defId is not null)
{
definitionObjectsMap[defId] = defProxy.objects;
}
}
}
foreach (var instanceProxy in instanceProxies)
{
// get the definition objects for this instance
if (!definitionObjectsMap.TryGetValue(instanceProxy.definitionId, out var definitionObjectIds))
{
continue; // definition not found, skip this proxy
}
// get transform from the instance proxy
var transform = GrasshopperHelpers.MatrixToTransform(instanceProxy.transform, instanceProxy.units);
// apply transform to each definition object
foreach (var objectId in definitionObjectIds)
{
if (ConvertedObjectsMap.TryGetValue(objectId, out var definitionObject))
{
// deep copy and transform the geometry
var transformedWrapper = definitionObject.DeepCopy();
// transform the GeometryBase
transformedWrapper.GeometryBase.NotNull().Transform(transform);
// keep Base and GeometryBase in sync (CNX-2847)
// Exception shouldn't ever happen for objects in ConvertedObjectsMap
transformedWrapper.Base =
SpeckleConversionContext.Current.ConvertToSpeckle(transformedWrapper.GeometryBase)
?? throw new InvalidOperationException($"Failed to convert transformed geometry for object {objectId}");
// preserve metadata from original Base
transformedWrapper.Base.applicationId = definitionObject.Base.applicationId;
transformedWrapper.Base["units"] = _settingsStore.Current.SpeckleUnits;
resolvedGeometries.Add(transformedWrapper);
}
}
}
return resolvedGeometries;
}
/// <summary>
/// Converts the raw converted objects to SpeckleGeometryWrappers for DataObject display values.
/// Does NOT apply DataObject-level colors/materials - that's handled by CreateDataObjectWrapper.
/// </summary>
private List<SpeckleGeometryWrapper> ConvertToGeometryWrappers(List<(object, Base)> converted)
{
var geometries = new List<SpeckleGeometryWrapper>();
foreach ((object convertedObj, Base original) in converted)
{
if (convertedObj is GeometryBase geometryBase)
{
SpeckleGeometryWrapper wrapper =
new()
{
Base = original,
GeometryBase = geometryBase,
// try to get color/material from the individual geometry first
Color = _colorUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjColor)
? cachedObjColor
: null,
Material = _materialUnpacker.Cache.TryGetValue(original.applicationId ?? "", out var cachedObjMaterial)
? cachedObjMaterial
: null,
};
geometries.Add(wrapper);
}
}
return geometries;
}
}
@@ -35,15 +35,9 @@ public class GrasshopperRootObjectBuilder : IRootObjectBuilder<SpeckleCollection
CancellationToken ct = default
)
{
// create root collection
var rootCollectionGoo = (SpeckleRootCollectionWrapperGoo)input[0].Duplicate();
rootCollectionGoo.Value.Name = "Grasshopper Model";
RootCollection rootCollection =
new(rootCollectionGoo.Value.Name)
{
applicationId = rootCollectionGoo.Value.ApplicationId,
properties = rootCollectionGoo.Value.Properties ?? new()
};
// deep copy input (to not mutate input) and set the input collection name to "Grasshopper Model"
var inputCollectionGoo = (SpeckleCollectionWrapperGoo)input[0].Duplicate();
inputCollectionGoo.Value.Name = "Grasshopper Model";
// create packers for colors and render materials
GrasshopperColorPacker colorPacker = new();
@@ -51,15 +45,15 @@ public class GrasshopperRootObjectBuilder : IRootObjectBuilder<SpeckleCollection
GrasshopperBlockPacker blockPacker = new(_instanceObjectsManager);
// unwrap the input collection to remove all wrappers
Unwrap(rootCollectionGoo.Value, rootCollection, colorPacker, materialPacker, blockPacker);
Collection root = Unwrap(inputCollectionGoo.Value, colorPacker, materialPacker, blockPacker);
// add proxies
rootCollection[ProxyKeys.COLOR] = colorPacker.ColorProxies.Values.ToList();
rootCollection[ProxyKeys.RENDER_MATERIAL] = materialPacker.RenderMaterialProxies.Values.ToList();
rootCollection[ProxyKeys.INSTANCE_DEFINITION] = blockPacker.InstanceDefinitionProxies.Values.ToList();
root[ProxyKeys.COLOR] = colorPacker.ColorProxies.Values.ToList();
root[ProxyKeys.RENDER_MATERIAL] = materialPacker.RenderMaterialProxies.Values.ToList();
root[ProxyKeys.INSTANCE_DEFINITION] = blockPacker.InstanceDefinitionProxies.Values.ToList();
// TODO: Not getting any conversion results yet
var result = new RootObjectBuilderResult(rootCollection, []);
var result = new RootObjectBuilderResult(root, []);
return Task.FromResult(result);
}
@@ -68,47 +62,42 @@ public class GrasshopperRootObjectBuilder : IRootObjectBuilder<SpeckleCollection
// Also packs colors, render materials and block definitions into proxies while unwrapping.
private Collection Unwrap(
SpeckleCollectionWrapper wrapper,
Collection targetCollection,
GrasshopperColorPacker colorPacker,
GrasshopperMaterialPacker materialPacker,
GrasshopperBlockPacker blockPacker
)
{
Collection currentColl = wrapper.Collection;
// unpack color, render material and block definitions
colorPacker.ProcessColor(wrapper.ApplicationId, wrapper.Color);
materialPacker.ProcessMaterial(wrapper.ApplicationId, wrapper.Material);
int skippedNulls = 0;
// iterate through this wrapper's elements to unwrap children
// HashSet<string> collObjectIds = new();
foreach (ISpeckleCollectionObject? element in wrapper.Elements)
foreach (ISpeckleCollectionObject element in wrapper.Elements)
{
switch (element)
{
case null:
// CNX-2855: count skipped nulls and obvs don't add to collection (can't send nulls)
skippedNulls++;
continue;
case SpeckleCollectionWrapper collWrapper:
// create an application id for this collection if none exists. This will be used for color and render material proxies
collWrapper.ApplicationId ??= collWrapper.GetSpeckleApplicationId();
// add to collection and continue unwrap
targetCollection.elements.Add(collWrapper.Collection);
Unwrap(collWrapper, collWrapper.Collection, colorPacker, materialPacker, blockPacker);
currentColl.elements.Add(collWrapper.Collection);
Unwrap(collWrapper, colorPacker, materialPacker, blockPacker);
break;
case SpeckleGeometryWrapper so: // handles both SpeckleObjectWrapper and SpeckleBlockInstanceWrapper (inheritance)
// convert wrapper to base and add to collection - common for all object wrappers
Base objectBase = UnwrapGeometry(so);
string applicationId = objectBase.applicationId!;
targetCollection.elements.Add(objectBase);
currentColl.elements.Add(objectBase);
// do block instance specific stuff (if this object wrapper is actually a block instance)
if (so is SpeckleBlockInstanceWrapper blockInstance)
{
ProcessBlockInstanceDefinition(blockInstance, colorPacker, materialPacker, blockPacker, targetCollection);
ProcessBlockInstanceDefinition(blockInstance, colorPacker, materialPacker, blockPacker, currentColl);
}
// process color and material for all object wrappers (including block instances)
@@ -121,7 +110,7 @@ public class GrasshopperRootObjectBuilder : IRootObjectBuilder<SpeckleCollection
// UnwrapDataObject will unwrap underlying geometry and handle color and material
// arguably doing too much, but I'm apprehensive looping twice without good reason
DataObject dataObject = UnwrapDataObject(dataObjectWrapper, colorPacker, materialPacker);
targetCollection.elements.Add(dataObject);
currentColl.elements.Add(dataObject);
break;
}
}
@@ -138,14 +127,7 @@ public class GrasshopperRootObjectBuilder : IRootObjectBuilder<SpeckleCollection
}
*/
// clear topology when nulls are present - no simple way to preserve tree structure since Collection.elements
// doesn't support nulls on publish. Topology is GH-specific and optional, so clearing it is safe. (CNX-2855)
if (skippedNulls > 0)
{
targetCollection[Constants.TOPOLOGY_PROP] = null;
}
return targetCollection;
return currentColl;
}
/// <summary>
@@ -79,9 +79,6 @@ public class SpecklePropertyGoo : GH_Goo<object>, ISpecklePropertyGoo
case int i:
Value = i;
return true;
case long l:
Value = l;
return true;
case string s:
Value = s;
return true;
@@ -13,61 +13,49 @@ public partial class SpeckleBlockDefinitionWrapperGoo
switch (source)
{
case InstanceDefinition instanceDefinition:
return TryConvertDefinition(
instanceDefinition.GetObjects().Cast<object>(),
instanceDefinition.Name,
instanceDefinition.Id.ToString()
);
List<SpeckleGeometryWrapper> objects = new();
foreach (var defObj in instanceDefinition.GetObjects())
{
SpeckleGeometryWrapperGoo defObjGoo = new();
if (defObjGoo.CastFrom(defObj))
{
objects.Add(defObjGoo.Value);
}
}
if (objects.Count == 0)
{
return false;
}
SetValueFromDefinitionProps(objects, instanceDefinition.Name, instanceDefinition.Id.ToString());
return true;
case ModelInstanceDefinition modelInstanceDef:
return TryConvertDefinition(
modelInstanceDef.Objects.Cast<object>(),
modelInstanceDef.Name,
modelInstanceDef.Id.ToString()
);
List<SpeckleGeometryWrapper> defObjs = new();
foreach (var defObj in modelInstanceDef.Objects)
{
SpeckleGeometryWrapperGoo geoWrapperGoo = new();
if (geoWrapperGoo.CastFrom(defObj))
{
defObjs.Add(geoWrapperGoo.Value);
}
}
if (defObjs.Count == 0)
{
throw new InvalidOperationException(
$"Block definition '{modelInstanceDef.Name}' did not have any valid geometry."
);
}
SetValueFromDefinitionProps(defObjs, modelInstanceDef.Name, modelInstanceDef.Id.ToString());
return true;
default:
return false;
}
}
/// <summary>
/// Attempts to convert block definition objects to SpeckleGeometryWrappers.
/// Returns false if all objects are unsupported, true if at least one converts.
/// </summary>
private bool TryConvertDefinition(IEnumerable<object> definitionObjects, string definitionName, string definitionId)
{
var objects = definitionObjects as object[] ?? definitionObjects.ToArray();
int totalCount = objects.Length;
List<SpeckleGeometryWrapper> converted = new();
foreach (var defObj in objects)
{
SpeckleGeometryWrapperGoo defObjGoo = new();
if (defObjGoo.CastFrom(defObj))
{
converted.Add(defObjGoo.Value);
}
}
int skippedCount = totalCount - converted.Count;
// return false if nothing converted - Grasshopper handles this as warning (CNX-2855)
if (converted.Count == 0)
{
return false;
}
// show debug info if some objects skipped (CNX-2855)
if (skippedCount > 0)
{
System.Diagnostics.Debug.WriteLine($"Block '{definitionName}' skipped {skippedCount} unsupported object(s)");
}
SetValueFromDefinitionProps(converted, definitionName, definitionId);
return true;
}
private void SetValueFromDefinitionProps(List<SpeckleGeometryWrapper> objs, string name, string id)
{
string validAppId = string.IsNullOrWhiteSpace(id) ? Guid.NewGuid().ToString() : id;
@@ -75,13 +75,7 @@ public partial class SpeckleBlockInstanceWrapperGoo : GH_Goo<SpeckleBlockInstanc
return false;
}
Base? converted = SpeckleConversionContext.Current.ConvertToSpeckle(instance);
if (converted is null)
{
return false; // gh deals with false return from casting as warning 😎
}
Base converted = SpeckleConversionContext.Current.ConvertToSpeckle(instance);
Value = new SpeckleBlockInstanceWrapper()
{
GeometryBase = instance,
@@ -51,7 +51,7 @@ public class SpeckleCollectionWrapper : SpeckleWrapper, ISpeckleCollectionObject
}
}
public List<ISpeckleCollectionObject?> Elements { get; set; } = new();
public List<ISpeckleCollectionObject> Elements { get; set; } = new();
/// <summary>
/// The Grasshopper Topology of this collection. This setter also sets the "topology" prop dynamically on <see cref="Collection"/>
@@ -92,8 +92,6 @@ public class SpeckleCollectionWrapper : SpeckleWrapper, ISpeckleCollectionObject
{
switch (element)
{
case null:
continue; // skip nulls (CNX-2855)
case SpeckleGeometryWrapper o:
o.Path = newPath;
o.Parent = this;
@@ -122,7 +120,6 @@ public class SpeckleCollectionWrapper : SpeckleWrapper, ISpeckleCollectionObject
.Select(e =>
e switch
{
null => null, // preserve nulls (CNX-2855)
SpeckleCollectionWrapper c => c.DeepCopy(),
SpeckleBlockInstanceWrapper b => b.DeepCopy(),
SpeckleGeometryWrapper o => o.DeepCopy(),
@@ -159,11 +156,6 @@ public class SpeckleCollectionWrapper : SpeckleWrapper, ISpeckleCollectionObject
// then bake elements in this collection
foreach (var obj in Elements)
{
if (obj is null)
{
continue; // skip nulls (CNX-2855)
}
if (obj is SpeckleGeometryWrapper so)
{
if (bakeObjects)
@@ -113,18 +113,16 @@ public class SpeckleCollectionParam : GH_Param<SpeckleCollectionWrapperGoo>, IGH
{
foreach (var element in collWrapper.Elements)
{
switch (element)
if (element is SpeckleCollectionWrapper subCollWrapper)
{
case null:
continue; // skip nulls (CNX-2855)
case SpeckleCollectionWrapper subCollWrapper:
FlattenForPreview(subCollWrapper);
break;
case SpeckleGeometryWrapper objWrapper:
_previewObjects.Add(objWrapper);
var box = objWrapper.GeometryBase?.GetBoundingBox(false) ?? new BoundingBox();
_clippingBox.Union(box);
break;
FlattenForPreview(subCollWrapper);
}
if (element is SpeckleGeometryWrapper objWrapper)
{
_previewObjects.Add(objWrapper);
var box = objWrapper.GeometryBase is null ? new() : objWrapper.GeometryBase.GetBoundingBox(false);
_clippingBox.Union(box);
}
}
}
@@ -19,8 +19,8 @@ public partial class SpeckleDataObjectWrapperGoo : GH_Goo<SpeckleDataObjectWrapp
switch (source)
{
case ModelObject modelObject:
var geometryWrapperGoo = new SpeckleGeometryWrapperGoo();
if (geometryWrapperGoo.CastFrom(modelObject))
var geometryWrapperGoo = new SpeckleGeometryWrapperGoo(modelObject);
if (geometryWrapperGoo.IsValid)
{
return CastFromSpeckleGeometryWrapper(geometryWrapperGoo.Value);
}
@@ -192,11 +192,6 @@ public partial class SpeckleDataObjectWrapperGoo : GH_Goo<SpeckleDataObjectWrapp
SpeckleGeometryWrapperGoo geoGoo = new();
if (geoGoo.CastFrom(geometricGoo))
{
// check if the geometry wrapper is valid before using it (CNX-2855)
if (!geoGoo.IsValid)
{
return false;
}
return CastFromSpeckleGeometryWrapper(geoGoo.Value);
}
return false;
@@ -42,12 +42,7 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
}
GeometryBase geometryBase = geometryGoo.ToGeometryBase();
Base? converted = SpeckleConversionContext.Current.ConvertToSpeckle(geometryBase);
if (converted is null)
{
return false; // gh deals with false return from casting as warning 😎
}
Base converted = SpeckleConversionContext.Current.ConvertToSpeckle(geometryBase);
// get layer, props, color, and mat
SpeckleCollectionWrapper? collection = GetLayerCollectionFromModelObject(modelObject);
@@ -60,13 +60,7 @@ public partial class SpeckleGeometryWrapperGoo : GH_Goo<SpeckleGeometryWrapper>,
return CastFromDataObject(dataObjectWrapper);
case IGH_GeometricGoo geometricGoo:
GeometryBase gb = geometricGoo.ToGeometryBase();
Base? converted = SpeckleConversionContext.Current.ConvertToSpeckle(gb);
if (converted is null)
{
return false; // gh deals with false return from casting as warning 😎
}
Base converted = SpeckleConversionContext.Current.ConvertToSpeckle(gb);
string appId = Guid.NewGuid().ToString();
Value = gb is InstanceReferenceGeometry instance
? new SpeckleBlockInstanceWrapper()
@@ -1,42 +0,0 @@
using System.Diagnostics.CodeAnalysis;
namespace Speckle.Connectors.GrasshopperShared.Parameters;
public class SpeckleRootCollectionWrapper : SpeckleCollectionWrapper
{
public Dictionary<string, object?>? Properties { get; set; }
public SpeckleRootCollectionWrapper() { }
[SetsRequiredMembers]
public SpeckleRootCollectionWrapper(SpeckleCollectionWrapper wrapper, Dictionary<string, object?>? properties = null)
{
Base = wrapper.Base;
Color = wrapper.Color;
Material = wrapper.Material;
ApplicationId = wrapper.ApplicationId;
Name = wrapper.Name;
Path = wrapper.Path;
Topology = wrapper.Topology;
Elements = wrapper.Elements;
Properties = properties;
}
public new SpeckleRootCollectionWrapper DeepCopy()
{
// delegate most to SpeckleCollectionWrapper and we just copy result
SpeckleCollectionWrapper baseCopy = base.DeepCopy();
return new SpeckleRootCollectionWrapper
{
Base = baseCopy.Base,
Color = baseCopy.Color,
Material = baseCopy.Material,
ApplicationId = baseCopy.ApplicationId,
Name = baseCopy.Name,
Path = baseCopy.Path,
Topology = baseCopy.Topology,
Elements = baseCopy.Elements,
Properties = Properties != null ? new Dictionary<string, object?>(Properties) : null
};
}
}
@@ -1,20 +0,0 @@
using Grasshopper.Kernel.Types;
namespace Speckle.Connectors.GrasshopperShared.Parameters;
public class SpeckleRootCollectionWrapperGoo : SpeckleCollectionWrapperGoo
{
public new SpeckleRootCollectionWrapper Value { get; set; }
public SpeckleRootCollectionWrapperGoo() { }
public SpeckleRootCollectionWrapperGoo(SpeckleRootCollectionWrapper value)
: base(value)
{
Value = value;
}
public override IGH_Goo Duplicate() => new SpeckleRootCollectionWrapperGoo(Value.DeepCopy());
public override string ToString() => Value?.ToString() ?? "Invalid Root Collection";
}
@@ -15,7 +15,6 @@ using Speckle.Connectors.GrasshopperShared.Operations.Send;
using Speckle.Connectors.GrasshopperShared.Parameters;
using Speckle.Connectors.GrasshopperShared.Properties;
using Speckle.Converters.Common;
using Speckle.Converters.Common.ToHost;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Models.GraphTraversal;
@@ -59,8 +58,6 @@ public class PriorityLoader : GH_AssemblyPriority
services.AddTransient<GrasshopperReceiveOperation>();
services.AddSingleton(DefaultTraversal.CreateTraversalFunc());
services.AddTransient<TraversalContextUnpacker>();
services.AddScoped<IDataObjectInstanceRegistry, DataObjectInstanceRegistry>();
services.AddTransient<LocalToGlobalMapHandler>();
// send
services.AddTransient<IRootObjectBuilder<SpeckleCollectionWrapperGoo>, GrasshopperRootObjectBuilder>();
@@ -90,8 +90,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleDataObjectWrapperParam.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleMaterialWrapperGoo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleMaterialWrapperParam.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleRootCollectionWrapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleRootCollectionWrapperGoo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleWrapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleMaterialWrapperGoo.ModelObjects.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Parameters\Wrappers\SpeckleMaterialWrapper.cs" />
@@ -8,7 +8,6 @@
<StartProgram>$(ProgramFiles)\Rhino $(RhinoVersion)\System\Rhino.exe</StartProgram>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<UseWpf>true</UseWpf>
<PlatformTarget>x64</PlatformTarget>
<UseWindowsForms>true</UseWindowsForms>
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
</PropertyGroup>
@@ -183,27 +183,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -327,8 +306,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -361,7 +341,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.rhino7": {
@@ -371,6 +351,29 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"GrasshopperAsyncComponent": {
"type": "CentralTransitive",
"requested": "[2.0.3, )",
@@ -419,15 +422,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"System.Resources.Extensions": {
"type": "CentralTransitive",
"requested": "[9.0.4, )",
@@ -7,15 +7,14 @@
<TargetExt>.rhp</TargetExt>
<StartProgram>$(ProgramFiles)\Rhino $(RhinoVersion)\System\Rhino.exe</StartProgram>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<PlatformTarget>x64</PlatformTarget>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.9.24194.18121"/>
<PackageReference Include="RhinoWindows" IncludeAssets="compile; build" PrivateAssets="all" VersionOverride="8.9.24194.18121"/>
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" />
<PackageReference Include="RhinoWindows" IncludeAssets="compile; build" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
@@ -183,27 +183,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -327,8 +306,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -361,7 +341,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.rhino8": {
@@ -370,6 +350,29 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"GrasshopperAsyncComponent": {
"type": "CentralTransitive",
"requested": "[2.0.3, )",
@@ -418,15 +421,6 @@
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
},
"System.Resources.Extensions": {
"type": "CentralTransitive",
"requested": "[9.0.4, )",
@@ -19,8 +19,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all"/>
<PackageReference Include="RhinoWindows" IncludeAssets="compile; build" PrivateAssets="all"/>
<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>
@@ -29,20 +29,20 @@
},
"RhinoCommon": {
"type": "Direct",
"requested": "[8.25.25328.11001, )",
"resolved": "8.25.25328.11001",
"contentHash": "PDKR9GwqyUXUkTulV4J0dzDIf/aWqSJkL7nkS8ReAx8xhnt/+RQpE8gTjOSCmkSU2tjG6WzclowbTxwMTU7VAA==",
"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.25.25328.11001, )",
"resolved": "8.25.25328.11001",
"contentHash": "I/+++piwtYTue+iAAQqcMF5QlontqwNnC7Leyhiv2FiF8JpAl6K44ZsJqB7ZEUC6ns0LDfa3mbFzQwUfHwYumQ==",
"requested": "[8.21.25188.17001, )",
"resolved": "8.21.25188.17001",
"contentHash": "9zqCorcLRBeiW/j1RTwUS4E7bnZetAdA9WDdtd/AQccjOpxdtw76wdN+ciyQ6qslseWkwZ9qSBeh7QaM800Ntw==",
"dependencies": {
"RhinoCommon": "[8.25.25328.11001]"
"RhinoCommon": "[8.21.25188.17001]"
}
},
"Speckle.InterfaceGenerator": {
@@ -172,25 +172,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -254,8 +235,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -279,7 +261,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.converters.rhino8": {
@@ -288,6 +270,27 @@
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -326,15 +329,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
},
"net8.0-windows7.0/win-x64": {
@@ -1,87 +0,0 @@
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Rhino.Extensions;
using Speckle.Converters.Common;
using Speckle.Converters.Common.ToHost;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
namespace Speckle.Connectors.Rhino.HostApp;
/// <summary>
/// Groups block instances created from DataObject with InstanceProxies as display values and applies DataObject metadata.
/// </summary>
public class DataObjectInstanceGrouper
{
private readonly IConverterSettingsStore<RhinoConversionSettings> _converterSettings;
private readonly ILogger<DataObjectInstanceGrouper> _logger;
private readonly IDataObjectInstanceRegistry _dataObjectInstanceRegistry;
public DataObjectInstanceGrouper(
IConverterSettingsStore<RhinoConversionSettings> converterSettings,
ILogger<DataObjectInstanceGrouper> logger,
IDataObjectInstanceRegistry dataObjectInstanceRegistry
)
{
_converterSettings = converterSettings;
_logger = logger;
_dataObjectInstanceRegistry = dataObjectInstanceRegistry;
}
/// <summary>
/// After all instances have been created, we then run through the data object instance registry to see which instances
/// belonged to a data object. The method then groups all instances to "re-assemble" the original data object and
/// applies the properties of the data object on to the instances.
/// </summary>
/// <remarks>
/// This is a deferred action and can only occur once the RhinoInstanceBaker has done its thing.
/// </remarks>
public void GroupAndApplyProperties()
{
var doc = _converterSettings.Current.Document;
var entries = _dataObjectInstanceRegistry.GetEntries(); // see docstring
foreach (var kvp in entries)
{
var dataObjectId = kvp.Key;
var entry = kvp.Value;
try
{
var instanceIds = _dataObjectInstanceRegistry.GetInstanceIdsForDataObject(dataObjectId);
if (instanceIds.Count == 0)
{
continue;
}
// create group, name the group and apply properties
using var dataObjectAtts = entry.DataObject.GetAttributes();
var groupName = dataObjectAtts.Name;
var groupIndex = doc.Groups.Add(groupName, instanceIds.Select(id => new Guid(id)));
if (groupIndex >= 0)
{
// apply properties to each instance (doing this on an instance level because setting to group doesn't work)
foreach (var instanceId in instanceIds)
{
var rhinoObj = doc.Objects.FindId(new Guid(instanceId));
if (rhinoObj != null)
{
// set the name from DataObject
rhinoObj.Attributes.Name = dataObjectAtts.Name;
// copy all user strings
foreach (var key in dataObjectAtts.GetUserStrings().AllKeys)
{
rhinoObj.Attributes.SetUserString(key, dataObjectAtts.GetUserString(key));
}
rhinoObj.CommitChanges();
}
}
}
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to group DataObject instances {dataObjectId}", dataObjectId);
}
}
}
}
@@ -6,7 +6,6 @@ using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Instances;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Rhino.Extensions;
using Speckle.Converters.Common.ToHost;
using Speckle.DoubleNumerics;
using Speckle.Sdk;
using Speckle.Sdk.Common;
@@ -23,21 +22,18 @@ public class RhinoInstanceBaker : IInstanceBaker<IReadOnlyCollection<string>>
private readonly RhinoLayerBaker _layerBaker;
private readonly RhinoColorBaker _colorBaker;
private readonly ILogger<RhinoInstanceBaker> _logger;
private readonly IDataObjectInstanceRegistry _dataObjectInstanceRegistry;
public RhinoInstanceBaker(
RhinoLayerBaker layerBaker,
RhinoMaterialBaker rhinoMaterialBaker,
RhinoColorBaker colorBaker,
ILogger<RhinoInstanceBaker> logger,
IDataObjectInstanceRegistry dataObjectInstanceRegistry
ILogger<RhinoInstanceBaker> logger
)
{
_layerBaker = layerBaker;
_materialBaker = rhinoMaterialBaker;
_colorBaker = colorBaker;
_logger = logger;
_dataObjectInstanceRegistry = dataObjectInstanceRegistry;
}
/// <summary>
@@ -159,9 +155,6 @@ public class RhinoInstanceBaker : IInstanceBaker<IReadOnlyCollection<string>>
applicationIdMap[instanceProxyId] = new List<string>() { id.ToString() };
createdObjectIds.Add(id.ToString());
conversionResults.Add(new(Status.SUCCESS, instanceProxy, id.ToString(), "Instance (Block)"));
// link this baked instance back to its DataObject if it came from one (the method handles the check)
_dataObjectInstanceRegistry.LinkInstanceToDataObject(instanceProxyId, id.ToString());
}
}
catch (Exception ex) when (!ex.IsFatal())
@@ -123,12 +123,6 @@ public class RhinoLayerBaker : TraversalContextUnpacker
}
var cleanNewLayerName = RhinoUtils.CleanLayerName(collection.name);
if (!ModelComponent.IsValidComponentName(cleanNewLayerName))
{
throw new SpeckleException($"Layer name '{currentLayerName}' is not valid");
}
Layer newLayer = new() { Name = cleanNewLayerName, ParentLayerId = previousLayer?.Id ?? Guid.Empty };
// set material
@@ -156,7 +150,7 @@ public class RhinoLayerBaker : TraversalContextUnpacker
int index = currentDocument.Layers.Add(newLayer);
if (index == -1)
{
throw new SpeckleException($"Could not create layer '{currentLayerName}'");
throw new SpeckleException($"Could not create layer '{currentLayerName}'.");
}
_hostLayerCache.Add(currentLayerName, index);
@@ -1,9 +1,11 @@
using System.IO;
using Microsoft.Extensions.Logging;
using Rhino;
using Rhino.DocObjects;
using Rhino.Render;
using Speckle.Objects.Other;
using Speckle.Sdk;
using Speckle.Sdk.Models;
using Material = Rhino.DocObjects.Material;
using PhysicallyBasedMaterial = Rhino.DocObjects.PhysicallyBasedMaterial;
using RenderMaterial = Rhino.Render.RenderMaterial;
@@ -19,6 +21,7 @@ public class RhinoMaterialUnpacker
/// For send operations
/// </summary>
private Dictionary<string, RenderMaterialProxy> RenderMaterialProxies { get; } = new();
private Dictionary<string, string> Textures { get; } = new();
public RhinoMaterialUnpacker(ILogger<RhinoMaterialUnpacker> logger)
{
@@ -237,14 +240,32 @@ public class RhinoMaterialUnpacker
roughness = roughness,
diffuse = diffuse.ToArgb(),
emissive = emissive.ToArgb(),
applicationId = renderMaterial.Id.ToString()
applicationId = renderMaterial.Id.ToString(),
["diffuseTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_BaseColor),
["metallicTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_Metallic),
["specularTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_Specular),
["shineTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_Sheen),
["roughnessTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_Roughness),
["opacityTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.Opacity),
["bumpTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.Bump),
["emissionTexture"] = GetEncodedTexture(pbRenderMaterial, TextureType.PBR_Emission),
["typeName"] = renderMaterial.TypeName,
["ior"] = pbRenderMaterial.ReflectiveIOR,
["shine"] = pbRenderMaterial.Material.Shine,
["specular"] = pbRenderMaterial.Specular
};
// add additional dynamic props for rhino material receive
speckleRenderMaterial["typeName"] = renderMaterial.TypeName;
speckleRenderMaterial["ior"] = pbRenderMaterial.Material.IndexOfRefraction;
speckleRenderMaterial["shine"] = pbRenderMaterial.Material.Shine;
return speckleRenderMaterial;
}
private static Blob? GetEncodedTexture(PhysicallyBasedMaterial pbRenderMaterial, TextureType kind)
{
var texture = pbRenderMaterial.GetTexture(kind);
string? path = texture?.FileName;
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
return null;
}
return new Blob(path!);
}
}
@@ -1,41 +1,27 @@
using System.Text;
namespace Speckle.Connectors.Rhino.HostApp;
public static class RhinoUtils
{
private static readonly HashSet<char> s_skipChars = ['[', ']', '(', ')', '{', '}'];
private static readonly HashSet<char> s_replaceWithHyphen = [':', ';'];
public static string CleanBlockDefinitionName(string str) => str.Replace('/', '_').Replace('\\', '_');
public static string CleanBlockDefinitionName(string str)
{
return ReplaceChars(str, @"\/", "_");
}
// Cleans up layer names to be "rhino" proof. Note this can be improved, as "()[] and {}" are illegal only at the start.
// https://docs.mcneel.com/rhino/6/help/en-us/index.htm#information/namingconventions.htm?Highlight=naming
public static string CleanLayerName(string str)
{
var sb = new StringBuilder(str.Length);
str = ReplaceChars(str, @"[](){}", "");
return ReplaceChars(str, @":;", "-");
}
foreach (char c in str)
private static string ReplaceChars(string str, string invalidChars, string replaceString)
{
foreach (char c in invalidChars)
{
if (char.IsControl(c))
{
continue; // skip control characters (shoutout cnx-2809)
}
if (s_skipChars.Contains(c))
{
continue; // skip brackets
}
if (s_replaceWithHyphen.Contains(c))
{
sb.Append('-');
continue;
}
sb.Append(c);
str = str.Replace(c.ToString(), replaceString);
}
return sb.ToString();
return str;
}
}
@@ -1,65 +0,0 @@
using Microsoft.Extensions.Logging;
using Rhino.DocObjects;
using Rhino.DocObjects.Tables;
using Speckle.Converters.Common;
using Speckle.Objects.Other;
using Speckle.Sdk;
namespace Speckle.Connectors.Rhino.HostApp;
public class RhinoViewUnpacker
{
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
private readonly ILogger<RhinoViewUnpacker> _logger;
public RhinoViewUnpacker(IRootToSpeckleConverter rootToSpeckleConverter, ILogger<RhinoViewUnpacker> logger)
{
_rootToSpeckleConverter = rootToSpeckleConverter;
_logger = logger;
}
private Camera? ConvertViewToCamera(ViewInfo view)
{
try
{
var converted = (Speckle.Objects.Other.Camera)_rootToSpeckleConverter.Convert(view);
if (converted is null)
{
return null;
}
return converted;
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to create a view from {view}", view.Name);
return null;
}
}
/// <summary>
/// Iterates through a given set of rhino named views to create proxies
/// </summary>
/// <param name="views">current document named views</param>
/// <returns></returns>
public List<Camera> UnpackViews(NamedViewTable views)
{
List<Camera> cameras = new();
foreach (ViewInfo view in views)
{
// skip isometric views for now.
// getting the orthographic match between host apps and the viewer requires too much effort atm.
if (view.Viewport.IsParallelProjection)
{
continue;
}
if (ConvertViewToCamera(view) is Camera camera)
{
cameras.Add(camera);
}
}
return cameras;
}
}
@@ -10,7 +10,6 @@ using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.Rhino.Extensions;
using Speckle.Connectors.Rhino.HostApp;
using Speckle.Converters.Common;
using Speckle.Converters.Common.ToHost;
using Speckle.Converters.Rhino;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
@@ -37,8 +36,6 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
private readonly ISdkActivityFactory _activityFactory;
private readonly IThreadContext _threadContext;
private readonly IReceiveConversionHandler _conversionHandler;
private readonly IDataObjectInstanceRegistry _dataObjectInstanceRegistry;
private readonly DataObjectInstanceGrouper _dataObjectInstanceGrouper;
public RhinoHostObjectBuilder(
IRootToHostConverter converter,
@@ -51,9 +48,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
RhinoGroupBaker groupBaker,
ISdkActivityFactory activityFactory,
IThreadContext threadContext,
IReceiveConversionHandler conversionHandler,
IDataObjectInstanceRegistry dataObjectInstanceRegistry,
DataObjectInstanceGrouper dataObjectInstanceGrouper
IReceiveConversionHandler conversionHandler
)
{
_converter = converter;
@@ -67,8 +62,6 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
_activityFactory = activityFactory;
_threadContext = threadContext;
_conversionHandler = conversionHandler;
_dataObjectInstanceRegistry = dataObjectInstanceRegistry;
_dataObjectInstanceGrouper = dataObjectInstanceGrouper;
}
#pragma warning disable CA1506
@@ -195,14 +188,8 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
if (conversionIds.Count == 0)
{
// Don't throw if this DataObject was registered for instance baking
if (!_dataObjectInstanceRegistry.IsRegistered(obj.applicationId ?? obj.id.NotNull()))
{
throw new ConversionException("Object did not convert to any native geometry");
}
// Skip normal processing - will be handled by DataObjectInstanceGrouper
return;
// TODO: add this condition to report object - same as in autocad
throw new ConversionException("Object did not convert to any native geometry");
}
// 4: log
@@ -245,10 +232,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
conversionResults.UnionWith(instanceConversionResults); // add instance conversion results to our list
}
// 7.1 Group DataObject instances and apply metadata
_dataObjectInstanceGrouper.GroupAndApplyProperties();
// 7.2 Normal group creation
// 7 - Create groups
if (unpackedRoot.GroupProxies is not null)
{
_groupBaker.BakeGroups(unpackedRoot.GroupProxies, applicationIdMap, baseLayerName);
@@ -260,9 +244,6 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
private void PreReceiveDeepClean(string baseLayerName)
{
// Clear DataObject instance registry at start of new build
_dataObjectInstanceRegistry.Clear();
// Remove all previously received layers and render materials from the document
int rootLayerIndex = _converterSettings.Current.Document.Layers.Find(
Guid.Empty,
@@ -373,7 +354,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
if (objCount > 1)
{
var groupIndex = _converterSettings.Current.Document.Groups.Add(
$"{originatingObject.speckle_type.Split('.').Last()} - {parentId} ({baseLayerName})",
$@"{originatingObject.speckle_type.Split('.').Last()} - {parentId} ({baseLayerName})",
objectIds
);
@@ -33,7 +33,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
private readonly RhinoGroupUnpacker _groupUnpacker;
private readonly RhinoMaterialUnpacker _materialUnpacker;
private readonly RhinoColorUnpacker _colorUnpacker;
private readonly RhinoViewUnpacker _viewUnpacker;
private readonly PropertiesExtractor _propertiesExtractor;
private readonly ILogger<RhinoRootObjectBuilder> _logger;
private readonly ISdkActivityFactory _activityFactory;
@@ -47,7 +46,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
RhinoGroupUnpacker groupUnpacker,
RhinoMaterialUnpacker materialUnpacker,
RhinoColorUnpacker colorUnpacker,
RhinoViewUnpacker viewUnpacker,
PropertiesExtractor propertiesExtractor,
ILogger<RhinoRootObjectBuilder> logger,
ISdkActivityFactory activityFactory
@@ -61,7 +59,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
_rootToSpeckleConverter = rootToSpeckleConverter;
_materialUnpacker = materialUnpacker;
_colorUnpacker = colorUnpacker;
_viewUnpacker = viewUnpacker;
_propertiesExtractor = propertiesExtractor;
_logger = logger;
_activityFactory = activityFactory;
@@ -75,8 +72,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
)
{
using var activity = _activityFactory.Start("Build");
using var sendPipeline = new Speckle.Sdk.Pipeline.Send();
// 0 - Init the root
Collection rootObjectCollection = new() { name = _converterSettings.Current.Document.Name ?? "Unnamed document" };
rootObjectCollection["units"] = _converterSettings.Current.SpeckleUnits;
@@ -99,7 +94,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
// 3 - Convert atomic objects
List<SendConversionResult> results = new(atomicObjects.Count);
int count = 0;
using (var _ = _activityFactory.Start("Convert all"))
{
foreach (RhinoObject rhinoObject in atomicObjects)
@@ -111,8 +105,9 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
Layer layer = _converterSettings.Current.Document.Layers[rhinoObject.Attributes.LayerIndex];
Collection collectionHost = _layerUnpacker.GetHostObjectCollection(layer, rootObjectCollection);
var result = await ConvertRhinoObject(rhinoObject, collectionHost, instanceProxies, projectId, sendPipeline);
var result = ConvertRhinoObject(rhinoObject, collectionHost, instanceProxies, projectId);
results.Add(result);
++count;
onOperationProgressed.Report(new("Converting", (double)count / atomicObjects.Count));
await Task.Yield();
@@ -127,47 +122,32 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
}
// 4 - Unpack all proxies for the root
// Get all layers from the created collections on the root object commit for proxy processing
List<Layer> layers = _layerUnpacker.GetUsedLayers().ToList();
using (var _ = _activityFactory.Start("UnpackRenderMaterials"))
{
// 4 - Unpack the render material proxies
rootObjectCollection[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackRenderMaterials(atomicObjects, layers);
}
using (var _ = _activityFactory.Start("UnpackColors"))
{
// 5 - Unpack the color proxies
rootObjectCollection[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, layers);
}
// 5 - Unpack all other objects for the root
using (var _ = _activityFactory.Start("UnpackViews"))
{
List<Objects.Other.Camera> views = _viewUnpacker.UnpackViews(_converterSettings.Current.Document.NamedViews);
if (views.Count > 0)
{
rootObjectCollection[RootKeys.VIEW] = views;
}
}
await sendPipeline.Process(rootObjectCollection);
await sendPipeline.WaitForUpload();
return new RootObjectBuilderResult(new Collection() { name = "ignore" }, results);
return new RootObjectBuilderResult(rootObjectCollection, results);
}
private async Task<SendConversionResult> ConvertRhinoObject(
private SendConversionResult ConvertRhinoObject(
RhinoObject rhinoObject,
Collection collectionHost,
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
string projectId,
Sdk.Pipeline.Send sendPipeline
string projectId
)
{
string applicationId = rhinoObject.Id.ToString();
string sourceType = rhinoObject.ObjectType.ToString();
bool wasCached = false;
try
{
// get from cache or convert:
@@ -181,7 +161,6 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
{
converted = value;
wasCached = true;
}
else
{
@@ -202,17 +181,10 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
converted["properties"] = properties;
}
// process in pipeline
var reference = await sendPipeline.Process(converted).ConfigureAwait(false);
if (!wasCached)
{
_sendConversionCache.AppendSendResult(projectId, applicationId, reference);
}
// add to host
collectionHost.elements.Add(reference);
collectionHost.elements.Add(converted);
return new(Status.SUCCESS, applicationId, sourceType, reference);
return new(Status.SUCCESS, applicationId, sourceType, converted);
}
catch (Exception ex) when (!ex.IsFatal())
{
@@ -6,7 +6,7 @@ using Speckle.Connectors.Rhino.DependencyInjection;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Models.Extensions;
namespace Speckle.Connectors.Rhino.Plugin;
///<summary>
@@ -22,7 +22,6 @@ 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.Converters.Common.ToHost;
using Speckle.Sdk.Models.GraphTraversal;
namespace Speckle.Connectors.Rhino.DependencyInjection;
@@ -76,7 +75,7 @@ public static class ServiceRegistration
InstanceObjectsManager<RhinoObject, List<string>>
>();
// register unpackers and bakers
// Register unpackers and bakers
serviceCollection.AddScoped<RhinoLayerUnpacker>();
serviceCollection.AddScoped<RhinoLayerBaker>();
@@ -92,15 +91,9 @@ public static class ServiceRegistration
serviceCollection.AddScoped<RhinoColorBaker>();
serviceCollection.AddScoped<RhinoColorUnpacker>();
serviceCollection.AddScoped<RhinoViewUnpacker>();
serviceCollection.AddScoped<PropertiesExtractor>();
serviceCollection.AddScoped<RevitMappingResolver>();
// handling proxified display values
serviceCollection.AddScoped<IDataObjectInstanceRegistry, DataObjectInstanceRegistry>();
serviceCollection.AddScoped<DataObjectInstanceGrouper>();
// register helpers
serviceCollection.AddScoped<RhinoLayerHelper>();
serviceCollection.AddScoped<RhinoObjectHelper>();
@@ -23,9 +23,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RhinoSendBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RhinoSelectionBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\AttributeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\DataObjectInstanceGrouper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Properties\PropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoViewUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoLayerHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoObjectHelper.cs" />
@@ -64,4 +62,4 @@
<Compile Include="$(MSBuildThisFileDirectory)Plugin\Speckle.Connectors.RhinoCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\Speckle.Connectors.RhinoPlugin.cs" />
</ItemGroup>
</Project>
</Project>
@@ -208,27 +208,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -346,8 +325,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -380,9 +360,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
@@ -427,15 +430,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -227,27 +227,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -427,8 +406,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -461,9 +441,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
@@ -508,15 +511,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -227,27 +227,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -427,8 +406,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -461,9 +441,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
@@ -508,15 +511,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -279,9 +258,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -305,15 +307,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -279,9 +258,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -305,15 +307,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -169,27 +169,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -280,8 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -305,9 +285,32 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )",
"Microsoft.CSharp": "[4.7.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -346,15 +349,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -155,25 +155,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -229,8 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -254,9 +236,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -295,15 +298,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -155,25 +155,6 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"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.11.1"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
@@ -229,8 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )",
"Speckle.Sdk": "[1.0.0, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
}
},
"speckle.connectors.dui": {
@@ -254,9 +236,30 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[1.0.0, )"
}
},
"speckle.objects": {
"type": "Project",
"dependencies": {
"Speckle.Sdk": "[1.0.0, )"
}
},
"speckle.sdk": {
"type": "Project",
"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": "[1.0.0, )"
}
},
"speckle.sdk.dependencies": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -295,15 +298,6 @@
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
}
}
}
}
@@ -1,6 +1,5 @@
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Converters.Autocad.ToHost.Helpers;
using Speckle.Converters.AutocadShared.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Registration;
@@ -31,6 +30,5 @@ public static class ServiceRegistration
serviceCollection.AddScoped<IPropertiesExtractor, PropertiesExtractor>();
serviceCollection.AddScoped<ExtensionDictionaryExtractor>();
serviceCollection.AddScoped<XDataExtractor>();
serviceCollection.AddScoped<EntityUnitConverter>();
}
}
@@ -22,11 +22,8 @@
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\ExtrusionXToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\SubDXToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\BrepXToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\SolidXToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\MeshToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Geometry\DataObjectConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Helpers\EntityUnitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Raw\RawEncodingToHostConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Raw\AutocadPolycurveToHostPolyline2dRawConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Raw\AutocadPolycurveToHostPolyline3dRawConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToHost\Raw\AutocadPolycurveToHostPolylineRawConverter.cs" />
@@ -61,7 +58,6 @@
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\ExtensionDictionaryExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\IPropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\PropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\Solid3dToRawEncodingConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\BrepToSpeckleRawConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\CircularArc2dToSpeckleRawConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\DBArcToSpeckleRawConverter.cs" />
@@ -92,7 +88,4 @@
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\DBSplineToSpeckleRawConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\VectorToSpeckleRawConverter.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)ToHost\Helpers\" />
</ItemGroup>
</Project>
@@ -1,12 +1,9 @@
using Speckle.Converters.Autocad.ToHost.Helpers;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Objects;
using Speckle.Objects.Data;
using Speckle.Objects.Other;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Instances;
namespace Speckle.Converters.AutocadShared.ToHost.Geometry;
@@ -20,8 +17,6 @@ public class DataObjectConverter : IToHostTopLevelConverter, ITypedConverter<Dat
private readonly ITypedConverter<SOG.Point, ADB.DBPoint> _pointConverter;
private readonly ITypedConverter<SOG.SubDX, List<(ADB.Entity a, Base b)>> _subDXConverter;
private readonly ITypedConverter<SOG.Region, ADB.Entity> _regionConverter;
private readonly ITypedConverter<RawEncoding, List<ADB.Entity>> _rawEncodingConverter;
private readonly EntityUnitConverter _entityUnitConverter;
public DataObjectConverter(
ITypedConverter<ICurve, List<(ADB.Entity, Base)>> curveConverter,
@@ -30,9 +25,7 @@ public class DataObjectConverter : IToHostTopLevelConverter, ITypedConverter<Dat
ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> meshConverter,
ITypedConverter<SOG.Point, ADB.DBPoint> pointConverter,
ITypedConverter<SOG.SubDX, List<(ADB.Entity a, Base b)>> subDXConverter,
ITypedConverter<SOG.Region, ADB.Entity> regionConverter,
ITypedConverter<RawEncoding, List<ADB.Entity>> rawEncodingConverter,
EntityUnitConverter entityUnitConverter
ITypedConverter<SOG.Region, ADB.Entity> regionConverter
)
{
_curveConverter = curveConverter;
@@ -42,8 +35,6 @@ public class DataObjectConverter : IToHostTopLevelConverter, ITypedConverter<Dat
_pointConverter = pointConverter;
_subDXConverter = subDXConverter;
_regionConverter = regionConverter;
_rawEncodingConverter = rawEncodingConverter;
_entityUnitConverter = entityUnitConverter;
}
public object Convert(Base target) => Convert((DataObject)target);
@@ -51,41 +42,14 @@ public class DataObjectConverter : IToHostTopLevelConverter, ITypedConverter<Dat
public List<(ADB.Entity a, Base b)> Convert(DataObject target)
{
var result = new List<(ADB.Entity a, Base b)>();
if (target.displayValue.Count > 0 && target.displayValue[0] is InstanceProxy)
{
return []; // return empty - defer to instance baker
}
// Check for SAT encoding first for lossless round-trip
if (target["encodedValue"] is RawEncoding encoding && encoding.format == RawEncodingFormats.ACAD_SAT)
{
try
{
var entities = _rawEncodingConverter.Convert(encoding);
if (entities.Count > 0)
{
// SAT format is unitless - scale entities if source and target units differ
_entityUnitConverter.ScaleIfNeeded(entities, target["units"] as string);
return entities.Select(e => (e, (Base)target)).ToList();
}
}
catch (ConversionException)
{
// Fall through to displayValue conversion
}
}
// Fallback: convert displayValue geometry
foreach (var item in target.displayValue)
{
result.AddRange(ConvertDisplayObject(item));
}
return result;
}
private IEnumerable<(ADB.Entity a, Base b)> ConvertDisplayObject(Base displayObject)
public IEnumerable<(ADB.Entity a, Base b)> ConvertDisplayObject(Base displayObject)
{
switch (displayObject)
{
@@ -1,72 +0,0 @@
using Speckle.Converters.Autocad.ToHost.Helpers;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Objects.Other;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
namespace Speckle.Converters.Autocad.Geometry;
/// <summary>
/// Converts a SolidX to AutoCAD Solid3d entities with lossless round-tripping via SAT encoding.
/// </summary>
[NameAndRankValue(typeof(SOG.SolidX), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class SolidXToHostConverter : IToHostTopLevelConverter, ITypedConverter<SOG.SolidX, List<(ADB.Entity a, Base b)>>
{
private readonly ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> _meshConverter;
private readonly ITypedConverter<RawEncoding, List<ADB.Entity>> _rawEncodingConverter;
private readonly EntityUnitConverter _entityUnitConverter;
private readonly ISdkActivityFactory _activityFactory;
public SolidXToHostConverter(
ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> meshConverter,
ITypedConverter<RawEncoding, List<ADB.Entity>> rawEncodingConverter,
EntityUnitConverter entityUnitConverter,
ISdkActivityFactory activityFactory
)
{
_meshConverter = meshConverter;
_rawEncodingConverter = rawEncodingConverter;
_entityUnitConverter = entityUnitConverter;
_activityFactory = activityFactory;
}
public object Convert(Base target) => Convert((SOG.SolidX)target);
public List<(ADB.Entity a, Base b)> Convert(SOG.SolidX target)
{
// Try to decode raw encoding first for lossless conversion
if (target.encodedValue?.format == RawEncodingFormats.ACAD_SAT)
{
try
{
List<ADB.Entity> entities = _rawEncodingConverter.Convert(target.encodedValue);
if (entities.Count > 0)
{
// SAT format is unitless - scale entities if source and target units differ
_entityUnitConverter.ScaleIfNeeded(entities, target.units);
return entities.Select(entity => ((ADB.Entity)entity, (Base)target)).ToList();
}
}
catch (ConversionException ex)
{
// Log the failure and fall through to displayValue fallback
using var activity = _activityFactory.Start("SolidX Raw Encoding Fallback");
activity?.SetStatus(SdkActivityStatusCode.Error);
activity?.RecordException(ex);
}
}
// Fallback: Convert displayValue meshes to PolyFaceMesh
var result = new List<ADB.PolyFaceMesh>();
foreach (SOG.Mesh mesh in target.displayValue)
{
ADB.PolyFaceMesh convertedMesh = _meshConverter.Convert(mesh);
result.Add(convertedMesh);
}
return result.Zip(target.displayValue, (a, b) => ((ADB.Entity)a, (Base)b)).ToList();
}
}
@@ -1,31 +0,0 @@
using Speckle.Converters.Common;
using Speckle.Sdk.Common;
namespace Speckle.Converters.Autocad.ToHost.Helpers;
/// <summary>
/// Scales AutoCAD entities from source units to target units.
/// SAT format is unitless, so we need to apply unit conversion manually after import.
/// </summary>
public class EntityUnitConverter(IConverterSettingsStore<AutocadConversionSettings> settingsStore)
{
public void ScaleIfNeeded(List<ADB.Entity> entities, string? sourceUnits)
{
if (string.IsNullOrEmpty(sourceUnits))
{
return;
}
double scaleFactor = Units.GetConversionFactor(sourceUnits, settingsStore.Current.SpeckleUnits);
if (Math.Abs(scaleFactor - 1.0) < 1e-10)
{
return;
}
var scaleMatrix = AG.Matrix3d.Scaling(scaleFactor, AG.Point3d.Origin);
foreach (var entity in entities)
{
entity.TransformBy(scaleMatrix);
}
}
}

Some files were not shown because too many files have changed in this diff Show More