Compare commits

...

39 Commits

Author SHA1 Message Date
Jedd Morgan 293e478e01 wip 2026-01-29 11:52:47 +03:00
Jedd Morgan db205024cc fix(grasshopper): Fix grasshoper's mark received and clarify sourceApplication ambeguity (#1260)
* Rename `SourceApplication` to something more descriptive

* Bump SDK version

* fix deps
2026-01-27 10:05:32 +00:00
kekesidavid fa8e4d2528 fix(revit): combining instance proxy cache key with mesh id (#1259)
* combining instance proxy cache key with mesh id

* cleanup
2026-01-26 16:34:16 +01:00
Dogukan Karatas 31c2d8d5b3 Merge pull request #1254 from specklesystems/dogukan/cnx-2919-rhino-materials-to-revit-materials-over-name
feat (revit): match materials by name on receive
2026-01-22 11:21:06 +01:00
Björn Steinhagen e22527f85e Merge branch 'dev' into dogukan/cnx-2919-rhino-materials-to-revit-materials-over-name 2026-01-22 12:12:52 +02:00
Jedd Morgan f082cf6723 Main to dev (#1256)
* Merge pull request #1250 from specklesystems/jedd/cnx-2869-revit-crashes-performance-issues-caused-by-speckle-connector

fix(revit): Ensure top level exception handler will catch RevitIdleManager calls

* Add logging for revitildlemanager reentry misuse (#1253)

* feat(revit)!: Enable config for disabling API listening events (#1255)

* Expose options to disable revit listening events

* fix mistake

* Disable change tracking for revit when document listener is disabled

* Check first

---------

Co-authored-by: Björn Steinhagen <88777268+bjoernsteinhagen@users.noreply.github.com>
2026-01-21 19:28:17 +00:00
Jedd Morgan c4184f2662 Merge branch 'dev' into jrm/main-to-dev 2026-01-21 19:19:35 +00:00
Jedd Morgan c0b38f0e12 feat(revit)!: Enable config for disabling API listening events (#1255)
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
* Expose options to disable revit listening events

* fix mistake

* Disable change tracking for revit when document listener is disabled

* Check first
2026-01-21 19:10:34 +00:00
Jedd Morgan 4a88380fd2 Add logging for revitildlemanager reentry misuse (#1253) 2026-01-21 17:52:06 +00:00
Dogukan Karatas 04132e88ac fix material name 2026-01-21 15:16:25 +01:00
Dogukan Karatas 3e3003827b quick null check 2026-01-21 13:51:20 +01:00
Dogukan Karatas e3bd4f6365 match materials 2026-01-21 10:57:08 +01:00
Mucahit Bilal GOKER 6e6d52509c fix(revit): imported elements not published (#1251)
* move invalid check to category filter

* csharpier format fix
2026-01-20 16:17:11 +03:00
Jedd Morgan 637ffbfc54 Merge pull request #1250 from specklesystems/jedd/cnx-2869-revit-crashes-performance-issues-caused-by-speckle-connector
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
fix(revit): Ensure top level exception handler will catch RevitIdleManager calls
2026-01-19 17:12:23 +00:00
Mucahit Bilal GOKER 32b26f8c86 ABGR to ARGB (#1249) 2026-01-19 13:12:15 +03:00
Björn Steinhagen c41c57544a Merge pull request #1246 from specklesystems/dev
dev -> main
2026-01-16 18:19:25 +02:00
Björn Steinhagen 6687383ce4 Merge pull request #1245 from specklesystems/main-backmerge
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
main backmerge
2026-01-16 18:13:52 +02:00
Björn f08d52e080 Merge branch 'dev' into main-backmerge 2026-01-16 18:08:34 +02:00
Dogukan Karatas 4dcf9910a5 fix (revit): handle receive for DataObjects with proxified displayValue (#1239)
* dataobject registery

* remove registery

* added helper function

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2026-01-16 15:08:43 +00:00
Jonathon Broughton 9a61ded43e removes parameters from NavisworksRootObjectBuilder (#1244)
Converts properties for skip node merging and disable grouping
into settable values and removes their initialisation parameters.
This simplifies the class structure and improves flexibility.
2026-01-16 18:04:30 +03:00
Oğuzhan Koral 5acb0b80ab Merge pull request #1243 from specklesystems/dev
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
Update dev into main
2026-01-16 15:01:22 +03:00
Oğuzhan Koral ba41ceca2f fix(revit): revit crashes and performance issues (#1242)
* Subscribe doc change events only if we have sender model card

* Bring old but GOLD idle manager

* Add tasks back

* fix format

* Simplify event invoke from document model store for cards
2026-01-16 14:56:23 +03:00
Björn Steinhagen 8474088e5b Merge pull request #1240 from specklesystems/dev
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
dev -> main
2026-01-15 18:20:53 +02:00
Jedd Morgan fe042d7a1c Merge pull request #1241 from specklesystems/main-backmerge
Main backmerge
2026-01-15 16:16:13 +00:00
Jedd Morgan d681c63a05 Merge branch 'dev' into main-backmerge 2026-01-15 16:13:30 +00:00
Jonathon Broughton bdc0e2b5bd fix(Navisworks) Fixed Instancing and memory leaking (#1237)
* Refactors Navisworks build process for resilience

Adds error checking to ensure the Navisworks version is set before build occurs, and improves error handling to avoid empty output directories.

Updates file copy logic to handle resource and ribbon files correctly.
Ensures that the Navisworks plugin is correctly packaged and deployed.

Addresses CNX-2788

* improves fragment collection logic in converter

Refines the collection process by ensuring that fragment paths match the length of the identity path before further processing. This change enhances the accuracy of fragment stacking.

Relates to ongoing work on instancing.

* improves path validation efficiency and clarity

Caches array lengths for path validation to enhance performance.

Revises validation logic to consolidate checks and streamline code readability.

Ensures paths without valid array data are properly skipped.

* refactors geometry converter for improved instancing

* adds instance handling and path utilities

Introduces functionality for discovering and managing instance paths.

Enhances path handling with a new record structure for better data management.

Implements a registry to track and group instance paths effectively.

* replaces DisplayValueExtractor with a new implementation

Redefines the DisplayValueExtractor to simplify dependencies by removing unnecessary components.

Updates GetDisplayValue method for cleaner logic and ensures it handles null model items more gracefully.

* updates geometry conversion registration process

Refactors the service registration for geometry conversion to ensure that it retrieves the current settings and registry instance from the service provider. This change supports instancing functionality within the conversion process.

* geometry processing with improved instance handling

Adds instance registry for managing geometry paths
Refactors fragment collection for more efficient processing
Clarifies logic for transforming and processing geometries

* improves geometry instance processing

Enhances the handling of geometry instances by capturing world transformation data and ensuring proper registration.

Updates the method for processing path fragments to return instance world data, allowing for improved conversion and registration of instances.

Fixes potential logic bottlenecks in instance transformation retrieval.

* adds instance fragment registry implementation

Introduces a new interface and concrete class for managing instance fragments, including functionality for grouping, conversion tracking, and world coordinates.

Improves structure for better management of instance data within the application.

* removes old geometry helper methods and adds new functionality

Introduces a new structure for axis-aligned bounding boxes, enhancing spatial computations.

Implements various geometric transformation methods to support unbaking and processing geometry data.

Improves vector comparison and bounding box calculations for improved accuracy.

* updates Aabb structure and improves geometry processing

Changes Aabb from a struct to a record type, enabling immutability and simpler construction.

Enhances geometry processing logic to ensure valid Aabb computation, allowing for improved handling of empty geometries.

Throws exceptions for null or invalid input in instance registration, ensuring greater robustness.

* adds instancing support and geometry unbaking

Implements instancing to optimise geometry handling and enables unbaking geometry for validation of instance detection.

Enhances diagnostics reporting for instance grouping and tracking, improving clarity on geometry processing outcomes.

* optimises geometry processing and visibility checks

Enhances performance by pre-allocating list capacities to reduce resizing overhead.

Implements a single-pass filter to improve visibility checks on model items, ensuring only geometries with both visibility and geometry are processed.

Cleans up and simplifies the code by removing unnecessary debug logs.

* adds diagnostics for instance grouping behaviour

Implements a diagnostics class to analyse instance grouping efficiency and effectiveness within the application.

Provides methods for generating detailed reports and summaries, aiding in debugging grouping failures and offering recommendations for improvement.

* adds geometry cache statistics logging

Implements a logging feature for geometry cache performance statistics, providing insights into COM extraction and geometry creation times.

Updates the display value extractor to allow access to geometry statistics.

Improves diagnostic capabilities by logging additional performance metrics during the geometry conversion process.

* improves performance tracking and diagnostics in processing

Enhances the timing and diagnostics for model item retrieval, providing detailed performance metrics to identify bottlenecks.

Updates user feedback mechanisms during operations to maintain responsiveness.

Refines the management of component instances in geometry processing for better efficiency.

* addresses memory leaks COM object management in geometry processing

Improves memory management with proper release of COM objects in the geometry processing system.

Adds safety checks and optimisations within existing methods to prevent memory leaks and enhance performance.

Relates to improved instancing capabilities.

* removes deprecated settings code and cleans up logic

Eliminates the previous implementation of conversion settings, streamlining settings management.

Refines the conversion settings factory by removing unused methods and comments, optimising the overall process for better readability and maintenance.

Updates the user-related configurations to enhance clarity and usability.

* updates primitive processor documentation and comments

Clarifies COM interop bottlenecks and performance analysis.

Removes outdated optimization recommendations to improve clarity.

Adds warnings for performance hotspots affecting vertex processing.

* improves event handling and diagnostics in filtering

Refines filtering behaviour to ensure consistency across all relevant components, aiding in the correct updating of saved sets.

Enhances diagnostic logging throughout path processing, providing better insights into timing and performance.

Removes redundant comments to streamline clarity and focus on essential diagnostics.

* Refines geometry path handling in converter

Improves null handling for geometry paths to prevent potential exceptions.

Clarifies performance statistics documentation for better understanding of COM overhead.

Enhances comments for the unbaking geometry method to improve code readability.

* refactors element selection service for improved integration

Moves element selection service to a converter-specific namespace.
Updates dependency injection bindings for the element selection service.
Streamlines usage by enhancing the functionality of the inherited service while preparing for future connector-specific extensions.

* removes deprecated code and improves material handling

Eliminates unnecessary COM interop logic for hash ID generation in the unpacker.

Refactors material name creation and streamlines object addition to proxies for improved performance and clarity.

Introduces a settings manager to efficiently manage visual representation and related settings for model-specific caching.

* formatting

* fixes CI error CS9113

Replaces a local display value extractor reference with a class-level field for consistency and improved readability.

The logging is only during DEBUG session so error was hidden until CI build

* refactors element selection service integration

Replaces the existing element selection service with a new implementation to improve clarity and maintainability.

Updates service registrations and filters to use the refactored service while removing outdated functionality.

Incorporates updates to ensure consistent geometry validation checks.

* updates selection handling in geometry converter

Replaces direct model item usage with a collection for selection handling, improving memory management by adding a dispose call.

Enhances overall stability and performance of geometry conversion process.

* optimises display values aggregation logic

Refactors the method for aggregating display values from sibling bases.

Utilises LINQ to streamline the accumulation process, enhancing readability and performance.
Maintains functionality while reducing code complexity.

* adds null check for item.Model in category extractor

Ensures that the extraction process safely handles cases where item.Model is null, preventing potential runtime errors.

Improves reliability of the converter's operation.

* removes debug diagnostics for instance grouping

Eliminates extensive logging and performance measurement related to instance grouping from the codebase.

Streamlines the overall code by removing unused functionality related to diagnostics that was not leading to meaningful insights.

This improves maintainability and clarity by reducing complexity in the relevant components.

* apply Y-up to Z-up transform to instance matrices

Instanced objects from Y-up models were incorrectly positioned because
instance transforms used the raw Navisworks matrix while geometry
vertices had already been converted to Z-up in PrimitiveProcessor.

Added TransformMatrixYUpToZUp() which applies P * M * P^-1 conjugation
to transform the entire 4x4 matrix to Z-up coordinate space. Applied
to both the unbake operation and instance proxy transform when the
model is not upright.

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2026-01-15 13:42:52 +03:00
Dogukan Karatas 6dc1726536 fix (revit): webview2 lazy initialization to avoid pyRevit conflict (#1235)
* lazy init webview

* simplified init
2026-01-15 13:34:02 +03:00
Björn Steinhagen 46198934ec feat(grasshopper): enables application id mutations on passthrough components (#1236)
* feat(grasshopper): enables user application id setting

* chore: prop exposure
2026-01-14 12:10:39 +03:00
kekesidavid b4191d1d65 get host id for curtain panels and mullions (#1234)
Co-authored-by: Mucahit Bilal GOKER <51519350+bimgeek@users.noreply.github.com>
2026-01-13 07:18:01 +03:00
Björn Steinhagen f007e28565 feat(grasshopper): add CollectionsByName component with nested collection support (#1233)
* feat(grasshopper): adds easier collection creation foundation

* feat(grasshopper): adds nesting support

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2026-01-12 16:37:02 +02:00
Björn Steinhagen d05667dac8 fix(revit): curve double-transform when publishing with reference points (#1231)
* fix(revit): adds logic to not double-transform curves with reference point

* fix(revit): updates rebar logic in light of changes

* chore(docs): updates comments

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2026-01-12 15:21:12 +03:00
Dogukan Karatas c922976bcd fix (rhino): handle invalid layer names during receive (#1232)
* fix whitepaces

* comment added
2026-01-09 17:47:36 +03:00
Björn Steinhagen c3aa44dfc2 feat(grasshopper): hides application id and speckle id on filter objects component (#1230) 2026-01-08 11:18:24 +02:00
Björn Steinhagen e1a64189c8 feat(grasshopper): adds version id output to publish components 2026-01-06 12:53:11 +02:00
Björn Steinhagen b0e0669cab fix(revit): bypass plane creation for geometry beyond distance limits 2026-01-06 10:57:55 +02:00
Mucahit Bilal GOKER b2a14e055c feat(revit): add parentId param to nested elements (#1227)
* add parent id to nested elements

* chore: formatting

* change from elementId to applicationId

---------

Co-authored-by: Björn Steinhagen <steinhagen.bjoern@gmail.com>
2026-01-05 16:00:11 +03:00
Mucahit Bilal GOKER 74f4525ff2 exclude invalid categories (#1226) 2026-01-05 12:59:04 +03:00
Björn Steinhagen bb57b31ae4 fix(grasshopper): handle mixed InstanceProxy and primitive geometry in DataObject displayValue (#1225) 2025-12-24 13:00:27 +01:00
kekesidavid d33a6ca358 fix(rhino): force initialization RhinoDocumentStore (#1224)
* force initialization RhinoDocumentStore

* commeng changed
2025-12-23 11:11:07 +01:00
174 changed files with 4879 additions and 2805 deletions
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -312,7 +313,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -356,12 +357,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -312,7 +313,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -356,12 +357,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -313,7 +314,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -230,14 +230,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -262,7 +263,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -306,12 +307,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -230,14 +230,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -262,7 +263,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -306,12 +307,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -290,14 +290,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -322,7 +323,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -366,12 +367,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -290,14 +290,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -322,7 +323,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -366,12 +367,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -290,14 +290,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -322,7 +323,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -366,12 +367,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -166,8 +166,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -175,13 +175,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -239,14 +239,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -272,7 +273,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -316,12 +317,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -166,8 +166,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -175,13 +175,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -239,14 +239,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -272,7 +273,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -316,12 +317,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.etabs21": {
@@ -355,12 +356,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -230,14 +230,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -254,7 +255,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.etabs22": {
@@ -304,12 +305,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2020": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2021": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2022": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2023": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2024": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -177,8 +177,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -188,13 +188,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -287,14 +287,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -311,7 +312,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2025": {
@@ -357,12 +358,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -186,8 +186,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -197,13 +197,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -288,14 +288,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -312,7 +313,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.navisworks2026": {
@@ -359,12 +360,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -6,32 +6,22 @@ using Speckle.Sdk;
namespace Speckle.Connector.Navisworks.Bindings;
public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
public class NavisworksBasicConnectorBinding(
IBrowserBridge parent,
DocumentModelStore store,
ISpeckleApplication speckleApplication
) : IBasicConnectorBinding
{
public string Name => "baseBinding";
public IBrowserBridge Parent { get; }
public BasicConnectorBindingCommands Commands { get; }
public IBrowserBridge Parent { get; } = parent;
private readonly DocumentModelStore _store;
private readonly ISpeckleApplication _speckleApplication;
public BasicConnectorBindingCommands Commands { get; } = new(parent);
public NavisworksBasicConnectorBinding(
IBrowserBridge parent,
DocumentModelStore store,
ISpeckleApplication speckleApplication
)
{
Parent = parent;
_store = store;
_speckleApplication = speckleApplication;
Commands = new BasicConnectorBindingCommands(parent);
}
public string GetSourceApplicationName() => speckleApplication.Slug;
public string GetSourceApplicationName() => _speckleApplication.Slug;
public string GetSourceApplicationVersion() => speckleApplication.HostApplicationVersion;
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
public string GetConnectorVersion() => speckleApplication.SpeckleVersion;
public DocumentInfo? GetDocumentInfo() =>
NavisworksApp.ActiveDocument is null || NavisworksApp.ActiveDocument.Models.Count == 0
@@ -42,15 +32,15 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
NavisworksApp.ActiveDocument.GetHashCode().ToString()
);
public DocumentModelStore GetDocumentState() => _store;
public DocumentModelStore GetDocumentState() => store;
public void AddModel(ModelCard model) => _store.AddModel(model);
public void AddModel(ModelCard model) => store.AddModel(model);
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
public void UpdateModel(ModelCard model) => store.UpdateModel(model);
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public void RemoveModel(ModelCard model) => store.RemoveModel(model);
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
public void RemoveModels(List<ModelCard> models) => store.RemoveModels(models);
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
@@ -1,6 +1,6 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Converter.Navisworks.Services;
namespace Speckle.Connector.Navisworks.Bindings;
@@ -12,6 +12,7 @@ using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Converter.Navisworks.Services;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk.Common;
@@ -58,12 +59,12 @@ public class NavisworksSendBinding : ISendBinding
private static void SubscribeToNavisworksEvents() { }
// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise, we might not be able to update list of saved sets.
// WARNING: Changes to filter behavior here must match everywhere filters are used, or saved sets won't update correctly
public List<ISendFilter> GetSendFilters() =>
[
new NavisworksSelectionFilter() { IsDefault = true },
new NavisworksSavedSetsFilter(new ElementSelectionService()),
new NavisworksSavedViewsFilter(new ElementSelectionService())
new NavisworksSavedSetsFilter(new ConnectorElementSelectionService()),
new NavisworksSavedViewsFilter(new ConnectorElementSelectionService())
];
public List<ICardSetting> GetSendSettings() =>
@@ -105,6 +106,7 @@ public class NavisworksSendBinding : ISendBinding
)
{
var selectedPaths = modelCard.SendFilter.NotNull().RefreshObjectIds();
var convertHiddenElementsSetting =
modelCard.Settings!.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool? ?? false;
var message = convertHiddenElementsSetting
@@ -115,30 +117,78 @@ public class NavisworksSendBinding : ISendBinding
{
throw new SpeckleSendFilterException(message);
}
onOperationProgressed.Report(new CardProgress("Getting selection...", null));
await Task.CompletedTask;
var modelItems = new List<NAV.ModelItem>();
int estimatedCapacity = selectedPaths.Count * 10;
var modelItems = new List<NAV.ModelItem>(estimatedCapacity);
double count = 0;
foreach (var path in selectedPaths)
{
onOperationProgressed.Report(new CardProgress("Getting selection...", count / selectedPaths.Count));
await Task.CompletedTask;
var modelItem = _selectionService.GetModelItemFromPath(path);
modelItems.AddRange(_selectionService.GetGeometryNodes(modelItem).Where(_selectionService.IsVisible));
var hasChildren = modelItem.Children.Any();
if (hasChildren)
{
int nodesVisited = 0;
int hiddenBranchesPruned = 0;
const int REPORT_INTERVAL = 1000;
void TraverseWithProgress(NAV.ModelItem node)
{
nodesVisited++;
if (nodesVisited % REPORT_INTERVAL == 0)
{
onOperationProgressed.Report(
new CardProgress(
$"Expanding tree: {nodesVisited} visited, {modelItems.Count} with geometry, {hiddenBranchesPruned} hidden",
null
)
);
Task.Delay(1).Wait();
}
if (!_selectionService.IsVisible(node))
{
hiddenBranchesPruned++;
return;
}
if (node.HasGeometry)
{
modelItems.Add(node);
}
foreach (var child in node.Children)
{
TraverseWithProgress(child);
}
}
TraverseWithProgress(modelItem);
}
else
{
if (modelItem.HasGeometry && _selectionService.IsVisible(modelItem))
{
modelItems.Add(modelItem);
}
}
count++;
}
return modelItems.Count == 0 ? throw new SpeckleSendFilterException(message) : modelItems;
}
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
/// <summary>
/// Cancels all outstanding send operations for the current document.
/// This method is called when the active document changes, to ensure
/// that any in-progress send operations are properly canceled before
/// the new document is loaded.
/// </summary>
public void CancelAllSendOperations()
{
foreach (var modelCardId in _store.GetSenders().Select(m => m.ModelCardId))
@@ -15,7 +15,7 @@ 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.Constants.Registers;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk.Models.GraphTraversal;
@@ -53,9 +53,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
@@ -64,6 +61,9 @@ public static class NavisworksConnectorServiceRegistration
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
// Registers and caches
serviceCollection.AddScoped<IInstanceFragmentRegistry, InstanceFragmentRegistry>();
// Register Intercom/interop
serviceCollection.AddSingleton<NavisworksDocumentModelStore>();
serviceCollection.AddSingleton<DocumentModelStore>(sp => sp.GetRequiredService<NavisworksDocumentModelStore>());
@@ -73,6 +73,9 @@ public static class NavisworksConnectorServiceRegistration
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedViewsFilter>();
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
serviceCollection.AddScoped<
Converter.Navisworks.Services.IElementSelectionService,
ConnectorElementSelectionService
>();
}
}
@@ -1,31 +1,12 @@
using Speckle.InterfaceGenerator;
using static Speckle.Converter.Navisworks.Helpers.ElementSelectionHelper;
namespace Speckle.Connector.Navisworks.Services;
namespace Speckle.Connector.Navisworks.Services;
[GenerateAutoInterface]
public class ElementSelectionService : IElementSelectionService
/// <summary>
/// Connector-specific element selection service that extends the converter's base implementation.
/// Inherits the cached visibility checking and path resolution from the converter layer.
/// </summary>
public class ConnectorElementSelectionService : Converter.Navisworks.Services.ElementSelectionService
{
private readonly Dictionary<Guid, bool> _visibleCache = new();
public string GetModelItemPath(NAV.ModelItem modelItem) => ResolveModelItemToIndexPath(modelItem);
public NAV.ModelItem GetModelItemFromPath(string path) => ResolveIndexPathToModelItem(path);
public bool IsVisible(NAV.ModelItem modelItem)
{
var key = modelItem.InstanceGuid;
if (_visibleCache.TryGetValue(key, out var isVisible))
{
return isVisible;
}
//same as ElementSelectionHelper.IsElementVisible
foreach (var item in modelItem.AncestorsAndSelf)
{
_visibleCache[item.InstanceGuid] = !item.IsHidden;
}
return _visibleCache[key];
}
public IEnumerable<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem) => ResolveGeometryLeafNodes(modelItem);
// This inherits all functionality from the converter's ElementSelectionService
// including cached IsVisible, GetModelItemPath, GetModelItemFromPath, and GetGeometryNodes
// Connector-specific extensions can be added here if needed in the future
}
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Helpers;
using Speckle.Converter.Navisworks.Services;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk;
@@ -130,16 +130,20 @@ public class NavisworksColorUnpacker(
var comSelection = ComBridge.ToInwOpSelection([modelItem]);
try
{
var pathsCollection = comSelection.Paths();
var paths = comSelection.Paths();
try
{
foreach (ComApi.InwOaPath path in pathsCollection)
foreach (ComApi.InwOaPath path in paths)
{
var fragmentsCollection = path.Fragments();
GC.KeepAlive(path);
var fragments = path.Fragments();
try
{
foreach (ComApi.InwOaFragment3 fragment in fragmentsCollection.OfType<ComApi.InwOaFragment3>())
foreach (ComApi.InwOaFragment3 fragment in fragments)
{
GC.KeepAlive(fragment);
fragment.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, primitiveChecker);
if (primitiveChecker.HasTriangles)
@@ -150,9 +154,9 @@ public class NavisworksColorUnpacker(
}
finally
{
if (fragmentsCollection != null)
if (fragments != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(fragmentsCollection);
System.Runtime.InteropServices.Marshal.ReleaseComObject(fragments);
}
}
}
@@ -161,9 +165,9 @@ public class NavisworksColorUnpacker(
}
finally
{
if (pathsCollection != null)
if (paths != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(pathsCollection);
System.Runtime.InteropServices.Marshal.ReleaseComObject(paths);
}
}
}
@@ -120,17 +120,6 @@ public sealed class NavisworksDocumentEvents
}
}
private void UnsubscribeFromDocumentModelEvents(object _)
{
var activeDocument = NavisworksApp.ActiveDocument;
if (activeDocument != null)
{
UnsubscribeFromModelEvents(activeDocument);
}
_isSubscribed = false;
}
private void UnsubscribeFromModelEvents(NAV.Document document)
{
document.Models.CollectionChanged -= HandleDocumentModelCountChanged;
@@ -1,22 +1,18 @@
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.Services;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converter.Navisworks.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Objects.Other;
using Speckle.Sdk;
using static Speckle.Converter.Navisworks.Constants.MaterialConstants;
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>(
@@ -74,66 +70,6 @@ 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;
@@ -162,7 +98,7 @@ public class NavisworksMaterialUnpacker(
);
var materialName =
$"{MaterialConstants.DEFAULT_MATERIAL_NAME_PREFIX}{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";
$"{DEFAULT_MATERIAL_NAME_PREFIX}{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";
var itemCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Item");
if (itemCategory != null)
@@ -188,14 +124,14 @@ 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]
objects = [finalId]
};
}
}
@@ -219,9 +155,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 : $"{DEFAULT_MATERIAL_NAME_PREFIX}{Math.Abs(color.ToArgb())}",
opacity = 1 - transparency,
metalness = 0,
roughness = 1,
@@ -1,7 +1,7 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Utils;
using Speckle.Converter.Navisworks.Services;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
@@ -1,7 +1,7 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Utils;
using Speckle.Converter.Navisworks.Services;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
@@ -48,8 +48,6 @@ public class NavisworksSavedViewsFilter : DiscriminatedObject, ISendFilterSelect
return objectIds;
}
var savedViews = NavisworksApp.ActiveDocument.SavedViewpoints;
foreach (var savedViewItem in SelectedItems.Select(item => ResolveSavedView(item.Id)))
{
// Get the visible elements in the saved view.
@@ -82,12 +80,12 @@ public class NavisworksSavedViewsFilter : DiscriminatedObject, ISendFilterSelect
{
var objectIds = new List<string>();
// THIS IS COMMENTED OUT AS IT IS LEGACY DEFENSIVE BEHAVIOUR - DISCUSSION REQUIRED
// THIS IS COMMENTED OUT AS IT IS LEGACY DEFENSIVE BEHAVIOR - DISCUSSION REQUIRED
// if (!savedView.ContainsVisibilityOverrides)
// {
// // We check this again as the view settings may have changed in the saved card.
// // If the saved view does not contain visibility overrides, this is effectively everything in the model.
// // This will need to be the documented behaviour.
// // This will need to be the documented behavior.
// throw new SpeckleSendFilterException(
// "Saved view does not contain visibility overrides. This would effectively publish everything in the model."
// );
@@ -154,7 +152,7 @@ public class NavisworksSavedViewsFilter : DiscriminatedObject, ISendFilterSelect
switch (item)
{
// case NAV.SavedViewpoint { ContainsVisibilityOverrides: false }:
// Legacy defensive behaviour: skip viewpoints without visibility overrides.
// Legacy defensive behavior: skip viewpoints without visibility overrides.
// Essentially, send everything, or whatever the current view state for hidden elements is.
// break;
case NAV.SavedViewpointAnimationCut:
@@ -1,4 +1,4 @@
using Speckle.Converter.Navisworks.Constants;
using static Speckle.Converter.Navisworks.Constants.PathConstants;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
@@ -15,6 +15,6 @@ public static class SavedItemHelpers
current = current.Parent;
}
return string.Join(PathConstants.SET_SEPARATOR, pathParts);
return string.Join(SET_SEPARATOR, pathParts);
}
}
@@ -1,5 +1,5 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Constants;
using static Speckle.Converter.Navisworks.Constants.PathConstants;
namespace Speckle.Connector.Navisworks.Operations.Send;
@@ -10,29 +10,29 @@ public static class GeometryNodeMerger
{
/// <summary>
/// Groups sibling geometry nodes based on material properties for merging.
/// Only merges nodes that share the same parent and have identical material properties.
/// This only merges nodes that share the same parent and have identical material properties.
/// </summary>
/// <param name="nodes">The collection of ModelItems to process</param>
/// <returns>Dictionary mapping parent paths (with material signature suffix) to their mergeable child nodes</returns>
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes)
{
var selectionService = new ElementSelectionService();
var selectionService = new ConnectorElementSelectionService();
// Group nameless geometry nodes by parent path and material signature
var mergeableGroups = nodes
.Where(node => node.HasGeometry && string.IsNullOrEmpty(node.DisplayName)) // Only anonymous geometry nodes
.GroupBy(node =>
{
// Get parent path
// Get the parent path
var path = selectionService.GetModelItemPath(node);
var lastSeparatorIndex = path.LastIndexOf(PathConstants.SEPARATOR);
var lastSeparatorIndex = path.LastIndexOf(SEPARATOR);
var parentPath = lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
// Generate material signature
string signature = GenerateSignature(node);
// Combine parent path with signature
return $"{parentPath}{PathConstants.MATERIAL_SEPARATOR}{signature}";
return $"{parentPath}{MATERIAL_SEPARATOR}{signature}";
})
.Where(group => group.Count() > 1) // Only include groups with multiple children
.ToDictionary(group => group.Key, group => group.ToList());
@@ -95,7 +95,7 @@ public static class GeometryNodeMerger
// Build a consistent string representation of all properties
var hashInput = new System.Text.StringBuilder();
// Sort keys to ensure consistent order
// Sort keys to ensure a consistent order
var sortedKeys = properties.Keys.OrderBy(k => k).ToList();
foreach (var key in sortedKeys)
@@ -139,7 +139,7 @@ public static class GeometryNodeMerger
/// </summary>
private static string GetMaterialName(NAV.ModelItem node)
{
// Check Item category for material name
// Check the Item category for material name
var itemCategory = node.PropertyCategories.FindCategoryByDisplayName("Item");
if (itemCategory != null)
{
@@ -1,8 +1,8 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Constants;
using Speckle.Converter.Navisworks.Services;
using Speckle.Converters.Common;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using static Speckle.Converter.Navisworks.Constants.PathConstants;
namespace Speckle.Connector.Navisworks.Operations.Send;
@@ -59,8 +59,8 @@ public class NavisworksHierarchyBuilder
allPaths.Sort(
(a, b) =>
{
var depthA = a.Count(c => c == PathConstants.SEPARATOR);
var depthB = b.Count(c => c == PathConstants.SEPARATOR);
var depthA = a.Count(c => c == SEPARATOR);
var depthB = b.Count(c => c == SEPARATOR);
return depthB.CompareTo(depthA); // <- Sort in ascending order of path length
}
);
@@ -126,7 +126,7 @@ public class NavisworksHierarchyBuilder
private static string GetParentPath(string path)
{
var idx = path.LastIndexOf(PathConstants.SEPARATOR);
var idx = path.LastIndexOf(SEPARATOR);
return idx == -1 ? string.Empty : path[..idx];
}
@@ -1,6 +1,5 @@
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.HostApp;
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Conversion;
@@ -14,7 +13,10 @@ using Speckle.Sdk;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Instances;
using static Speckle.Connector.Navisworks.Operations.Send.GeometryNodeMerger;
using static Speckle.Connectors.Common.Operations.ProxyKeys;
using static Speckle.Converter.Navisworks.Constants.InstanceConstants;
namespace Speckle.Connector.Navisworks.Operations.Send;
@@ -26,14 +28,15 @@ public class NavisworksRootObjectBuilder(
ISdkActivityFactory activityFactory,
NavisworksMaterialUnpacker materialUnpacker,
NavisworksColorUnpacker colorUnpacker,
Speckle.Converter.Navisworks.Constants.Registers.IInstanceFragmentRegistry instanceRegistry,
IElementSelectionService elementSelectionService,
IUiUnitsCache uiUnitsCache,
InstanceStoreManager instanceStoreManager
IUiUnitsCache uiUnitsCache
) : IRootObjectBuilder<NAV.ModelItem>
{
#pragma warning disable CA1823
#pragma warning restore CA1823
private bool SkipNodeMerging { get; set; }
internal NavisworksConversionSettings GetCurrentSettings() => converterSettings.Current;
private bool DisableGroupingForInstanceTesting { get; set; }
public async Task<RootObjectBuilderResult> Build(
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
@@ -43,14 +46,14 @@ public class NavisworksRootObjectBuilder(
)
{
#if DEBUG
SkipNodeMerging = true;
SkipNodeMerging = false;
DisableGroupingForInstanceTesting = false;
#endif
using var activity = activityFactory.Start("Build");
ValidateInputs(navisworksModelItems, projectId, onOperationProgressed);
var rootCollection = InitializeRootCollection();
(Dictionary<string, Base?> convertedElements, List<SendConversionResult> conversionResults) =
await ConvertModelItemsAsync(navisworksModelItems, projectId, onOperationProgressed, cancellationToken);
@@ -58,30 +61,17 @@ public class NavisworksRootObjectBuilder(
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);
}
AddInstanceDefinitionsToCollection(rootCollection, ref finalElements);
int finalInstanceProxyCount = CountInstanceProxiesRecursive(finalElements);
logger.LogInformation(
"Final output contains {count} InstanceProxy objects in displayValues",
finalInstanceProxyCount
);
rootCollection.elements = finalElements;
return new RootObjectBuilderResult(rootCollection, conversionResults);
}
@@ -127,16 +117,32 @@ public class NavisworksRootObjectBuilder(
var convertedBases = new Dictionary<string, Base?>();
int processedCount = 0;
int totalCount = navisworksModelItems.Count;
int instanceProxyCount = 0;
foreach (var item in navisworksModelItems)
{
cancellationToken.ThrowIfCancellationRequested();
var converted = ConvertNavisworksItem(item, convertedBases, projectId);
results.Add(converted);
if (
converted.Status == Status.SUCCESS
&& convertedBases.TryGetValue(elementSelectionService.GetModelItemPath(item), out var convertedBase)
&& convertedBase?["displayValue"] is List<Base> displayValues
)
{
instanceProxyCount += displayValues.Count(dv => dv.GetType().Name == "InstanceProxy");
}
processedCount++;
onOperationProgressed.Report(new CardProgress("Converting", (double)processedCount / totalCount));
}
logger.LogInformation(
"Converted {total} items, found {instanceProxies} InstanceProxy objects",
totalCount,
instanceProxyCount
);
return Task.FromResult((convertedBases, results));
}
@@ -155,10 +161,24 @@ public class NavisworksRootObjectBuilder(
{
var finalElements = new List<Base>();
var processedPaths = new HashSet<string>();
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
if (!DisableGroupingForInstanceTesting)
{
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
logger.LogInformation(
"After grouping: {grouped} paths processed, {elements} elements in collection",
processedPaths.Count,
finalElements.Count
);
}
else
{
logger.LogInformation("Grouping disabled for instance testing");
}
if (converterSettings.Current.User.PreserveModelHierarchy)
{
logger.LogInformation("Building hierarchy (PreserveModelHierarchy=true)");
var hierarchyBuilder = new NavisworksHierarchyBuilder(
convertedBases,
rootToSpeckleConverter,
@@ -168,7 +188,10 @@ public class NavisworksRootObjectBuilder(
return hierarchyBuilder.BuildHierarchy();
}
logger.LogInformation("Adding remaining elements (flat mode)");
AddRemainingElements(finalElements, convertedBases, processedPaths);
logger.LogInformation("Final elements count: {count}", finalElements.Count);
return finalElements;
}
@@ -181,7 +204,7 @@ public class NavisworksRootObjectBuilder(
{
foreach (var group in groupedNodes)
{
var siblingBases = new List<Base>();
var siblingBases = new List<Base>(group.Value.Count);
foreach (var itemPath in group.Value.Select(elementSelectionService.GetModelItemPath))
{
processedPaths.Add(itemPath);
@@ -236,10 +259,29 @@ public class NavisworksRootObjectBuilder(
string cleanParentPath = ElementSelectionHelper.GetCleanPath(groupKey);
(string name, string path) = GetElementNameAndPath(cleanParentPath);
int estimatedCapacity = siblingBases.Sum(b => (b["displayValue"] as List<Base>)?.Count ?? 0);
var displayValues = new List<Base>(estimatedCapacity);
displayValues.AddRange(
siblingBases
.Where(sibling => sibling["displayValue"] is List<Base>)
.SelectMany(sibling => (List<Base>)sibling["displayValue"]!)
);
var instanceProxyCount = displayValues.Count(dv => dv.GetType().Name == "InstanceProxy");
if (instanceProxyCount > 0)
{
logger.LogDebug(
"Group {groupKey} merging {siblings} siblings with {proxies} InstanceProxy objects",
groupKey,
siblingBases.Count,
instanceProxyCount
);
}
return new NavisworksObject
{
name = name,
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
displayValue = displayValues,
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
units = converterSettings.Current.Derived.SpeckleUnits,
applicationId = groupKey,
@@ -280,25 +322,100 @@ public class NavisworksRootObjectBuilder(
var renderMaterials = materialUnpacker.UnpackRenderMaterial(navisworksModelItems, groupedNodes);
if (renderMaterials.Count > 0)
{
rootCollection[ProxyKeys.RENDER_MATERIAL] = renderMaterials;
rootCollection[RENDER_MATERIAL] = renderMaterials;
}
var colors = colorUnpacker.UnpackColor(navisworksModelItems, groupedNodes);
if (colors.Count > 0)
{
rootCollection[ProxyKeys.COLOR] = colors;
}
var instanceDefinitionProxies = instanceStoreManager.GetInstanceDefinitionProxies();
if (instanceDefinitionProxies.Count > 0)
{
rootCollection[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies.ToList();
rootCollection[COLOR] = colors;
}
return Task.CompletedTask;
}
private void AddInstanceDefinitionsToCollection(Collection rootCollection, ref List<Base> finalElements)
{
using var _ = activityFactory.Start("BuildInstanceDefinitions");
// Get all definition geometries from the registry
var allDefinitions = instanceRegistry.GetAllDefinitionGeometries();
if (allDefinitions.Count == 0)
{
logger.LogInformation("No instance definitions found - instancing may be disabled");
return;
}
logger.LogInformation("Building instance structure for {count} definition groups", allDefinitions.Count);
if (allDefinitions.Count > 100)
{
logger.LogWarning(
"Large number of definition groups ({count}) detected - this may indicate instance grouping is not working effectively",
allDefinitions.Count
);
}
var instanceDefinitionProxies = new List<InstanceDefinitionProxy>(allDefinitions.Count);
int estimatedGeometryCount = allDefinitions.Sum(kvp => kvp.Value.Count);
var allDefinitionGeometries = new List<Base>(estimatedGeometryCount);
foreach (var kvp in allDefinitions)
{
var groupKey = kvp.Key;
var geometries = kvp.Value;
var groupKeyHash = groupKey.ToHashString();
var defProxy = new InstanceDefinitionProxy
{
name = $"Shared Geometry {groupKeyHash}",
objects = geometries.Select(g => g.applicationId ?? "").Where(id => !string.IsNullOrEmpty(id)).ToList(),
applicationId = $"{DEFINITION_ID_PREFIX}{groupKeyHash}",
maxDepth = 0
};
instanceDefinitionProxies.Add(defProxy);
allDefinitionGeometries.AddRange(geometries);
}
rootCollection[INSTANCE_DEFINITION] = instanceDefinitionProxies;
var geometryDefinitionsCollection = new Collection
{
name = "Geometry Definitions",
elements = allDefinitionGeometries
};
var objectCollection = new Collection { name = "", elements = finalElements };
finalElements = [geometryDefinitionsCollection, objectCollection];
logger.LogInformation(
"Added {proxyCount} instance definition proxies and {geomCount} definition geometries",
instanceDefinitionProxies.Count,
allDefinitionGeometries.Count
);
}
private int CountInstanceProxiesRecursive(List<Base> elements)
{
int count = 0;
foreach (var element in elements)
{
if (element["displayValue"] is List<Base> displayValues)
{
count += displayValues.Count(dv => dv.GetType().Name == "InstanceProxy");
}
if (element is Collection { elements: not null } collection)
{
count += CountInstanceProxiesRecursive(collection.elements);
}
}
return count;
}
private SendConversionResult ConvertNavisworksItem(
NAV.ModelItem navisworksItem,
Dictionary<string, Base?> convertedBases,
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converter.Navisworks.Settings;
using Speckle.InterfaceGenerator;
@@ -8,158 +7,106 @@ using Speckle.Sdk.Common;
namespace Speckle.Connector.Navisworks.Operations.Send.Settings;
[GenerateAutoInterface]
public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavisworks
public class ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
: IToSpeckleSettingsManagerNavisworks
{
private readonly ISendConversionCache _sendConversionCache;
// cache invalidation process run with ModelCardId since the settings are model specific
// cache invalidation process run with ModelCardId since the settings are model-specific
private readonly Dictionary<string, RepresentationMode> _visualRepresentationCache = [];
private readonly Dictionary<string, OriginMode> _originModeCache = [];
private readonly Dictionary<string, bool?> _convertHiddenElementsCache = [];
private readonly Dictionary<string, bool?> _includeInternalPropertiesCache = [];
private readonly Dictionary<string, bool?> _preserveModelHierarchyCache = [];
private readonly Dictionary<string, bool?> _revitCategoryMappingCache = [];
private readonly Dictionary<string, bool> _convertHiddenElementsCache = [];
private readonly Dictionary<string, bool> _includeInternalPropertiesCache = [];
private readonly Dictionary<string, bool> _preserveModelHierarchyCache = [];
private readonly Dictionary<string, bool> _revitCategoryMappingCache = [];
public ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
{
_sendConversionCache = sendConversionCache;
}
public RepresentationMode GetVisualRepresentationMode(SenderModelCard modelCard)
/// <summary>
/// Generic helper to get a setting value with caching and cache invalidation.
/// </summary>
private T GetCachedSetting<T>(
SenderModelCard modelCard,
string settingId,
Dictionary<string, T> cache,
Func<object?, T> valueExtractor,
T defaultValue
)
{
if (modelCard == null)
{
throw new ArgumentNullException(nameof(modelCard));
}
var representationString = modelCard.Settings?.First(s => s.Id == "visualRepresentation").Value as string;
var settingValue = modelCard.Settings?.FirstOrDefault(s => s.Id == settingId)?.Value;
var returnValue = settingValue != null ? valueExtractor(settingValue) : defaultValue;
if (
representationString is not null
&& VisualRepresentationSetting.VisualRepresentationMap.TryGetValue(
representationString,
out RepresentationMode representation
)
cache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue)
&& !EqualityComparer<T>.Default.Equals(previousValue, returnValue)
)
{
if (_visualRepresentationCache.TryGetValue(modelCard.ModelCardId.NotNull(), out RepresentationMode previousType))
{
if (previousType != representation)
{
EvictCacheForModelCard(modelCard);
}
}
_visualRepresentationCache[modelCard.ModelCardId.NotNull()] = representation;
return representation;
}
throw new ArgumentException($"Invalid visual representation value: {representationString}");
}
public OriginMode GetOriginMode(SenderModelCard modelCard)
{
if (modelCard == null)
{
throw new ArgumentNullException(nameof(modelCard));
}
var originString = modelCard.Settings?.FirstOrDefault(s => s.Id == "originMode")?.Value as string;
if (!OriginModeSetting.OriginModeMap.TryGetValue(originString ?? string.Empty, out var origin))
{
return OriginMode.ModelOrigin; // Default to ModelOrigin if not specified or invalid
}
if (_originModeCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousType) && previousType != origin)
{
EvictCacheForModelCard(modelCard);
}
_originModeCache[modelCard.ModelCardId.NotNull()] = origin;
return origin;
}
public bool GetMappingToRevitCategories(SenderModelCard modelCard)
{
if (modelCard == null)
{
throw new ArgumentNullException(nameof(modelCard));
}
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "mappingToRevitCategories")?.Value as bool?;
var returnValue = value != null && value.NotNull();
if (_revitCategoryMappingCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
{
if (previousValue != returnValue)
{
EvictCacheForModelCard(modelCard);
}
}
_revitCategoryMappingCache[modelCard.ModelCardId] = returnValue;
cache[modelCard.ModelCardId.NotNull()] = returnValue;
return returnValue;
}
public bool GetConvertHiddenElements(SenderModelCard modelCard)
{
if (modelCard == null)
{
throw new ArgumentNullException(nameof(modelCard));
}
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool?;
var returnValue = value != null && value.NotNull();
if (_convertHiddenElementsCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
{
if (previousValue != returnValue)
public RepresentationMode GetVisualRepresentationMode(SenderModelCard modelCard) =>
GetCachedSetting(
modelCard,
"visualRepresentation",
_visualRepresentationCache,
value =>
{
EvictCacheForModelCard(modelCard);
}
}
var representationString = value as string;
return
representationString is not null
&& VisualRepresentationSetting.VisualRepresentationMap.TryGetValue(
representationString,
out RepresentationMode representation
)
? representation
: throw new ArgumentException($"Invalid visual representation value: {representationString}");
},
RepresentationMode.Active // default value if setting not found
);
_convertHiddenElementsCache[modelCard.ModelCardId] = returnValue;
return returnValue;
}
public bool GetIncludeInternalProperties([NotNull] SenderModelCard modelCard)
{
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "includeInternalProperties")?.Value as bool?;
var returnValue = value != null && value.NotNull();
if (_includeInternalPropertiesCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
{
if (previousValue != returnValue)
public OriginMode GetOriginMode(SenderModelCard modelCard) =>
GetCachedSetting(
modelCard,
"originMode",
_originModeCache,
value =>
{
EvictCacheForModelCard(modelCard);
}
}
var originString = value as string;
if (OriginModeSetting.OriginModeMap.TryGetValue(originString ?? string.Empty, out var origin))
{
return origin;
}
return OriginMode.ModelOrigin;
},
OriginMode.ModelOrigin
);
_includeInternalPropertiesCache[modelCard.ModelCardId] = returnValue;
return returnValue;
}
public bool GetMappingToRevitCategories(SenderModelCard modelCard) =>
GetCachedSetting(modelCard, "mappingToRevitCategories", _revitCategoryMappingCache, value => value is true, false);
public bool GetPreserveModelHierarchy([NotNull] SenderModelCard modelCard)
{
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "preserveModelHierarchy")?.Value as bool?;
public bool GetConvertHiddenElements(SenderModelCard modelCard) =>
GetCachedSetting(modelCard, "convertHiddenElements", _convertHiddenElementsCache, value => value is true, false);
var returnValue = value != null && value.NotNull();
if (_preserveModelHierarchyCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
{
if (previousValue != returnValue)
{
EvictCacheForModelCard(modelCard);
}
}
public bool GetIncludeInternalProperties(SenderModelCard modelCard) =>
GetCachedSetting(
modelCard,
"includeInternalProperties",
_includeInternalPropertiesCache,
value => value is true,
false
);
_preserveModelHierarchyCache[modelCard.ModelCardId] = returnValue;
return returnValue;
}
public bool GetPreserveModelHierarchy(SenderModelCard modelCard) =>
GetCachedSetting(modelCard, "preserveModelHierarchy", _preserveModelHierarchyCache, value => value is true, false);
private void EvictCacheForModelCard(SenderModelCard modelCard)
{
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
_sendConversionCache.EvictObjects(objectIds);
sendConversionCache.EvictObjects(objectIds);
}
}
@@ -14,7 +14,7 @@ public static class SpeckleV3Tool
public const string RIBBON_STRINGS = "NavisworksRibbon.name";
public const string PLUGIN_SUFFIX = ".Speckle";
public static Speckle.Sdk.Application App =>
public static Sdk.Application App =>
#if NAVIS
HostApplications.Navisworks;
#else
@@ -193,8 +193,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -204,13 +204,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -303,14 +303,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -326,7 +327,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.revit2022": {
@@ -371,11 +372,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"Speckle.Revit.API": {
@@ -383,6 +384,12 @@
"requested": "[2023.0.0, )",
"resolved": "2022.0.2.1",
"contentHash": "IrLN4WyI2ix+g3zCpo7sX8zNB3FrtrdQ3E2RpceGVPNG00v8OfD+Kei7o1bn1u/ML46iBYRAr/JcsLbwfUQsBw=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -193,8 +193,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -204,13 +204,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -303,14 +303,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -326,7 +327,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.revit2023": {
@@ -371,11 +372,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"Speckle.Revit.API": {
@@ -383,6 +384,12 @@
"requested": "[2023.0.0, )",
"resolved": "2023.0.0",
"contentHash": "tq40eD7psgTbV+epNouYyqfo6+hEi7FmXZqcxEOsAV7zfYyWhL6Rt3vmojkWGNuerGbH6oRI6KIIxrnlCNb8Hw=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -193,8 +193,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -204,13 +204,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -303,14 +303,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -326,7 +327,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.revit2024": {
@@ -371,11 +372,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"Speckle.Revit.API": {
@@ -383,6 +384,12 @@
"requested": "[2023.0.0, )",
"resolved": "2024.0.0",
"contentHash": "a4dsvZ00ocvzTgCD6dUdydf0jIZDVcDhs6dUX9cv+y3aTDbU8rmzhYXWt8sThedIG+IPSVa0vHmAH9pKiJL3SQ=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -173,8 +173,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -246,14 +246,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -269,7 +270,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.revit2025": {
@@ -314,11 +315,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"Speckle.Revit.API": {
@@ -326,6 +327,12 @@
"requested": "[2023.0.0, )",
"resolved": "2025.0.0",
"contentHash": "Hwf/3Ydc7KxvjgD9pSZKLSJRsFTsxYg95YyTm6f43hcsGjmk49GsLFQt921Z9OcvUVewOggQHcmBgti+P2EPHw=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -3,17 +3,15 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:dui="clr-namespace:Speckle.Connectors.DUI;assembly=Speckle.Connectors.DUI"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<wv2:CoreWebView2CreationProperties x:Key="EvergreenWebView2CreationProperties" UserDataFolder="C:\temp" />
</UserControl.Resources>
<DockPanel>
<wv2:WebView2
CreationProperties="{StaticResource EvergreenWebView2CreationProperties}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Name="Browser" Grid.Row="0" Source="{x:Static dui:Url.Netlify}" />
</DockPanel>
<!-- WebView2 is created lazily -->
<Border Name="BrowserContainer" Background="White">
<TextBlock Name="LoadingText"
Text="Loading Speckle..."
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="14"
Foreground="Gray" />
</Border>
</UserControl>
@@ -2,6 +2,8 @@ using System.Windows.Controls;
using System.Windows.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using Speckle.Connectors.DUI;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.Revit.Plugin;
@@ -12,6 +14,10 @@ public sealed partial class RevitControlWebView : UserControl, IBrowserScriptExe
{
private readonly IServiceProvider _serviceProvider;
private readonly IRevitTask _revitTask;
#pragma warning disable CA2213
private WebView2? _browser;
#pragma warning restore CA2213
private bool _isInitializing;
public RevitControlWebView(IServiceProvider serviceProvider, IRevitTask revitTask)
{
@@ -19,35 +25,61 @@ public sealed partial class RevitControlWebView : UserControl, IBrowserScriptExe
_revitTask = revitTask;
InitializeComponent();
Browser.CoreWebView2InitializationCompleted += (sender, args) =>
// Delay WebView2 creation until the panel is actually visible
// This avoids conflicts with other plugins (like pyRevit) during startup
IsVisibleChanged += OnIsVisibleChanged;
}
private void OnIsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is true && _browser == null && !_isInitializing)
{
_isInitializing = true;
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, CreateWebView2);
}
}
private void CreateWebView2()
{
_browser = new WebView2
{
CreationProperties = new CoreWebView2CreationProperties { UserDataFolder = "C:\\temp" },
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
Source = Url.Netlify
};
_browser.CoreWebView2InitializationCompleted += (sender, args) =>
_serviceProvider
.GetRequiredService<ITopLevelExceptionHandler>()
.CatchUnhandled(() => OnInitialized(sender, args));
BrowserContainer.Child = _browser;
}
public bool IsBrowserInitialized => Browser.IsInitialized;
public bool IsBrowserInitialized => _browser?.IsInitialized ?? false;
public object BrowserElement => Browser;
public object BrowserElement => _browser!;
public void ExecuteScript(string script)
{
if (!Browser.IsInitialized)
if (_browser == null || !_browser.IsInitialized)
{
throw new InvalidOperationException("Failed to execute script, Webview2 is not initialized yet.");
}
_revitTask.Run(() => Browser.ExecuteScriptAsync(script));
_revitTask.Run(() => _browser.ExecuteScriptAsync(script));
}
public void SendProgress(string script)
{
if (!Browser.IsInitialized)
if (_browser == null || !_browser.IsInitialized)
{
throw new InvalidOperationException("Failed to execute script, Webview2 is not initialized yet.");
}
//always invoke even on the main thread because it's better somehow
Browser.Dispatcher.Invoke(
_browser.Dispatcher.Invoke(
//fire and forget
() => Browser.ExecuteScriptAsync(script),
() => _browser.ExecuteScriptAsync(script),
DispatcherPriority.Background
);
}
@@ -74,11 +106,18 @@ public sealed partial class RevitControlWebView : UserControl, IBrowserScriptExe
private void SetupBinding(IBinding binding)
{
binding.Parent.AssociateWithBinding(binding);
Browser.CoreWebView2.AddHostObjectToScript(binding.Name, binding.Parent);
_browser!.CoreWebView2.AddHostObjectToScript(binding.Name, binding.Parent);
}
public void ShowDevTools() => Browser.CoreWebView2.OpenDevToolsWindow();
public void ShowDevTools() => _browser?.CoreWebView2?.OpenDevToolsWindow();
//https://github.com/MicrosoftEdge/WebView2Feedback/issues/2161
public void Dispose() => Browser.Dispatcher.Invoke(() => Browser.Dispose(), DispatcherPriority.Send);
public void Dispose()
{
if (_browser != null)
{
_browser.Dispatcher.Invoke(() => _browser.Dispose(), DispatcherPriority.Send);
_browser = null;
}
}
}
@@ -166,8 +166,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -175,13 +175,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -239,14 +239,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -262,7 +263,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.revit2026": {
@@ -298,11 +299,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"Speckle.Revit.API": {
@@ -310,6 +311,12 @@
"requested": "[2023.0.0, )",
"resolved": "2026.0.0",
"contentHash": "SiqqKbF1pXyZWXZhAl2JhjYhTt7RiYO5JaQrAjq+OlleAjT4zatwAp/DnTwQspFbP7UZr3b2Ed2kuWNN0ZFelw=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -42,6 +42,17 @@ public partial class CefSharpPanel : Page, Autodesk.Revit.UI.IDockablePaneProvid
}
}
public Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken)
{
Browser.Dispatcher.Invoke(
() => Browser.ExecuteScriptAsync(script),
DispatcherPriority.Background,
cancellationToken
);
return Task.CompletedTask;
}
public void SendProgress(string script) => ExecuteScript(script);
public bool IsBrowserInitialized => Browser.IsBrowserInitialized;
@@ -24,7 +24,7 @@ namespace Speckle.Connectors.Revit.Bindings;
internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
{
private readonly IAppIdleManager _idleManager;
private readonly RevitIdleManager _revitIdleManager;
private readonly RevitContext _revitContext;
private readonly DocumentModelStore _store;
private readonly ICancellationManager _cancellationManager;
@@ -38,6 +38,9 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
private readonly LinkedModelHandler _linkedModelHandler;
private readonly IThreadContext _threadContext;
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
private bool _isDocChangedSubscribed;
private EventHandler<Autodesk.Revit.DB.Events.DocumentChangedEventArgs>? _documentChangedHandler;
private readonly ConnectorConfig _config;
/// <summary>
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
@@ -48,7 +51,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
private ConcurrentHashSet<ElementId> ChangedObjectIds { get; set; } = new();
public RevitSendBinding(
IAppIdleManager idleManager,
RevitIdleManager revitIdleManager,
RevitContext revitContext,
DocumentModelStore store,
ICancellationManager cancellationManager,
@@ -62,11 +65,12 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
LinkedModelHandler linkedModelHandler,
IThreadContext threadContext,
IRevitTask revitTask,
ISendOperationManagerFactory sendOperationManagerFactory
ISendOperationManagerFactory sendOperationManagerFactory,
IConfigStore configStore
)
: base("sendBinding", bridge)
{
_idleManager = idleManager;
_revitIdleManager = revitIdleManager;
_revitContext = revitContext;
_store = store;
_cancellationManager = cancellationManager;
@@ -79,6 +83,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
_linkedModelHandler = linkedModelHandler;
_threadContext = threadContext;
_sendOperationManagerFactory = sendOperationManagerFactory;
_config = configStore.GetConnectorConfig();
Commands = new SendBindingUICommands(bridge);
// TODO expiry events
@@ -86,12 +91,58 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
revitTask.Run(() =>
{
revitContext.UIApplication.NotNull().Application.DocumentChanged += (_, e) =>
_topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
// revitContext.UIApplication.NotNull().Application.DocumentChanged += (_, e) =>
// _topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
_documentChangedHandler = (_, e) => _topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
_store.ModelCardsChanged += (_, e) => OnModelCardsChanged(e);
_store.DocumentChanged += (_, _) => topLevelExceptionHandler.FireAndForget(async () => await OnDocumentChanged());
});
}
private void OnModelCardsChanged(ModelCardsChangedEventArgs e)
{
if (
!_config.DocumentChangeListeningDisabled
&& e.ModelCards.Count > 0
&& e.ModelCards.Any(m => m.TypeDiscriminator == nameof(SenderModelCard))
)
{
SubscribeDocChanged();
}
else
{
UnsubscribeDocChanged();
}
}
private void SubscribeDocChanged()
{
if (_documentChangedHandler == null || _isDocChangedSubscribed)
{
return;
}
_threadContext.RunOnMain(() =>
{
_revitContext.UIApplication.NotNull().Application.DocumentChanged += _documentChangedHandler;
});
_isDocChangedSubscribed = true;
}
private void UnsubscribeDocChanged()
{
if (_documentChangedHandler == null || !_isDocChangedSubscribed)
{
return;
}
_threadContext.RunOnMain(() =>
{
_revitContext.UIApplication.NotNull().Application.DocumentChanged -= _documentChangedHandler;
});
_isDocChangedSubscribed = false;
}
public List<ISendFilter> GetSendFilters() =>
[
new RevitSelectionFilter { IsDefault = true },
@@ -276,7 +327,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
if (addedElementIds.Count > 0)
{
_idleManager.SubscribeToIdle(nameof(PostSetObjectIds), PostSetObjectIds);
_revitIdleManager.SubscribeToIdle(nameof(PostSetObjectIds), PostSetObjectIds);
}
if (HaveUnitsChanged(doc))
@@ -296,8 +347,8 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
_sendConversionCache.EvictObjects(unpackedObjectIds);
}
_idleManager.SubscribeToIdle(nameof(CheckFilterExpiration), CheckFilterExpiration);
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
_revitIdleManager.SubscribeToIdle(nameof(CheckFilterExpiration), CheckFilterExpiration);
_revitIdleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
}
// Keeps track of doc and current units
@@ -1,5 +1,6 @@
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Settings;
using Speckle.Connectors.Revit.Plugin;
using Speckle.Converters.RevitShared.Helpers;
using Speckle.Sdk.Common;
@@ -17,27 +18,32 @@ internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, ID
public SelectionBinding(
RevitContext revitContext,
IBrowserBridge parent,
IAppIdleManager idleManager,
RevitIdleManager idleManager,
#if REVIT2022
ITopLevelExceptionHandler topLevelExceptionHandler,
IRevitTask revitTask
#endif
IRevitTask revitTask,
IConfigStore configStore
)
: base("selectionBinding", parent)
{
_revitContext = revitContext;
if (!configStore.GetConnectorConfig().SelectionChangeListeningDisabled)
{
#if REVIT2022
// NOTE: getting the selection data should be a fast function all, even for '000s of elements - and having a timer hitting it every 1s is ok.
_selectionTimer = new System.Timers.Timer(1000);
_selectionTimer.Elapsed += (_, _) => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged);
_selectionTimer.Start();
// NOTE: getting the selection data should be a fast function all, even for '000s of elements - and having a timer hitting it every 1s is ok.
_selectionTimer = new System.Timers.Timer(1000);
_selectionTimer.Elapsed += (_, _) => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged);
_selectionTimer.Start();
#else
revitTask.Run(
() =>
_revitContext.UIApplication.NotNull().SelectionChanged += (_, _) =>
idleManager.SubscribeToIdle(nameof(OnSelectionChanged), OnSelectionChanged)
);
revitTask.Run(
() =>
_revitContext.UIApplication.NotNull().SelectionChanged += (_, _) =>
idleManager.SubscribeToIdle(nameof(OnSelectionChanged), OnSelectionChanged)
);
#endif
}
}
private void OnSelectionChanged()
@@ -48,11 +48,12 @@ public static class ServiceRegistration
serviceCollection.AddSingleton<IBinding, SelectionBinding>();
serviceCollection.AddSingleton<IBinding, RevitSendBinding>();
serviceCollection.AddSingleton<IBinding, RevitReceiveBinding>();
serviceCollection.AddSingleton<RevitIdleManager>();
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBindingRevit>();
serviceCollection.AddSingleton<IAppIdleManager, RevitIdleManager>();
// serviceCollection.AddSingleton<IAppIdleManager, RevitIdleManager>();
// send operation and dependencies
serviceCollection.AddScoped<SendOperation<DocumentToConvert>>();
@@ -17,13 +17,16 @@ namespace Speckle.Connectors.Revit.HostApp;
internal sealed class RevitDocumentStore : DocumentModelStore
{
private readonly ILogger<RevitDocumentStore> _logger;
private readonly IAppIdleManager _idleManager;
//private readonly IAppIdleManager _idleManager;
private readonly RevitIdleManager _idleManager;
private readonly RevitContext _revitContext;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly ISqLiteJsonCacheManager _jsonCacheManager;
public RevitDocumentStore(
IAppIdleManager idleManager,
//IAppIdleManager idleManager,
RevitIdleManager idleManager,
RevitContext revitContext,
IJsonSerializer jsonSerializer,
ITopLevelExceptionHandler topLevelExceptionHandler,
@@ -34,6 +37,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
: base(logger, jsonSerializer)
{
_jsonCacheManager = jsonCacheManagerFactory.CreateForUser("ConnectorsFileData");
//_idleManager = idleManager;
_idleManager = idleManager;
_revitContext = revitContext;
_topLevelExceptionHandler = topLevelExceptionHandler;
@@ -5,7 +5,6 @@ using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Settings;
using Speckle.Objects.Other;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Extensions;
using Speckle.Sdk.Models.GraphTraversal;
@@ -32,6 +31,24 @@ public class RevitMaterialBaker
_converterSettings = converterSettings;
}
private ElementId? FindExistingMaterialByName(string? materialName)
{
if (string.IsNullOrWhiteSpace(materialName))
{
return null;
}
string sanitizedName = _revitUtils.RemoveInvalidChars(materialName!);
using var collector = new FilteredElementCollector(_converterSettings.Current.Document);
var existingMaterial = collector
.OfClass(typeof(Material))
.Cast<Material>()
.FirstOrDefault(m => string.Equals(m.Name, sanitizedName, StringComparison.OrdinalIgnoreCase));
return existingMaterial?.Id;
}
/// <summary>
/// Checks the every atomic object has render material or not, if not it tries to find it from its layer tree and mutates
/// its render material proxy objects list with the traversal current. It will also map displayable objects' display values to their
@@ -106,11 +123,9 @@ public class RevitMaterialBaker
/// Will bake render materials in the revit document.
/// </summary>
/// <param name="speckleRenderMaterialProxies"></param>
/// <param name="baseLayerName"></param>
/// <returns></returns>
public Dictionary<string, ElementId> BakeMaterials(
IReadOnlyCollection<RenderMaterialProxy> speckleRenderMaterialProxies,
string baseLayerName
IReadOnlyCollection<RenderMaterialProxy> speckleRenderMaterialProxies
)
{
Dictionary<string, ElementId> objectIdAndMaterialIndexMap = new();
@@ -120,27 +135,42 @@ public class RevitMaterialBaker
try
{
// all values assumed to be on the 0 - 1 scale need to pass through this validation and logging (if assumption wrong)
double roughness = ClampToUnitRange(speckleRenderMaterial.roughness, "roughness", speckleRenderMaterial.name);
double opacity = ClampToUnitRange(speckleRenderMaterial.opacity, "opacity", speckleRenderMaterial.name);
double metalness = ClampToUnitRange(speckleRenderMaterial.metalness, "metalness", speckleRenderMaterial.name);
// first try to match existing material by name
ElementId? existingMaterialId = FindExistingMaterialByName(speckleRenderMaterial.name);
var diffuse = System.Drawing.Color.FromArgb(speckleRenderMaterial.diffuse);
double transparency = 1 - opacity;
double smoothness = 1 - roughness;
string materialId = speckleRenderMaterial.applicationId ?? speckleRenderMaterial.id.NotNull();
string matName = _revitUtils.RemoveInvalidChars($"{speckleRenderMaterial.name}-({materialId})-{baseLayerName}");
ElementId materialIdToUse;
var newMaterialId = Material.Create(_converterSettings.Current.Document, matName);
var revitMaterial = (Material)_converterSettings.Current.Document.GetElement(newMaterialId);
revitMaterial.Color = new Color(diffuse.R, diffuse.G, diffuse.B);
revitMaterial.Transparency = (int)(transparency * 100);
revitMaterial.Shininess = (int)(metalness * 128);
revitMaterial.Smoothness = (int)(smoothness * 128);
if (existingMaterialId != null)
{
// Use existing material
materialIdToUse = existingMaterialId;
}
else
{
// create new material
// all values assumed to be on the 0 - 1 scale need to pass through this validation and logging (if assumption wrong)
double roughness = ClampToUnitRange(speckleRenderMaterial.roughness, "roughness", speckleRenderMaterial.name);
double opacity = ClampToUnitRange(speckleRenderMaterial.opacity, "opacity", speckleRenderMaterial.name);
double metalness = ClampToUnitRange(speckleRenderMaterial.metalness, "metalness", speckleRenderMaterial.name);
var diffuse = System.Drawing.Color.FromArgb(speckleRenderMaterial.diffuse);
double transparency = 1 - opacity;
double smoothness = 1 - roughness;
string matName = _revitUtils.RemoveInvalidChars($"{speckleRenderMaterial.name}");
var newMaterialId = Material.Create(_converterSettings.Current.Document, matName);
var revitMaterial = (Material)_converterSettings.Current.Document.GetElement(newMaterialId);
revitMaterial.Color = new Color(diffuse.R, diffuse.G, diffuse.B);
revitMaterial.Transparency = (int)(transparency * 100);
revitMaterial.Shininess = (int)(metalness * 128);
revitMaterial.Smoothness = (int)(smoothness * 100);
materialIdToUse = revitMaterial.Id;
}
foreach (var objectId in proxy.objects)
{
objectIdAndMaterialIndexMap[objectId] = revitMaterial.Id;
objectIdAndMaterialIndexMap[objectId] = materialIdToUse;
}
}
catch (Exception ex) when (!ex.IsFatal())
@@ -21,6 +21,7 @@ using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Instances;
using Transform = Speckle.Objects.Other.Transform;
namespace Speckle.Connectors.Revit.Operations.Receive;
@@ -38,12 +39,15 @@ public sealed class RevitHostObjectBuilder(
IThreadContext threadContext,
RevitToHostCacheSingleton revitToHostCacheSingleton,
ITypedConverter<
(Base atomicObject, IReadOnlyCollection<Matrix4x4> matrix),
(Base atomicObject, IReadOnlyCollection<Matrix4x4> matrix, DataObject? parentDataObject),
DirectShape
> localToGlobalDirectShapeConverter,
IReceiveConversionHandler conversionHandler
) : IHostObjectBuilder, IDisposable
{
// Maps atomic object applicationId -> parent DataObject
private readonly Dictionary<string, DataObject> _atomicObjectToParentDataObject = new();
public Task<HostObjectBuilderResult> Build(
Base rootObject,
string projectName,
@@ -102,6 +106,9 @@ public sealed class RevitHostObjectBuilder(
unpackedRoot.ObjectsToConvert.ToList()
);
// Register DataObjects with InstanceProxy displayValues
RegisterDataObjectsWithInstanceProxies(unpackedRoot);
// NOTE: below is 💩... https://github.com/specklesystems/speckle-sharp-connectors/pull/813 broke sketchup to revit workflow
// ids were modified to fix receiving instances [CNX-1707](https://linear.app/speckle/issue/CNX-1707/revit-curves-and-meshes-in-blocks-come-as-duplicated)
// but we then broke sketchup to revit because applicationIds in proxies didn't match modified application ids which cam from #813 hack
@@ -176,12 +183,15 @@ public sealed class RevitHostObjectBuilder(
}
}
// Update DataObject lookup IDs
UpdateAtomicObjectLookupWithModifiedIds(originalToModifiedIds);
// 2 - Bake materials (now with the updated IDs)
if (unpackedRoot.RenderMaterialProxies != null)
{
transactionManager.StartTransaction(true, "Baking materials");
materialBaker.MapLayersRenderMaterials(unpackedRoot);
var map = materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseGroupName);
var map = materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies);
foreach (var kvp in map)
{
revitToHostCacheSingleton.MaterialsByObjectId.Add(kvp.Key, kvp.Value);
@@ -234,6 +244,87 @@ public sealed class RevitHostObjectBuilder(
return conversionResults.builderResult;
}
/// <summary>
/// Registers DataObjects that have InstanceProxy displayValues and builds the lookup.
/// </summary>
private void RegisterDataObjectsWithInstanceProxies(RootObjectUnpackerResult unpackedRoot)
{
var definitionToDataObject = new Dictionary<string, DataObject>();
foreach (var tc in unpackedRoot.ObjectsToConvert)
{
if (tc.Current is DataObject dataObject)
{
var instanceProxies = dataObject.displayValue.OfType<InstanceProxy>().ToList();
if (instanceProxies.Count > 0)
{
foreach (var ip in instanceProxies)
{
definitionToDataObject[ip.definitionId] = dataObject;
}
}
}
}
// Build lookup: definition object applicationId -> parent DataObject
_atomicObjectToParentDataObject.Clear();
if (unpackedRoot.DefinitionProxies is not null)
{
foreach (var defProxy in unpackedRoot.DefinitionProxies)
{
if (
defProxy.applicationId is not null
&& definitionToDataObject.TryGetValue(defProxy.applicationId, out var parentDataObject)
)
{
foreach (var objectId in defProxy.objects)
{
_atomicObjectToParentDataObject[objectId] = parentDataObject;
}
}
else
{
logger.LogError(
"Could not find parent DataObject for DefinitionProxy {ApplicationId}",
defProxy.applicationId
);
}
}
}
}
/// <summary>
/// Updates the atomic object lookup with modified IDs
/// </summary>
private void UpdateAtomicObjectLookupWithModifiedIds(Dictionary<string, List<string>> originalToModifiedIds)
{
// Build updated entries first to avoid modifying collection during iteration
var entriesToAdd = new List<KeyValuePair<string, DataObject>>();
var keysToRemove = new List<string>();
foreach (var kvp in _atomicObjectToParentDataObject)
{
if (originalToModifiedIds.TryGetValue(kvp.Key, out var modifiedIds))
{
keysToRemove.Add(kvp.Key);
foreach (var modifiedId in modifiedIds)
{
entriesToAdd.Add(new(modifiedId, kvp.Value));
}
}
}
foreach (var key in keysToRemove)
{
_atomicObjectToParentDataObject.Remove(key);
}
foreach (var entry in entriesToAdd)
{
_atomicObjectToParentDataObject[entry.Key] = entry.Value;
}
}
private Autodesk.Revit.DB.Transform? CalculateNewTransform(
Autodesk.Revit.DB.Transform? receiveTransform,
Autodesk.Revit.DB.Transform? rootTransform
@@ -278,9 +369,17 @@ public sealed class RevitHostObjectBuilder(
onOperationProgressed.Report(new("Converting", (double)++count / localToGlobalMaps.Count));
if (result is DirectShapeDefinitionWrapper)
{
// Look up parent DataObject for this atomic object (handles InstanceProxy displayValue)
var atomicId = localToGlobalMap.AtomicObject.applicationId;
DataObject? parentDataObject = null;
if (atomicId is not null)
{
_atomicObjectToParentDataObject.TryGetValue(atomicId, out parentDataObject);
}
// direct shape creation happens here
DirectShape directShapes = localToGlobalDirectShapeConverter.Convert(
(localToGlobalMap.AtomicObject, localToGlobalMap.Matrix)
(localToGlobalMap.AtomicObject, localToGlobalMap.Matrix, parentDataObject)
);
bakedObjectIds.Add(directShapes.UniqueId);
@@ -351,6 +450,7 @@ public sealed class RevitHostObjectBuilder(
DirectShapeLibrary.GetDirectShapeLibrary(converterSettings.Current.Document).Reset(); // Note: this needs to be cleared, as it is being used in the converter
revitToHostCacheSingleton.MaterialsByObjectId.Clear(); // Massive hack!
_atomicObjectToParentDataObject.Clear();
groupManager.PurgeGroups(baseGroupName);
materialBaker.PurgeMaterials(baseGroupName);
}
@@ -81,7 +81,11 @@ public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSen
foreach (Category category in _doc.Settings.Categories)
{
if (SupportedCategoriesUtils.IsSupportedCategory(category))
if (SupportedCategoriesUtils.IsSupportedCategory(category)
#if REVIT2023_OR_GREATER
&& category.BuiltInCategory != BuiltInCategory.INVALID
#endif
)
{
categories.Add(new CategoryData(category.Name, category.Id.ToString()));
}
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Autodesk.Revit.DB;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Builders;
@@ -7,6 +8,7 @@ using Speckle.Connectors.Common.Extensions;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Settings;
using Speckle.Connectors.Revit.HostApp;
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Helpers;
@@ -29,7 +31,8 @@ public class RevitRootObjectBuilder(
SendCollectionManager sendCollectionManager,
ILogger<RevitRootObjectBuilder> logger,
RevitToSpeckleCacheSingleton revitToSpeckleCacheSingleton,
LinkedModelHandler linkedModelHandler
LinkedModelHandler linkedModelHandler,
IConfigStore configStore
) : IRootObjectBuilder<DocumentToConvert>
{
public Task<RootObjectBuilderResult> Build(
@@ -42,6 +45,7 @@ public class RevitRootObjectBuilder(
() => Task.FromResult(BuildSync(documentElementContexts, projectId, onOperationProgressed, ct))
);
[SuppressMessage("Maintainability", "CA1506:Avoid excessive class coupling")]
private RootObjectBuilderResult BuildSync(
IReadOnlyList<DocumentToConvert> documentElementContexts,
string projectId,
@@ -134,6 +138,8 @@ public class RevitRootObjectBuilder(
var cacheHitCount = 0;
var skippedObjectCount = 0;
var config = configStore.GetConnectorConfig();
foreach (var atomicObjectByDocumentAndTransform in atomicObjectsByDocumentAndTransform)
{
string? modelDisplayName = null;
@@ -185,7 +191,11 @@ public class RevitRootObjectBuilder(
// TODO: Potential here to transform cached objects and NOT reconvert,
// TODO: we wont do !hasTransform here, and re-set application id before this
if (!hasTransform && sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
if (
!hasTransform
&& !config.DocumentChangeListeningDisabled //This is experimental
&& sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value)
)
{
converted = value;
cacheHitCount++;
@@ -1,43 +1,112 @@
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Converters.RevitShared.Helpers;
using Speckle.Sdk.Common;
namespace Speckle.Connectors.Revit.Plugin;
public sealed class RevitIdleManager : AppIdleManager
/// <remarks>
/// Please do NOT try and refactor this class.
/// Whether it's to try and generalize with the <see cref="IdleCallManager"/> class
/// or to unnecessary try and make this class thread safe.
/// This class is a simple singleton, targeted to a Revit's host app requirements
/// where everything happens on the main thread, and we can avoid overly complex threading/thread-safty.
///
/// Previous good refactors with good intention have lead to poor debugging experiences, over-engineered threading,
/// and low confidence in the reliability.
/// </remarks>
/// should be registered as singleton
public class RevitIdleManager(
RevitContext revitContext,
ITopLevelExceptionHandler topLevelExceptionHandler,
ILogger<RevitIdleManager> logger
)
{
private readonly UIApplication _uiApplication;
private readonly IIdleCallManager _idleCallManager;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly UIApplication _uiApplication = revitContext.UIApplication.NotNull();
private event EventHandler<IdlingEventArgs>? OnIdle;
private readonly Dictionary<string, Func<Task>> _calls = new();
private bool _hasSubscribed;
public RevitIdleManager(
RevitContext revitContext,
IIdleCallManager idleCallManager,
ITopLevelExceptionHandler topLevelExceptionHandler,
IRevitTask revitTask
)
: base(idleCallManager)
private bool _isExecutingIdle;
/// <summary>
/// Defers the invocation of an <paramref name="action"/> until next Revit idle tick (deduped by name).
/// The <paramref name="action"/> will be called only once.
/// </summary>
/// <param name="name">A key that prevents enqueuing duplicate events</param>
/// <param name="action">The action to be invoked</param>
/// <example>
/// Some events in host app are triggered many times, we might get 10x per object
/// Making this more like a deferred action, so we don't update the UI many times
/// </example>
/// <remarks>
/// This function must be called on the main thread
/// </remarks>
public void SubscribeToIdle(string name, Action action)
{
_topLevelExceptionHandler = topLevelExceptionHandler;
_uiApplication = revitContext.UIApplication.NotNull();
_idleCallManager = idleCallManager;
revitTask.Run(
() => _uiApplication.Idling += (s, e) => OnIdle?.Invoke(s, e) // will be called on the main thread always and fixing the Revit exceptions on subscribing/unsubscribing Idle events
SubscribeToIdle(
name,
() =>
{
action.Invoke();
return Task.CompletedTask;
}
);
}
protected override void AddEvent()
/// <inheritdoc cref="SubscribeToIdle(string, Action)"/>
public void SubscribeToIdle(string name, Func<Task> action)
{
_topLevelExceptionHandler.CatchUnhandled(() =>
if (_isExecutingIdle)
{
OnIdle += RevitAppOnIdle;
});
logger.LogWarning("SubscribeToIdle called while already executing idle events");
}
_calls[name] = action;
if (_hasSubscribed)
{
return;
}
_hasSubscribed = true;
_uiApplication.Idling += RevitAppOnIdle;
}
private void RevitAppOnIdle(object? sender, IdlingEventArgs e) =>
_idleCallManager.AppOnIdle(() => OnIdle -= RevitAppOnIdle);
private void RevitAppOnIdle(object? sender, IdlingEventArgs e)
{
topLevelExceptionHandler.CatchUnhandled(() =>
{
if (_isExecutingIdle)
{
logger.LogWarning("SubscribeToIdle called while already executing idle events");
}
_isExecutingIdle = true;
try
{
try
{
foreach (KeyValuePair<string, Func<Task>> kvp in _calls)
{
topLevelExceptionHandler.FireAndForget(kvp.Value.Invoke);
}
}
finally
{
_calls.Clear();
}
}
finally
{
_uiApplication.Idling -= RevitAppOnIdle;
_isExecutingIdle = false;
// setting last will delay entering re-subscription
_hasSubscribed = false;
}
});
}
}
@@ -54,9 +54,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\DetailLevelSetting.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\IRevitPlugin.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitTask.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitExternalApplication.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitThreadContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCefPlugin.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleRevitTaskException.cs" />
@@ -204,8 +204,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -215,13 +215,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -347,7 +347,7 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.logging": {
@@ -357,7 +357,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.rhino7": {
@@ -402,11 +402,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -204,8 +204,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -215,13 +215,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -347,7 +347,7 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.logging": {
@@ -357,7 +357,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.rhino8": {
@@ -401,11 +401,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -0,0 +1,311 @@
using System.Runtime.InteropServices;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Speckle.Connectors.GrasshopperShared.HostApp;
using Speckle.Connectors.GrasshopperShared.Parameters;
using Speckle.Connectors.GrasshopperShared.Properties;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.GrasshopperShared.Components.Collections;
/// <summary>
/// Creates collections by matching name tree structure to elements tree structure.
/// Each branch in the names tree corresponds to the same-path branch in the elements tree.
/// </summary>
[Guid("7E8F9A1B-2C3D-4E5F-6A7B-8C9D0E1F2A3B")]
public class CollectionsByName : GH_Component
{
public override Guid ComponentGuid => GetType().GUID;
protected override Bitmap Icon => Resources.speckle_collections_create; // TODO: Update to specific icon if available
public override GH_Exposure Exposure => GH_Exposure.primary;
public CollectionsByName()
: base(
"Collections by Name",
"CbN",
"Creates collections by matching name tree structure to objects tree structure. Each branch in the names tree corresponds to the same-path branch in the objects tree.",
ComponentCategories.PRIMARY_RIBBON,
ComponentCategories.COLLECTIONS
) { }
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddTextParameter(
"Names",
"N",
"Collection names (tree structure must match Objects tree structure)",
GH_ParamAccess.tree
);
pManager.AddGenericParameter(
"Objects",
"O",
"Objects to group into collections (tree structure must match Names tree structure)",
GH_ParamAccess.tree
);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager) =>
pManager.AddParameter(
new SpeckleCollectionParam(),
"Collection",
"C",
"Root collection containing named sub-collections",
GH_ParamAccess.item
);
protected override void SolveInstance(IGH_DataAccess da)
{
// access the tree data directly from parameters
var namesParam = Params.Input[0];
var elementsParam = Params.Input[1];
var namesTree = namesParam.VolatileData;
var elementsTree = elementsParam.VolatileData;
// validate that both inputs have data
if (namesTree.IsEmpty)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Names tree is empty");
return;
}
if (elementsTree.IsEmpty)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Objects tree is empty");
return;
}
// validate tree structures match exactly
if (!TreeStructuresMatch(namesTree, elementsTree))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Tree structures and topologies must match exactly");
return;
}
// create root collection
var rootCollection = CollectionHelpers.CreateRootCollection(InstanceGuid.ToString());
// process each path
foreach (var path in namesTree.Paths)
{
var nameBranch = namesTree.get_Branch(path);
var elementsBranch = elementsTree.get_Branch(path);
// validate name branch - throw if empty
if (nameBranch.Count == 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Name branch at path {path} is empty");
return;
}
// validate name branch - just warn if multiple, use first
if (nameBranch.Count > 1)
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
$"Name branch at path {path} has {nameBranch.Count} names - using first name only"
);
}
// get the collection name
string collectionName = GetCollectionName(nameBranch[0]);
if (string.IsNullOrWhiteSpace(collectionName))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Invalid collection name at path {path}");
return;
}
// skip empty element branches with warning
if (elementsBranch.Count == 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Skipping empty elements branch at path {path}");
continue;
}
// parse nested collection path (e.g. parent::child)
var collectionNames = collectionName.Split(
new[] { Constants.LAYER_PATH_DELIMITER },
StringSplitOptions.RemoveEmptyEntries
);
// create or get nested collection structure
var targetCollection = GetOrCreateNestedCollection(rootCollection, collectionNames, elementsBranch, path);
// add elements to deepest collection
AddElementsToCollection(targetCollection, elementsBranch, path);
}
// validate collection has content
if (rootCollection.Elements.Count == 0)
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Error,
"Collection contains no valid geometry. All branches were empty or contained unsupported types."
);
return;
}
// validate for duplicate application IDs (following CreateCollection pattern)
if (CollectionHelpers.HasDuplicateApplicationIds(rootCollection))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The same object(s) cannot appear in multiple collections");
return;
}
da.SetData(0, new SpeckleCollectionWrapperGoo(rootCollection));
}
/// <summary>
/// Validates that two tree structures have exactly matching paths
/// </summary>
private bool TreeStructuresMatch(
Grasshopper.Kernel.Data.IGH_Structure namesTree,
Grasshopper.Kernel.Data.IGH_Structure elementsTree
)
{
if (namesTree.PathCount != elementsTree.PathCount)
{
return false;
}
// check that all paths match exactly
var namePaths = namesTree.Paths.ToList();
var elementPaths = elementsTree.Paths.ToList();
for (int i = 0; i < namePaths.Count; i++)
{
if (namePaths[i].CompareTo(elementPaths[i]) != 0)
{
return false;
}
}
return true;
}
/// <summary>
/// Extracts collection name, handling GH_String and other text types
/// </summary>
private string GetCollectionName(object nameObj) =>
nameObj switch
{
GH_String ghString => ghString.Value,
IGH_Goo goo => goo.ToString(),
_ => nameObj.ToString()
};
/// <summary>
/// Gets or creates a nested collection structure based on the collection names.
/// </summary>
/// <remarks>
/// Handles paths like "parent::child::grandchild" by creating intermediate collections.
/// </remarks>
private SpeckleCollectionWrapper GetOrCreateNestedCollection(
SpeckleCollectionWrapper rootCollection,
string[] collectionNames,
System.Collections.IList elementsBranch,
Grasshopper.Kernel.Data.GH_Path path
)
{
SpeckleCollectionWrapper currentCollection = rootCollection;
var currentPath = new List<string>(rootCollection.Path);
foreach (var collectionName in collectionNames)
{
// build path for this level
currentPath.Add(collectionName);
// check if child collection already exists
var existingChild = currentCollection
.Elements.OfType<SpeckleCollectionWrapper>()
.FirstOrDefault(c => c.Name == collectionName);
if (existingChild != null)
{
// use existing collection
currentCollection = existingChild;
}
else
{
// create new child collection
var newChild = new SpeckleCollectionWrapper
{
Base = new Collection(),
Name = collectionName,
Path = currentPath.ToList(),
Color = null,
Material = null,
Topology = null, // only set topology on leaf collections
ApplicationId = Guid.NewGuid().ToString()
};
currentCollection.Elements.Add(newChild);
currentCollection = newChild;
}
}
// set topology on the final (leaf) collection
currentCollection.Topology = GetBranchTopology(path, elementsBranch.Count);
return currentCollection;
}
/// <summary>
/// Adds elements from a branch to the target collection
/// </summary>
private void AddElementsToCollection(
SpeckleCollectionWrapper targetCollection,
System.Collections.IList elementsBranch,
Grasshopper.Kernel.Data.GH_Path path
)
{
foreach (var item in elementsBranch)
{
if (item == null)
{
// preserve nulls for topology (CNX-2855 pattern)
targetCollection.Elements.Add(null);
continue;
}
// convert to SpeckleWrapper if possible - cast to IGH_Goo first
if (item is not IGH_Goo goo)
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
$"Unsupported object type in branch {path}: {item.GetType().Name}"
);
continue;
}
var wrapper = goo.ToSpeckleObjectWrapper();
if (wrapper == null)
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
$"Unsupported object type in branch {path}: {item.GetType().Name}"
);
continue;
}
if (wrapper is ISpeckleCollectionObject collectionObject)
{
targetCollection.Elements.Add(collectionObject);
}
else
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
$"Object type {wrapper.GetType().Name} is not a valid collection element"
);
}
}
}
/// <summary>
/// Creates topology string for a single branch (following GrasshopperHelpers.GetParamTopology pattern)
/// </summary>
private string GetBranchTopology(Grasshopper.Kernel.Data.GH_Path path, int count) =>
$"{path.ToString(false)}-{count}";
}
@@ -47,7 +47,7 @@ public class CreateCollection : VariableParameterComponentBase
protected override void SolveInstance(IGH_DataAccess dataAccess)
{
var rootCollection = CreateRootCollection();
var rootCollection = CollectionHelpers.CreateRootCollection(InstanceGuid.ToString());
bool hasAnyInput = false;
foreach (var inputParam in Params.Input)
@@ -73,14 +73,14 @@ public class CreateCollection : VariableParameterComponentBase
}
// validate for duplicate application IDs across the entire collection hierarchy
if (HasDuplicateApplicationIds(rootCollection))
if (CollectionHelpers.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))
if (rootCollection.Elements.Count == 0 || !rootCollection.Elements.Any(CollectionHelpers.HasAnyValidContent))
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Error,
@@ -233,56 +233,6 @@ public class CreateCollection : VariableParameterComponentBase
}
}
/// <summary>
/// Validates that all application IDs are unique across the entire collection hierarchy.
/// Shows an error if duplicates are found, indicating objects appear in multiple collections.
/// </summary>
/// <returns>True if duplicates exist, false if all IDs are unique</returns>
private bool HasDuplicateApplicationIds(SpeckleCollectionWrapper rootCollection)
{
// args to CheckForDuplicateApplicationIds passed in since the method can recursively check
var seenIds = new HashSet<string>();
var duplicateIds = new HashSet<string>();
// iterate, create hash set and check all application IDs
ProcessAndCheckForDuplicateApplicationIds(rootCollection, seenIds, duplicateIds);
return duplicateIds.Count > 0;
}
/// <summary>
/// Recursively collects application IDs from all in the collection hierarchy.
/// </summary>
/// <remarks>
/// Only checks the wrapper's ApplicationId, not for example geometries within DataObjects.
/// </remarks>
private void ProcessAndCheckForDuplicateApplicationIds(
SpeckleCollectionWrapper collection,
HashSet<string> seenIds,
HashSet<string> duplicateIds
)
{
foreach (var element in collection.Elements)
{
switch (element)
{
case null:
break; // skip nulls (CNX-2855)
case SpeckleCollectionWrapper childCollection:
// recurse into child collections
ProcessAndCheckForDuplicateApplicationIds(childCollection, seenIds, duplicateIds);
break;
case SpeckleWrapper wrapper:
if (wrapper.ApplicationId != null && !seenIds.Add(wrapper.ApplicationId))
{
duplicateIds.Add(wrapper.ApplicationId);
}
break;
}
}
}
// IGH_VariableParameterComponent implementation
public override bool CanInsertParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Input;
@@ -1,5 +1,6 @@
using System.Runtime.InteropServices;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Grasshopper.Kernel.Types;
using Speckle.Connectors.GrasshopperShared.Components.BaseComponents;
using Speckle.Connectors.GrasshopperShared.HostApp;
@@ -12,7 +13,7 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
/// Given a list of objects, this component will filter the list for objects that match the queries.
/// </summary>
[Guid("26AEA046-4DD4-4F61-8251-E92A6D2AC880")]
public class FilterSpeckleObjects : GH_Component
public class FilterSpeckleObjects : GH_Component, IGH_VariableParameterComponent
{
public override Guid ComponentGuid => GetType().GUID;
protected override Bitmap Icon => Resources.speckle_objects_filter;
@@ -49,17 +50,6 @@ public class FilterSpeckleObjects : GH_Component
GH_ParamAccess.item
);
Params.Input[3].Optional = true;
pManager.AddTextParameter(
"Application Id",
"aID",
"Find objects with a matching applicationId",
GH_ParamAccess.item
);
Params.Input[4].Optional = true;
pManager.AddTextParameter("Speckle Id", "sID", "Find objects with a matching Speckle id", GH_ParamAccess.item);
Params.Input[5].Optional = true;
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
@@ -103,101 +93,39 @@ public class FilterSpeckleObjects : GH_Component
dataAccess.GetData(2, ref property);
string material = "";
dataAccess.GetData(3, ref material);
// optional parameters - only read if they've been added via ⊕
string appId = "";
dataAccess.GetData(4, ref appId);
string speckleId = "";
dataAccess.GetData(5, ref speckleId);
int? appIdIndex = FindInputIndexByName("Application Id");
int? speckleIdIndex = FindInputIndexByName("Speckle Id");
if (appIdIndex.HasValue)
{
dataAccess.GetData(appIdIndex.Value, ref appId);
}
if (speckleIdIndex.HasValue)
{
dataAccess.GetData(speckleIdIndex.Value, ref speckleId);
}
bool filterByAppId = appIdIndex.HasValue;
bool filterBySpeckleId = speckleIdIndex.HasValue;
List<SpeckleWrapper> matchedObjects = new();
List<SpeckleWrapper> removedObjects = new();
for (int i = 0; i < objects.Count; i++)
foreach (SpeckleWrapper wrapper in objects.Cast<SpeckleWrapper>())
{
SpeckleWrapper wrapper = objects[i]!;
// filter by name
if (!MatchesSearchPattern(name, wrapper.Name))
if (MatchesAllFilters(wrapper, name, property, material, appId, filterByAppId, speckleId, filterBySpeckleId))
{
removedObjects.Add(wrapper);
continue;
}
// filter by property
bool foundProperty = false;
if (string.IsNullOrEmpty(property))
{
foundProperty = true;
matchedObjects.Add(wrapper);
}
else
{
SpecklePropertyGroupGoo? properties = wrapper is SpeckleDataObjectWrapper dataObjPropWrapper
? dataObjPropWrapper.Properties
: wrapper is SpeckleGeometryWrapper geoPropWrapper
? geoPropWrapper.Properties
: null;
if (properties is not null)
{
// use flattened properties to search ALL nested property keys
// fix for [CNX-2512](https://linear.app/speckle/issue/CNX-2512/filter-objects-material-and-property-key-inputs-dont-work-as-expected)
Dictionary<string, SpecklePropertyGoo> flattenedProps = properties.Flatten();
foreach (string key in flattenedProps.Keys)
{
if (MatchesSearchPattern(property, key))
{
foundProperty = true;
break;
}
}
}
}
if (!foundProperty)
{
removedObjects.Add(wrapper);
continue;
}
// filter by material name
bool materialMatches = true;
if (!string.IsNullOrEmpty(material))
{
materialMatches = false;
if (wrapper is SpeckleGeometryWrapper geoWrapper)
{
materialMatches = MatchesSearchPattern(material, geoWrapper.Material?.Name ?? "");
}
else if (wrapper is SpeckleDataObjectWrapper dataObjWrapper)
{
// check if ANY geometry in the data object has a matching material (not sure about this...)
// fix for [CNX-2512](https://linear.app/speckle/issue/CNX-2512/filter-objects-material-and-property-key-inputs-dont-work-as-expected)
materialMatches = dataObjWrapper.Geometries.Any(geo =>
MatchesSearchPattern(material, geo.Material?.Name ?? "")
);
}
}
if (!materialMatches)
{
removedObjects.Add(wrapper);
continue;
}
// filter by application id
if (!MatchesSearchPattern(appId, wrapper.Base.applicationId ?? ""))
{
removedObjects.Add(wrapper);
continue;
}
// filter by speckle id
if (!MatchesSearchPattern(speckleId, wrapper.Base.id ?? ""))
{
removedObjects.Add(wrapper);
continue;
}
matchedObjects.Add(wrapper);
}
// Set output objects
@@ -214,4 +142,190 @@ public class FilterSpeckleObjects : GH_Component
return Operator.IsSymbolNameLike(target, searchPattern);
}
/// <summary>
/// Determines if a wrapper matches all active filter criteria.
/// </summary>
private bool MatchesAllFilters(
SpeckleWrapper wrapper,
string name,
string property,
string material,
string appId,
bool filterByAppId,
string speckleId,
bool filterBySpeckleId
)
{
// filter by name
if (!MatchesSearchPattern(name, wrapper.Name))
{
return false;
}
// filter by property
if (!MatchesPropertyFilter(wrapper, property))
{
return false;
}
// filter by material name
if (!MatchesMaterialFilter(wrapper, material))
{
return false;
}
// filter by application id (only if parameter was added)
if (filterByAppId && !MatchesSearchPattern(appId, wrapper.Base.applicationId ?? ""))
{
return false;
}
// filter by speckle id (only if parameter was added)
if (filterBySpeckleId && !MatchesSearchPattern(speckleId, wrapper.Base.id ?? ""))
{
return false;
}
return true;
}
private bool MatchesPropertyFilter(SpeckleWrapper wrapper, string property)
{
if (string.IsNullOrEmpty(property))
{
return true;
}
SpecklePropertyGroupGoo? properties = wrapper is SpeckleDataObjectWrapper dataObjPropWrapper
? dataObjPropWrapper.Properties
: wrapper is SpeckleGeometryWrapper geoPropWrapper
? geoPropWrapper.Properties
: null;
if (properties is null)
{
return false;
}
// use flattened properties to search ALL nested property keys
return properties.Flatten().Keys.Any(key => MatchesSearchPattern(property, key));
}
private bool MatchesMaterialFilter(SpeckleWrapper wrapper, string material)
{
if (string.IsNullOrEmpty(material))
{
return true;
}
if (wrapper is SpeckleGeometryWrapper geoWrapper)
{
return MatchesSearchPattern(material, geoWrapper.Material?.Name ?? "");
}
if (wrapper is SpeckleDataObjectWrapper dataObjWrapper)
{
// check if ANY geometry in the data object has a matching material
return dataObjWrapper.Geometries.Any(geo => MatchesSearchPattern(material, geo.Material?.Name ?? ""));
}
return false;
}
/// <summary>
/// Finds the index of an input parameter by its Name.
/// Returns null if the parameter doesn't exist.
/// </summary>
private int? FindInputIndexByName(string paramName)
{
for (int i = 0; i < Params.Input.Count; i++)
{
if (Params.Input[i].Name == paramName)
{
return i;
}
}
return null;
}
#region IGH_VariableParameterComponent
public bool CanInsertParameter(GH_ParameterSide side, int index)
{
if (side != GH_ParameterSide.Input)
{
return false;
}
// only allow inserting after the fixed parameters (index 4+)
if (index < 4)
{
return false;
}
// check how many optional params are already added (total inputs - 4 fixed)
int addedOptionalCount = Params.Input.Count - 4;
// we have 2 optional parameters available
return addedOptionalCount < 2;
}
public bool CanRemoveParameter(GH_ParameterSide side, int index) =>
// only allow removing optional input parameters (index 4+)
side == GH_ParameterSide.Input
&& index >= 4;
/// <remarks>
/// The ternary operator for NickName is needed due to a Grasshopper quirk where
/// dynamically created parameters don't respect the "Draw Full Names" setting automatically.
/// We check CanvasFullNames at creation time to set the appropriate NickName.
/// This does not handle the case where the user toggles "Draw Full Names" while the
/// component is already on the canvas. Handling that would require subscribing to
/// Grasshopper.CentralSettings.CanvasFullNamesChanged event, which is overkill for now.
/// </remarks>
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
{
bool hasAppId = FindInputIndexByName("Application Id").HasValue;
bool hasSpeckleId = FindInputIndexByName("Speckle Id").HasValue;
if (!hasAppId)
{
return new Param_String
{
Name = "Application Id",
NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Application Id" : "aID", // see remarks
Description = "Find objects with a matching applicationId",
Access = GH_ParamAccess.item,
Optional = true
};
}
if (!hasSpeckleId)
{
return new Param_String
{
Name = "Speckle Id",
NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Speckle Id" : "sID", // see remarks
Description = "Find objects with a matching Speckle id",
Access = GH_ParamAccess.item,
Optional = true
};
}
return new Param_String();
}
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Input && index >= 4;
public void VariableParameterMaintenance()
{
// ensure all optional parameters stay marked as optional
for (int i = 4; i < Params.Input.Count; i++)
{
Params.Input[i].Optional = true;
}
}
#endregion
}
@@ -9,7 +9,7 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
[Guid("8D2E3F4A-1B5C-4E7F-9A8B-3C6D9E2F1A4B")]
public class SpeckleBlockDefinitionPassthrough()
: SpeckleSolveInstance(
: SpecklePassthroughComponentBase(
"Speckle Block Definition",
"SBD",
"Create or modify a Speckle Block Definition",
@@ -21,6 +21,9 @@ public class SpeckleBlockDefinitionPassthrough()
protected override Bitmap Icon => Resources.speckle_objects_block_def;
public override GH_Exposure Exposure => GH_Exposure.tertiary;
protected override int FixedInputCount => 3;
protected override int FixedOutputCount => 3;
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(
@@ -122,12 +125,16 @@ public class SpeckleBlockDefinitionPassthrough()
result.Value.Name = inputName;
}
// no need to process application Id.
// New definitions should have a new appID generated in the new() constructor, and we want to preserve old appID otherwise for changetracking.
// process application id (only if user provided one, otherwise preserve existing)
if (TryGetApplicationIdInput(da, out string? inputAppId))
{
result.Value.ApplicationId = inputAppId;
}
// set outputs
da.SetData(0, result);
da.SetDataList(1, result.Value.Objects.Select(o => o.CreateGoo()));
da.SetData(2, result.Value.Name);
SetApplicationIdOutput(da, result.Value.ApplicationId);
}
}
@@ -9,7 +9,7 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
[Guid("2F8A9B1C-3D4E-5F6A-7B8C-9D0E1F2A3B4C")]
public class SpeckleBlockInstancePassthrough()
: SpeckleSolveInstance(
: SpecklePassthroughComponentBase(
"Speckle Block Instance",
"SBI",
"Create or modify a Speckle Block Instance",
@@ -21,6 +21,9 @@ public class SpeckleBlockInstancePassthrough()
protected override Bitmap Icon => Resources.speckle_objects_block_inst;
public override GH_Exposure Exposure => GH_Exposure.tertiary;
protected override int FixedInputCount => 7;
protected override int FixedOutputCount => 7;
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
int instanceIndex = pManager.AddParameter(
@@ -205,8 +208,11 @@ public class SpeckleBlockInstancePassthrough()
result.Value.Material = inputMaterial.Value;
}
// no need to process application id.
// new appids are generated if this is a new object, otherwise the input object appID should be preserved for change tracking.
// process application id (only if user provided one, otherwise preserve existing)
if (TryGetApplicationIdInput(da, out string? inputAppId))
{
result.Value.ApplicationId = inputAppId;
}
// Set outputs
da.SetData(0, result);
@@ -216,6 +222,7 @@ public class SpeckleBlockInstancePassthrough()
da.SetData(4, result.Value.Properties);
da.SetData(5, result.Value.Color);
da.SetData(6, result.Value.Material);
SetApplicationIdOutput(da, result.Value.ApplicationId);
}
private Transform? ExtractTransform(IGH_Goo input) =>
@@ -8,7 +8,7 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
[Guid("5CE8AA40-7706-4893-853D-4C77604548FA")]
public class SpeckleDataObjectPassthrough()
: SpeckleSolveInstance(
: SpecklePassthroughComponentBase(
"Speckle Data Object",
"SDO",
"Create or modify a Speckle Data Object",
@@ -20,6 +20,9 @@ public class SpeckleDataObjectPassthrough()
protected override Bitmap Icon => Resources.speckle_objects_dataobject;
public override GH_Exposure Exposure => GH_Exposure.secondary;
protected override int FixedInputCount => 4;
protected override int FixedOutputCount => 5;
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
int objIndex = pManager.AddParameter(
@@ -158,9 +161,17 @@ public class SpeckleDataObjectPassthrough()
result.Properties = inputProperties;
}
// generate application ID for new data objects. Unlike SpeckleGeometry, DataObject wrappers aren't created
// through casting (which auto-generates IDs), so we must explicitly ensure an ID exists here
result.ApplicationId ??= Guid.NewGuid().ToString();
// process application id (only if user provided one)
if (TryGetApplicationIdInput(da, out string? inputAppId))
{
result.ApplicationId = inputAppId;
}
else
{
// generate application ID for new data objects. Unlike SpeckleGeometry, DataObject wrappers aren't created
// through casting (which auto-generates IDs), so we must explicitly ensure an ID exists here
result.ApplicationId ??= Guid.NewGuid().ToString();
}
// get the path
string? path =
@@ -172,5 +183,6 @@ public class SpeckleDataObjectPassthrough()
da.SetData(2, result.Name);
da.SetData(3, result.Properties);
da.SetData(4, path);
SetApplicationIdOutput(da, result.ApplicationId);
}
}
@@ -10,7 +10,7 @@ namespace Speckle.Connectors.GrasshopperShared.Components.Objects;
[Guid("F9418610-ACAE-4417-B010-19EBEA6A121F")]
public class SpeckleGeometryPassthrough()
: SpeckleSolveInstance(
: SpecklePassthroughComponentBase(
"Speckle Geometry",
"SG",
"Create or modify a Speckle Geometry",
@@ -22,6 +22,9 @@ public class SpeckleGeometryPassthrough()
protected override Bitmap Icon => Resources.speckle_objects_geometry;
public override GH_Exposure Exposure => GH_Exposure.secondary;
protected override int FixedInputCount => 6;
protected override int FixedOutputCount => 7;
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
int objIndex = pManager.AddGenericParameter(
@@ -220,8 +223,11 @@ public class SpeckleGeometryPassthrough()
result.Material = inputMaterial.Value;
}
// no need to process application Id.
// New definitions should have a new appID generated in the new() constructor, and we want to preserve old appID otherwise for changetracking.
// process application id (only if user provided one, otherwise preserve existing)
if (TryGetApplicationIdInput(da, out string? inputAppId))
{
result.ApplicationId = inputAppId;
}
// get the path
string? path =
@@ -235,6 +241,7 @@ public class SpeckleGeometryPassthrough()
da.SetData(4, result.Color);
da.SetData(5, result.Material);
da.SetData(6, path);
SetApplicationIdOutput(da, result.ApplicationId);
}
// keeps the geometry and wrapped base the same while assigning all other props from the inut wrapper
@@ -1,8 +1,19 @@
using Speckle.Connectors.Common.Operations;
using Speckle.Sdk.Credentials;
using Version = Speckle.Sdk.Api.GraphQL.Models.Version;
namespace Speckle.Connectors.GrasshopperShared.Components.Operations.Receive;
/// <param name="Account"></param>
/// <param name="WorkspaceId"></param>
/// <param name="ProjectId"></param>
/// <param name="ProjectName"></param>
/// <param name="ModelId"></param>
/// <param name="ModelName"></param>
/// <param name="SelectedVersionId"></param>
/// <param name="SourceApplication">See <see cref="Version.sourceApplication"/></param>
/// <param name="ReceivingApplicationSlug">Slug of the application doing the receiving (i.e. the current host app)</param>
/// <param name="SelectedVersionUserId"></param>
public record GrasshopperReceiveInfo(
Account Account,
string? WorkspaceId,
@@ -12,5 +23,6 @@ public record GrasshopperReceiveInfo(
string ModelName,
string SelectedVersionId,
string SourceApplication,
string ReceivingApplicationSlug,
string? SelectedVersionUserId
) : ReceiveInfo(Account, ProjectId, ProjectName, ModelId, ModelName, SelectedVersionId, SourceApplication);
) : ReceiveInfo(Account, ProjectId, ProjectName, ModelId, ModelName, SelectedVersionId, ReceivingApplicationSlug);
@@ -87,6 +87,7 @@ public class SendAsyncComponent : GH_AsyncComponent<SendAsyncComponent>
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam());
pManager.AddTextParameter("Version ID", "V", "ID of the created version", GH_ParamAccess.item);
}
public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
@@ -321,6 +322,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
private Stopwatch? _stopwatch;
public SpeckleUrlModelResource? OutputParam { get; set; }
public string? OutputVersionId { get; set; }
private List<(GH_RuntimeMessageLevel, string)> RuntimeMessages { get; } = new();
public override WorkerInstance<SendAsyncComponent> Duplicate(string id, CancellationToken cancellationToken)
@@ -332,6 +334,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
{
_stopwatch = new Stopwatch();
_stopwatch.Start();
OutputVersionId = null;
}
public override void SetData(IGH_DataAccess da)
@@ -342,6 +345,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
{
Parent.JustPastedIn = false;
da.SetData(0, Parent.OutputParam);
da.SetData(1, OutputVersionId);
return;
}
@@ -357,6 +361,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
}
da.SetData(0, OutputParam);
da.SetData(1, OutputVersionId);
Parent.CurrentComponentState = ComponentState.UpToDate;
Parent.OutputParam = OutputParam; // ref the outputs in the parent too, so we can serialise them on write/read
@@ -373,7 +378,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
*/
Parent.AddRuntimeMessage(
GH_RuntimeMessageLevel.Remark,
$"Successfully published to Speckle. Right-click on the component to view online."
"Successfully published to Speckle. Right-click on the component to view online."
);
Parent.AddRuntimeMessage(
GH_RuntimeMessageLevel.Remark,
@@ -471,6 +476,7 @@ public class SendComponentWorker : WorkerInstance<SendAsyncComponent>
result.VersionId
);
OutputParam = createdVersion;
OutputVersionId = result.VersionId;
Parent.Url = $"{createdVersion.Account.Server}/projects/{sendInfo.ProjectId}/models/{sendInfo.ModelId}";
}
}
@@ -36,9 +36,10 @@ public class SendComponentInput
}
}
public class SendComponentOutput(SpeckleUrlModelResource? resource)
public class SendComponentOutput(SpeckleUrlModelResource? resource, string? versionId = null)
{
public SpeckleUrlModelResource? Resource { get; } = resource;
public string? VersionId { get; } = versionId;
}
public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, SendComponentOutput>
@@ -86,8 +87,11 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
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());
pManager.AddTextParameter("Version ID", "V", "ID of the created version", GH_ParamAccess.item);
}
protected override SendComponentInput GetInput(IGH_DataAccess da)
{
@@ -134,6 +138,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
else
{
da.SetData(0, result.Resource);
da.SetData(1, result.VersionId);
Message = "Done";
}
}
@@ -216,7 +221,7 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
using var client = clientFactory.Create(account);
var sendInfo = await input.Resource.GetSendInfo(client, cancellationToken).ConfigureAwait(false);
await sendOperation
var result = await sendOperation
.Execute(
new List<SpeckleCollectionWrapperGoo> { collectionToSend },
sendInfo,
@@ -244,6 +249,6 @@ public class SendComponent : SpeckleTaskCapableComponent<SendComponentInput, Sen
sendInfo.ModelId
);
Url = $"{sendInfo.Account.serverInfo.url}/projects/{sendInfo.ProjectId}/models/{sendInfo.ModelId}";
return new SendComponentOutput(createdVersionResource);
return new SendComponentOutput(createdVersionResource, result.VersionId);
}
}
@@ -0,0 +1,231 @@
using GH_IO.Serialization;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
namespace Speckle.Connectors.GrasshopperShared.Components;
/// <summary>
/// Base class for passthrough components with "hidden" Application ID parameter.
/// </summary>
/// <remarks>
/// Users can click ⊕ to add an optional Application ID input and output.
/// </remarks>
public abstract class SpecklePassthroughComponentBase : SpeckleSolveInstance, IGH_VariableParameterComponent
{
private const string APP_ID_NAME = "Application Id";
private const string APP_ID_NICKNAME = "aID";
private const string APP_ID_DESCRIPTION = "The application id of the Speckle objects";
protected abstract int FixedInputCount { get; }
protected abstract int FixedOutputCount { get; }
private bool HasApplicationIdParam => Params.Input.Count > FixedInputCount;
protected SpecklePassthroughComponentBase(
string name,
string nickname,
string description,
string category,
string subCategory
)
: base(name, nickname, description, category, subCategory) { }
/// <summary>
/// Reads the optional Application Id input. Returns true if user provided a valid value.
/// </summary>
protected bool TryGetApplicationIdInput(IGH_DataAccess da, out string? applicationId)
{
applicationId = null;
if (!HasApplicationIdParam)
{
return false;
}
string appId = string.Empty;
if (da.GetData(FixedInputCount, ref appId))
{
if (string.IsNullOrWhiteSpace(appId))
{
AddRuntimeMessage(
GH_RuntimeMessageLevel.Warning,
"Empty Application Id ignored - existing or auto-generated id will be used"
);
return false;
}
applicationId = appId;
return true;
}
return false;
}
/// <summary>
/// Sets the Application Id output (if the parameter exists).
/// </summary>
protected void SetApplicationIdOutput(IGH_DataAccess da, string? applicationId)
{
if (!HasApplicationIdParam)
{
return;
}
da.SetData(FixedOutputCount, applicationId);
}
public bool CanInsertParameter(GH_ParameterSide side, int index)
{
// only allow inserting if not yet added
if (HasApplicationIdParam)
{
return false;
}
// only allow at the end position
return side switch
{
GH_ParameterSide.Input => index == FixedInputCount,
GH_ParameterSide.Output => index == FixedOutputCount,
_ => false
};
}
public bool CanRemoveParameter(GH_ParameterSide side, int index)
{
if (!HasApplicationIdParam)
{
return false;
}
return side switch
{
GH_ParameterSide.Input => index == FixedInputCount,
GH_ParameterSide.Output => index == FixedOutputCount,
_ => false
};
}
/// <remarks>
/// The ternary for NickName handles a Grasshopper quirk where dynamically created parameters
/// don't respect the "Draw Full Names" setting automatically.
/// </remarks>
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
{
// when adding on either side, add both input and output together
if (side == GH_ParameterSide.Input && Params.Output.Count == FixedOutputCount)
{
OnPingDocument()?.ScheduleSolution(5, _ => AddApplicationIdOutput());
}
else if (side == GH_ParameterSide.Output && Params.Input.Count == FixedInputCount)
{
OnPingDocument()?.ScheduleSolution(5, _ => AddApplicationIdInput());
}
return CreateApplicationIdParam();
}
public bool DestroyParameter(GH_ParameterSide side, int index)
{
// when removing from either side, remove both input and output together
if (side == GH_ParameterSide.Input && index == FixedInputCount && Params.Output.Count > FixedOutputCount)
{
OnPingDocument()?.ScheduleSolution(5, _ => RemoveApplicationIdOutput());
}
else if (side == GH_ParameterSide.Output && index == FixedOutputCount && Params.Input.Count > FixedInputCount)
{
OnPingDocument()?.ScheduleSolution(5, _ => RemoveApplicationIdInput());
}
return side switch
{
GH_ParameterSide.Input => index == FixedInputCount,
GH_ParameterSide.Output => index == FixedOutputCount,
_ => false
};
}
public void VariableParameterMaintenance()
{
// ensure the Application Id input stays optional
if (HasApplicationIdParam && Params.Input.Count > FixedInputCount)
{
Params.Input[FixedInputCount].Optional = true;
}
}
private static IGH_Param CreateApplicationIdParam() =>
new Param_String
{
Name = APP_ID_NAME,
NickName = Grasshopper.CentralSettings.CanvasFullNames ? APP_ID_NAME : APP_ID_NICKNAME,
Description = APP_ID_DESCRIPTION,
Access = GH_ParamAccess.item,
Optional = true
};
private void AddApplicationIdInput()
{
if (Params.Input.Count > FixedInputCount)
{
return;
}
Params.RegisterInputParam(CreateApplicationIdParam());
Params.OnParametersChanged();
VariableParameterMaintenance();
ExpireSolution(true);
}
private void AddApplicationIdOutput()
{
if (Params.Output.Count > FixedOutputCount)
{
return;
}
Params.RegisterOutputParam(CreateApplicationIdParam());
Params.OnParametersChanged();
ExpireSolution(true);
}
private void RemoveApplicationIdInput()
{
if (Params.Input.Count <= FixedInputCount)
{
return;
}
Params.UnregisterInputParameter(Params.Input[FixedInputCount]);
Params.OnParametersChanged();
ExpireSolution(true);
}
private void RemoveApplicationIdOutput()
{
if (Params.Output.Count <= FixedOutputCount)
{
return;
}
Params.UnregisterOutputParameter(Params.Output[FixedOutputCount]);
Params.OnParametersChanged();
ExpireSolution(true);
}
public override bool Write(GH_IWriter writer)
{
var result = base.Write(writer);
writer.SetBoolean("HasApplicationIdParam", HasApplicationIdParam);
return result;
}
public override bool Read(GH_IReader reader)
{
var result = base.Read(reader);
// parameters are restored by GH serialization, this flag is for reference
bool hasAppIdParam = false;
reader.TryGetBoolean("HasApplicationIdParam", ref hasAppIdParam);
return result;
}
}
@@ -0,0 +1,83 @@
using Speckle.Connectors.GrasshopperShared.Parameters;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.GrasshopperShared.Components.Collections;
/// <summary>
/// Shared helper methods for collection components to avoid code duplication
/// </summary>
public static class CollectionHelpers
{
/// <summary>
/// Creates a root collection wrapper with default values
/// </summary>
public static SpeckleCollectionWrapper CreateRootCollection(string instanceGuid) =>
new SpeckleCollectionWrapper
{
Base = new Collection(),
Name = "Unnamed",
Path = new List<string> { "Unnamed" },
Color = null,
Material = null,
ApplicationId = instanceGuid
};
/// <summary>
/// Validates that all application IDs are unique across the entire collection hierarchy.
/// </summary>
/// <returns>True if duplicates exist, false if all IDs are unique</returns>
public static bool HasDuplicateApplicationIds(SpeckleCollectionWrapper rootCollection)
{
var seenIds = new HashSet<string>();
var duplicateIds = new HashSet<string>();
ProcessAndCheckForDuplicateApplicationIds(rootCollection, seenIds, duplicateIds);
return duplicateIds.Count > 0;
}
/// <summary>
/// Recursively collects application IDs from all wrappers in the collection hierarchy.
/// </summary>
/// <remarks>
/// Only checks the wrapper's ApplicationId, not for example geometries within DataObjects.
/// </remarks>
private static void ProcessAndCheckForDuplicateApplicationIds(
SpeckleCollectionWrapper collection,
HashSet<string> seenIds,
HashSet<string> duplicateIds
)
{
foreach (var element in collection.Elements)
{
switch (element)
{
case null:
break; // skip nulls (CNX-2855)
case SpeckleCollectionWrapper childCollection:
// recurse into child collections
ProcessAndCheckForDuplicateApplicationIds(childCollection, seenIds, duplicateIds);
break;
case SpeckleWrapper wrapper:
if (wrapper.ApplicationId != null && !seenIds.Add(wrapper.ApplicationId))
{
duplicateIds.Add(wrapper.ApplicationId);
}
break;
}
}
}
/// <summary>
/// Recursively checks if collection or any descendants contain valid geometry/data objects
/// </summary>
public static bool HasAnyValidContent(ISpeckleCollectionObject? element) =>
element switch
{
SpeckleGeometryWrapper => true,
SpeckleDataObjectWrapper => true,
SpeckleCollectionWrapper collection => collection.Elements.Any(HasAnyValidContent),
_ => false
};
}
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.GrasshopperShared.Components.Operations.Receive;
using Speckle.Connectors.GrasshopperShared.Components.Operations.Send;
@@ -50,6 +51,7 @@ public record SpeckleUrlLatestModelVersionResource(
model.name,
version.id,
version.sourceApplication.NotNull(),
HostApplications.Grasshopper.Slug,
version.authorUser?.id
);
@@ -65,13 +67,7 @@ public record SpeckleUrlLatestModelVersionResource(
await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
await client.Model.Get(ModelId, ProjectId, cancellationToken).ConfigureAwait(false);
return new GrasshopperSendInfo(
client.Account,
WorkspaceId,
ProjectId,
ModelId,
"Grasshopper8" // TODO: Grab from the right place!
);
return new GrasshopperSendInfo(client.Account, WorkspaceId, ProjectId, ModelId, HostApplications.Grasshopper.Slug);
}
}
@@ -101,6 +97,7 @@ public record SpeckleUrlModelVersionResource(
model.name,
VersionId,
version.sourceApplication.NotNull(),
HostApplications.Grasshopper.Slug,
version.authorUser?.id
);
@@ -116,13 +113,7 @@ public record SpeckleUrlModelVersionResource(
await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
await client.Model.Get(ModelId, ProjectId, cancellationToken).ConfigureAwait(false);
return new GrasshopperSendInfo(
client.Account,
WorkspaceId,
ProjectId,
ModelId,
"Grasshopper8" // TODO: Grab from the right place!
);
return new GrasshopperSendInfo(client.Account, WorkspaceId, ProjectId, ModelId, HostApplications.Grasshopper.Slug);
}
}
@@ -95,7 +95,7 @@ public class GrasshopperReceiveOperation
.ConfigureAwait(false);
await apiClient
.Version.Received(new(version.id, receiveInfo.ProjectId, receiveInfo.SourceApplication), cancellationToken)
.Version.Received(new(version.id, receiveInfo.ProjectId, receiveInfo.ReceivingApplicationSlug), cancellationToken)
.ConfigureAwait(false);
return commitObject;
}
@@ -225,6 +225,14 @@ internal sealed class LocalToGlobalMapHandler
var entry = _dataObjectInstanceRegistry.GetEntries()[dataObjectId];
var resolvedGeometries = ResolveInstanceProxiesToGeometries(entry.InstanceProxies);
var primitiveConverted = dataObject
.displayValue.Where(item => item is not InstanceProxy)
.SelectMany(item => SpeckleConversionContext.Current.ConvertToHost(item))
.ToList();
resolvedGeometries.AddRange(ConvertToGeometryWrappers(primitiveConverted));
var dataObjectWrapper = CreateDataObjectWrapper(dataObject, resolvedGeometries, path, objectCollection);
CollectionRebuilder.AppendSpeckleGrasshopperObject(dataObjectWrapper, path, _colorUnpacker, _materialUnpacker);
@@ -14,6 +14,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Components\BaseComponents\ValueSet.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\BaseComponents\VariableParameterComponentBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\CollectionPathsSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\CollectionsByName.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\CreateCollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Collections\ExpandCollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Objects\ExpandSpeckleProperties.cs" />
@@ -41,7 +42,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Components\Operations\Wizard\VersionMenuHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Operations\Wizard\WorkspaceMenuHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\Operations\Wizard\SpeckleOperationWizard.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\SpecklePassthroughComponentBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Components\SpeckleSolveInstance.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CollectionHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Extras\StateTag.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\KeyWatcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\GrasshopperBlockUnpacker.cs" />
@@ -185,8 +185,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -196,13 +196,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -328,14 +328,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -361,7 +362,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.rhino7": {
@@ -421,11 +422,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Resources.Extensions": {
@@ -437,6 +438,12 @@
"System.Formats.Nrbf": "9.0.4",
"System.Memory": "4.5.5"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -185,8 +185,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -196,13 +196,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -328,14 +328,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -361,7 +362,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.rhino8": {
@@ -420,11 +421,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Resources.Extensions": {
@@ -436,6 +437,12 @@
"System.Formats.Nrbf": "9.0.4",
"System.Memory": "4.5.5"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -174,8 +174,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -183,13 +183,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -255,14 +255,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -279,7 +280,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"speckle.converters.rhino8": {
@@ -329,12 +330,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -122,7 +122,9 @@ public class RhinoLayerBaker : TraversalContextUnpacker
continue;
}
var cleanNewLayerName = RhinoUtils.CleanLayerName(collection.name);
var cleanNewLayerName = string.IsNullOrWhiteSpace(collection.name)
? "unnamed"
: RhinoUtils.CleanLayerName(collection.name);
if (!ModelComponent.IsValidComponentName(cleanNewLayerName))
{
@@ -14,6 +14,7 @@ public static class RhinoUtils
public static string CleanLayerName(string str)
{
var sb = new StringBuilder(str.Length);
bool lastWasSpace = true;
foreach (char c in str)
{
@@ -30,10 +31,29 @@ public static class RhinoUtils
if (s_replaceWithHyphen.Contains(c))
{
sb.Append('-');
lastWasSpace = false;
continue;
}
// Collapse double spaces into one and skip leading spaces.
// e.g. " Items Name " -> "Items Name"
if (c == ' ')
{
if (!lastWasSpace)
{
sb.Append(c);
lastWasSpace = true;
}
continue;
}
sb.Append(c);
lastWasSpace = false;
}
if (sb.Length > 0 && sb[^1] == ' ')
{
sb.Length--;
}
return sb.ToString();
@@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection;
using Rhino.PlugIns;
using Speckle.Connectors.Common;
using Speckle.Connectors.DUI;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.Rhino.DependencyInjection;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
@@ -50,6 +51,10 @@ public class SpeckleConnectorsRhinoPlugin : PlugIn
// but the Rhino connector has `.rhp` as it is extension.
Container = services.BuildServiceProvider();
// FORCE INITIALIZATION RhinoDocumentStore to register event handlers for BeginOpenDocument and EndOpenDocument
// this is needed when the user opens a Rhino file by double clicking the file,
// instead of opening a file in an already running Rhino instance
Container.GetRequiredService<DocumentModelStore>();
Container.UseDUI();
return LoadReturnCode.Success;
@@ -210,8 +210,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -221,13 +221,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -347,14 +347,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -380,7 +381,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"LibTessDotNet": {
@@ -430,12 +431,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -229,8 +229,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -240,13 +240,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -428,14 +428,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -461,7 +462,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"LibTessDotNet": {
@@ -511,12 +512,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -229,8 +229,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -240,13 +240,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -428,14 +428,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -461,7 +462,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"LibTessDotNet": {
@@ -511,12 +512,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -279,7 +279,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -308,11 +308,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -279,7 +279,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -308,11 +308,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -305,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -349,12 +350,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -230,14 +230,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -254,7 +255,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -298,12 +299,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -230,14 +230,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -254,7 +255,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -298,12 +299,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -279,7 +279,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -308,11 +308,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -157,8 +157,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -166,13 +166,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -228,7 +228,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -257,11 +257,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -288,7 +288,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -317,11 +317,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -288,7 +288,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -317,11 +317,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -288,7 +288,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -317,11 +317,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
}
}
@@ -166,8 +166,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -175,13 +175,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -239,14 +239,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -263,7 +264,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -307,12 +308,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -166,8 +166,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Data.Sqlite": "7.0.5",
@@ -175,13 +175,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -239,14 +239,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.dui.webview": {
@@ -263,7 +264,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -307,12 +308,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -171,8 +171,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -182,13 +182,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -281,14 +281,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -298,7 +299,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,12 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -180,8 +180,8 @@
},
"Speckle.Sdk": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "D04pCdleqLeDxthANCb8+X1xfEYr4+Q3GTuHtqOrMQeGHDAVPc5G3M0D6VYEUYbLYav0NBZ6tNuWO2Y/fqfWSw==",
"resolved": "3.12.0",
"contentHash": "LbKL7I5lFa2R8nSkY6FsePipSR3qQHr/6lxvCHX1Q/zyRxHYrcQXQo0X9gxuCjun/b6PThosdysOiYtRVaDZnA==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -191,13 +191,13 @@
"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": "3.12.0"
}
},
"Speckle.Sdk.Dependencies": {
"type": "Transitive",
"resolved": "3.11.1",
"contentHash": "u8lJ+ECslmVPsn4yOCg3hAzj3zh6r+gp2oQh8RDGn22NihIPOsMhBFvoBruL1QVhXdJcS4rI2J6VEAbdvL9FRg=="
"resolved": "3.12.0",
"contentHash": "L8eoBpEYIlJ593bAltaIAxcwbmwALSdL4+6ayjtzRlHX3bUfsGKd6jj/r0P4xX3H4tQFJScPn7u89oHitHaaPQ=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
@@ -282,14 +282,15 @@
"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": "[3.12.0, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
"Speckle.Connectors.Common": "[1.0.0, )",
"System.Threading.Tasks.Dataflow": "[10.0.2, )"
}
},
"speckle.connectors.logging": {
@@ -299,7 +300,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.11.1, )"
"Speckle.Objects": "[3.12.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -337,12 +338,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.11.1, )",
"resolved": "3.11.1",
"contentHash": "JUCY3bA6Pa+fa6wZV9uQ9mhLRihvICkF58nIr28Yi94j0th7wSg4l8WeThl3ubKVnHDQE5mdVffVlY1e5ZUkuQ==",
"requested": "[3.12.0, )",
"resolved": "3.12.0",
"contentHash": "IQ9dcPsBnm207TFrxGDAPlL3T+9JSkqxczClK9G67saYHjsMAowrh71GkqgsZGxk5x0dCnbAOnV4szj2c6gJ5A==",
"dependencies": {
"Speckle.Sdk": "3.11.1"
"Speckle.Sdk": "3.12.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "h1jjCvwBFPXfH4y8KeGXERA+D/oKWUwZ5zX8TXO3YSQRi7zWiNxhvc8GTgFFEW11yTvepjVugDxemtzNDMW7Qw=="
}
}
}
@@ -0,0 +1,8 @@
namespace Speckle.Converter.Navisworks.Constants;
public static class InstanceConstants
{
public const string GEOMETRY_ID_PREFIX = "geom_";
public const string DEFINITION_ID_PREFIX = "def_";
public const string INSTANCE_ID_PREFIX = "instance_";
}

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