Compare commits

...

178 Commits

Author SHA1 Message Date
Jedd Morgan 00d59913c2 fix(ci): Add Navisworks 2026 to the build consts (#742)
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
2025-04-08 16:22:26 +01:00
Oğuzhan Koral 373b0e5397 Merge pull request #741 from specklesystems/dev
Update dev into main
2025-04-08 17:47:36 +03:00
Jedd Morgan e9ebe65775 Reworded error message for DataObjects that have no displayValue (#718) 2025-04-08 13:58:23 +00:00
Claire Kuang 249fc40105 feat(rhino): receives properties as user strings (#726)
* adds receiving properties as user strings

* skips props that ends with noisy strings

---------

Co-authored-by: Dimitrie Stefanescu <didimitrie@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-04-08 13:44:55 +00:00
Jonathon Broughton a81261a0e3 feat(Navisworks): CNX-1582 - Add 2026 support (#731)
* Adds Navisworks 2026 connector

Introduces a new connector for Navisworks 2026, enabling Speckle to interact with the latest version of the software.

This includes project files, dependency configurations, and plugin manifest updates.

* Adds support for unreleased Navisworks version

Adds provisional support for a newer, unreleased version of Navisworks.

Uses a temporary workaround to handle the version number until the official SDK is available.

* Updates Speckle dependencies

Updates the Speckle.Objects, Speckle.Sdk, and Speckle.Sdk.Dependencies packages to version 3.1.8 in the Navisworks connector.

This ensures compatibility and incorporates the latest features and fixes from the Speckle ecosystem.

* Updates Navisworks 2026 support

Uses the correct enum value for the 2026 Navisworks version.

This ensures that the application correctly identifies and supports the
specified version when it becomes available in the SDK.

* Updates WebView2 and adds System.Reactive

Updates the WebView2 package to the latest version.

Adds the System.Reactive package.

* Also lock the converters dependency

* Fix local.sln

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
2025-04-08 13:36:15 +00:00
Björn Steinhagen 6e4894d3bc fix(revit): Enable view-based filtering for multiple linked model instances (#727)
* feat: poc for independant view returns for instance

- next commit will optimise unnecesarry / redundant for loops

* refactor: earlier exit in FindLinkInstanceForDocument

- early exit in FindLinkInstanceForDocument in no transform
- linq expression for matching transform hash
- some docs

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-04-08 13:14:39 +00:00
kekesidavid e4f1ef8564 Feat(rhino): send filter for layers (#728)
* rhino layers filter implemented

* removed commented out code

* Correct the id and add type as select

* Refresh send filters whenever layer has changed

---------

Co-authored-by: KatKatKateryna <89912278+KatKatKateryna@users.noreply.github.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
2025-04-08 08:43:22 +00:00
Dogukan Karatas 2cd7f4f905 applies scale factor (#738) 2025-04-08 07:58:47 +00:00
Claire Kuang c6d06fbda1 feat(rhino): add brep, extursion, subd support to data object to host conversion (#735)
* Update DataObjectConverter.cs

* Update DataObjectConverter.cs
2025-04-07 14:55:24 +00:00
Oğuzhan Koral 6337a9e220 Add type for send filter (#729) 2025-04-07 14:27:41 +00:00
Adam Hathcock 65f97b4f4a Update to SDK 3.1.8 (#734) 2025-04-07 11:15:05 +00:00
KatKatKateryna cf570342d2 feat (revit): receive Region as native FilledRegion (#696)
* regions with failed viewId

* render stuff in the first found suitable view

* use native or fallback conversion depending on the view

* better comments

* implement conditional conversion

* remove comment

* comment

* unload Root Host converter

* fix highlighting the model

* inject PlanView converter

* specify views in which receive is supported

* throw unsupported views in advance

* remove redundant check

* ViewManager added; View check is moved to the beginning of receive operation (to throw once and not for every object)

* simplify and remove unused

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-04-07 04:58:15 +08:00
KatKatKateryna 33e4008e4b fix autocad send region polycurve (#732) 2025-04-04 19:03:56 +08:00
KatKatKateryna bcefe3b4c4 feat (autocad): region and hatches conversions (#681)
* clean send (except closed circular arcs)

* split functions

* include inner loops for complex regions

* reorient only polycurves with arcs

* regions to host

* merge conflict

* substract regions on receive

* optimize

* add checks

* fix icurve, receive hatches

* hatch receive

* reduce dataObject conversions

* finally hatches are recorded in a database

* regrouped

* simplify

* rename

* send hatch (only the first)

* remove hatches for now

* comment

* fixed icurve converter and reference in DataObject converter

* reformat

* hatch to speckle

* hatch to host

* hatch receive works

* set solid pattern on receive

* send properly and throw if complex hacth

* calculate mesh area from region

* prevent Autocad crash by catching exceptions in the middle of transaction

* sending both polylines and curves for hatches

* boolean operation for sending hatches

* turned 2d Hatch curves into 3d - now Brep creation doesn't fail!

* circles handled

* construct both polyline and vertices in parallel

* handling splines on receive

* comments

* don't reverse proper segments

* basic comment fixes

* open block table for write more concise

* use top-level transaction

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-04-01 18:36:04 +08:00
Jedd Morgan 13f3bb8ae5 Merge pull request #723 from specklesystems/jrm/main-dev-merge
Main -> Dev
2025-03-28 14:49:47 +00:00
Jedd Morgan d31cb47a85 Merge branch 'dev' into jrm/main-dev-merge 2025-03-28 14:40:55 +00:00
Björn Steinhagen 378438f1bc fix(revit): respect view visibility in linked models when sending (#716)
* fix(revit): sening via views with correct visibility to linked models

* handle not null

* pass path name to function instead full doc

* refactor: move common code outside

* docs: commenting on known limitations

* refactor: preprocessor directive specific stuff back in place

* refactor: oversight on common code

* fix: method name

* docs: cleanup

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
2025-03-27 14:44:11 +03:00
Jedd Morgan b485a4ff6f Don't build everything when zero changes (#715)
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
2025-03-26 15:21:12 +00:00
Jedd Morgan 5697afc292 fix(ifc): Fixed regression with IFC Site geometry not being converted (#712)
* IFC spatial elements now attach geometry as separate data object

* removed unnecessary attribute

* Updated tester for faster testing
2025-03-26 14:57:50 +00:00
Adam Hathcock 07a681eda7 Avoid multiple enumeration issues when saving if we copy the list first (#713) 2025-03-26 13:14:10 +00:00
Adam Hathcock 4ec45d3cd5 Merge pull request #709 from specklesystems/dev
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
Bump sdk to 3.1.7 (#708)
2025-03-25 12:14:05 +00:00
Oğuzhan Koral 939c710bf2 Bump sdk to 3.1.7 (#708)
* Bump sdk to 3.1.7

* missing lock file changes

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
2025-03-25 12:05:00 +00:00
Jedd Morgan ac1345bbaf Merge pull request #703 from specklesystems/dev
Update dev into main
2025-03-25 11:54:03 +00:00
Jedd Morgan 95a7bdb81f Merge pull request #707 from specklesystems/main
Main to dev
2025-03-25 11:46:27 +00:00
Jedd Morgan b1a5824bcd Update pr.yml (#706) 2025-03-25 11:44:08 +00:00
Dimitrie Stefanescu 09f9b1ee51 Revit linked models (#699)
* Bjorn/cnx 1359 have a setting in UI whether include or not (#646)

* feat(revit): linked model settings

* docs: cache invalidation note

* Feat(revit): linked models POC (#656)

* cleanup on RefreshElementsIdsOnSender

* POC for multiple and copied linked models

* fix render materials for copied linked models

* comment

* comment

* split linked models with collections

* style: ci potential null on key

* style: not null

---------

Co-authored-by: Björn <steinhagen.bjoern@gmail.com>

* feat(revit): sending linked model poc round two (#657)

* Added IFC app name (#648)

* test: add tests for threadcontext (#651)

* add tests for threadcontext

* add test for extensions

* remove needed usage

* fix for looking for model store (#654)

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>

* test: Send Operation tests (#652)

* add tests for threadcontext

* add test for extensions

* remove needed usage

* move cancellation

* Only add send operation tests

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>

* chore (autocad/civil): add regen after receive (#650)

* regenerates doc

* moves regen to receive base binding

* Update AutocadReceiveBaseBinding.cs

* feat: linked model send responsive to ui

- current throw just a placeholder
- small variable name refactor

* fix: object reference not set to an instance of an object

* fix: display value extractor

* refactor: converterSettings as readonly field

* feat: warning in response to ui setting not enabled

* docs: todos etc.

* Revert "Merge branch 'dev' into bjorn/cnx-1360-get-linked-models-on-send-function-according-to-setting"

This reverts commit 7202058a98, reversing
changes made to 4bc9ec2352.

---------

Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* fix: transform needed to be inversed (#659)

* feat(revit): linked models send by category (#666)

* docs: notes on collection filtering

* feature: RevitCategoriesFilter with linked models too

poc

* docs: notes

* feat(revit): commit structure (#675)

* feat: collection structure switch

- poc
- if linked models, send nested
- if not linked, send flat

* docs: comments on updates

* docs: comment on exception swallowing

* fix: nullability

* refactor: linked model helper class and refactor (#682)

* fix: premature processing of linked models

- add early check for linked models setting
- skips expensive element collection for linked models when disabled
- add empty document contexts for linked models when disabled to maintain warning generation (HACK)
- improve code readability with clearer variable names and comments

* refactor: category ids outside of linked model processing

- inefficient to repeat for every document

* fix: improve separation of concerns for linked model handling

- extract linked model processing to a dedicated method
- add IsLinkedDocument flag to DocumentToConvert class
- move linked model warning generation to RevitRootObjectBuilder
- make RevitSendBinding responsible only for element collection

* refactor: dedicated LinkedModelHandler class for linked model processing

- extract linked model element collection logic to a separate class
- improve separation of concerns between flow control and element collection
- add clear documentation explaining the responsibility boundaries

* fix: duplicate if check still floating around

* docs: over-explaining myself

* Fix(revit): do not use converter settings in element unpacker (#687)

* fix resetting the selected object ids after collecting the elements

* Pass document to element unpacker for the sake of linked models

* fix: send by categories mode

---------

Co-authored-by: Björn <steinhagen.bjoern@gmail.com>

* fix(revit): handle multiple linked model instances with transform hashing (#688)

* feat: linked model transform caching in RevitRootObjectBuilder

Add transform-specific hashing to properly handle multiple instances of the same linked model. Uses transform properties to create a unique suffix for the applicationId, preventing cached objects from being incorrectly reused across different transform contexts.

* more comments

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>

* fix: handle null elements when unpacking linked model groups

- add null element check before GroupBy in ElementUnpacker to prevent NullReferenceException
- improve robustness when processing groups in linked models
- add documentation explaining linked model element handling throughout UnpackElements method
- edge case where group member elements might not resolve properly in linked contexts

* make linked model setting true by default

* Fix(revit): illegal attempt to modify document (#700)

* Run refresh object ids in revit task

* Proper not null

* await instead .result

* feat(revit): collection structure for multiple linked model instances  (#701)

* feat: suffix for instances of linked model

* Extract out GetIdFromDocumentToConvert

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>

* Correct receive default setting for linked models even if irrevelant

* Fix post conflict

* Cleanup the code

* Add comment

---------

Co-authored-by: Björn Steinhagen <steinhagen.bjoern@gmail.com>
Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-25 11:02:29 +00:00
KatKatKateryna 1a687fb188 ignore helper objects on selection (#689) 2025-03-25 00:02:14 +08:00
Dimitrie Stefanescu 30e050fff2 Merge pull request #698 from specklesystems/dimitrie/cnx-614-rhino-8-to-rhino-8-breps-not-working
fix: filter out elems with null geometry
2025-03-24 12:37:57 +00:00
Dimitrie Stefanescu 30ab3b108e fix: filter out elems with null geometry
this is a blind fix: works on bilal's computer, i could not reproduce
2025-03-24 12:29:33 +00:00
Adam Hathcock 1f3ac7a5ad Exclude library assets for all host applications for connectors/converters (#697)
* Exclude runtime assets from autocad 2022-2025

* add exclude to navisworks too

* exclude from remaining csprojs
2025-03-24 11:02:07 +00:00
KatKatKateryna 33e515efb6 feat(rhino): sending region display values as meshes (#685)
* send meshes

* comment

* refactor displayMeshExtractor

* comment

* error message

* comments

* Update HatchToSpeckleConverter.cs

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-22 09:21:15 +00:00
jhdempsey86 4a5c91231d Caught error with SpiralDirection (#692)
Caught error with SpiralDirection

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-21 09:04:41 +00:00
KatKatKateryna 97a8df93d9 Arcgis send regions (#678)
* send regions

* send meshes

* comment

* typo

* adjust jsons

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-19 23:09:55 +08:00
Adam Hathcock 0106befa7d Caches visibility for the lifetime of the send (#672)
* Add selection progress and try/finally for exceptions

* format

* Caches visibility for the lifetime of the send

* clean up
2025-03-18 08:37:46 +00:00
KatKatKateryna ef87d5838b Rhino region conversions (#643)
* rhino hatch; autocad regions

* rhino: attempting to extract mesh

* stick to curves

* POC sending hatches

* receive region

* add tolerance

* change displayValue to curves

* revert autocad changes

* switch to curveConverter, add bbox

* lock files

* remove unused converter

* Revert "lock files"

This reverts commit 9ff42c00fe.

* comment

* remove checks, fix displayValue

* address comments

* remove displayValue

* bbox not required

* update nuget

* Revert "update nuget"

This reverts commit 28e6c30b2c.

* upgraded nuget

* convert Regions from DataObjects on Receive

* small fixes

* check result hatches

* json update

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-17 17:16:10 +00:00
Oğuzhan Koral 295162127a Merge pull request #684 from specklesystems/dev
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
Merge dev into main
2025-03-17 17:41:55 +03:00
jhdempsey86 6d336fbac4 fix(Civil3D): Update CorridorDisplayValueExtractor.cs to fix PropertySetDefinitionName error (#669)
* Update CorridorDisplayValueExtractor.cs

For unknown reasons, sometimes trying to get the PropertySetDefinitionName throws an exception.
Updated to catch this, ignore that propery set, and move to the next one. It is never the "Corridor Identity" property set that has this issue, so there should be no missing data.

* .

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-17 14:04:36 +00:00
Adam Hathcock 6b2078fadb (feat/fix) Navisworks: Add selection progress and try/finally for exceptions (#671)
* Add selection progress and try/finally for exceptions

* format

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-03-17 13:53:08 +00:00
Adam Hathcock bfd465449a Bump SDK to 3.1.4 (#683) 2025-03-17 13:00:08 +00:00
Adam Hathcock a9a4893bdb test: Send/Receive Progress tests (#662)
* add tests for receive progress

* add send progress tests

* fmt
2025-03-17 15:09:04 +03:00
Adam Hathcock 21066eebbb Add tests for send caching (#660) 2025-03-17 11:51:07 +00:00
Claire Kuang 9d5ff85cff feat(revit): adds level extractor and levels to revit objects (#679)
* adds level extractor and levels to revit objects

* changes return to null when no level

* bumps sdk
2025-03-17 14:43:30 +03:00
Adam Hathcock 64befa758d fix(Revit) improving revit selection perf (#623)
* Revit allocation improvements

* fmt

* Don't use concurrent bag
2025-03-17 14:31:44 +03:00
Adam Hathcock d9a0cbb4bf Build everything always, only zip affected groups (#677)
* Build everything always, only zip affected groups

* get the dependencies right

* try dependencies again

* can't use affected in enums
2025-03-17 11:02:44 +00:00
Oğuzhan Koral 50807b1e88 Feat(accounts): Add remove account to binding (#680)
* Add remove account to binding

* Remove models as batch
2025-03-15 21:29:36 +03:00
Oğuzhan Koral 7780071073 Fix(autocad): Remove circular dependency (#676)
* Remove circular dependency

* removes polycurve to spline raw converter

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-14 20:02:45 +03:00
Jedd Morgan be63b4ab55 public release on tag (#674)
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
* public release on tag

* and nuget
2025-03-14 13:36:32 +00:00
Jedd Morgan 63c5bb26cb Added quotes escape in build (#673) 2025-03-14 13:29:57 +00:00
Adam Hathcock f7a1d98d8a feat: building/publish only affected projects (#665)
.NET Build and Publish / build-windows (push) Has been cancelled
.NET Build and Publish / build-linux (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled
* Add affected usage with tag math

* use this branch as a test branch

* adjust test

* fix github action

* build refactor to get affected work

* Lazy affected

* put if statement on job

* add conditions around build and publish for linux

* affected tests and small refactor

* fmt

* verbose

* full checkout

* more testing and made things more clear

* adjust installer test branch

* add comments

* use zip on release

* detect main release

* use right trigger for release

* fix build

* maybe fix if statement...version env var don't work

* use current branch, not target branch

* test installer should be stored

* write to github action env vars

* use the env var correctly

* format

* set the output version as before

---------

Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
2025-03-14 12:37:49 +00:00
Jedd Morgan a14de5bdde File import service now creates branch if one doesn't already exist (#670) 2025-03-14 12:03:11 +00:00
Jedd Morgan a89407ae3c Ignore null properties and empty psets (#668) 2025-03-12 17:51:57 +00:00
Jedd Morgan a3285a4f67 Use 3 instead of 0 for cardinality indicator of triangle faces (#667) 2025-03-12 14:28:49 +00:00
Jedd Morgan ae4b1b0ab5 Merge pull request #655 from specklesystems/jrm/ifc-collections-data-objects
Send IfcProjects, IfcSites, IfcBuildings, and IfcStoreys as Collections
2025-03-12 08:32:30 +00:00
Jedd Morgan ed9d81d206 Better exception messages for breps that fail to meshify (#634) 2025-03-11 16:08:05 +00:00
Adam Hathcock a2fc846613 Remove stack usage to hash (#663) 2025-03-11 12:26:38 +00:00
Adam Hathcock 184953f5f0 Update to SDK 3.1.1 (#658) 2025-03-10 12:52:44 +03:00
Adam Hathcock d71b36c2f7 Sped up Rhino receive hot spots (#596)
* Sped up Rhino receive hot spots

* formatting

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-09 17:42:22 +00:00
Claire Kuang f152cff619 chore (autocad/civil): add regen after receive (#650)
* regenerates doc

* moves regen to receive base binding

* Update AutocadReceiveBaseBinding.cs
2025-03-07 14:33:15 +00:00
Adam Hathcock 4aed602089 test: Send Operation tests (#652)
* add tests for threadcontext

* add test for extensions

* remove needed usage

* move cancellation

* Only add send operation tests

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-03-07 16:44:21 +03:00
Adam Hathcock 63c4d31467 fix for looking for model store (#654)
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-03-07 13:32:28 +00:00
Adam Hathcock b807be35ff test: add tests for threadcontext (#651)
* add tests for threadcontext

* add test for extensions

* remove needed usage
2025-03-07 16:27:58 +03:00
Jedd Morgan 32ea041c5e Added IFC app name (#648) 2025-03-06 16:22:47 +00:00
Adam Hathcock 950c8373d9 fix: Autocad perf - Adds early exit to idle manager to shortcut call check (#609)
* Refactors idle manager to shortcut call check

* fix tests

* Match the id of idle action with the function name

it is more safe with this way bc we might accidentially skip some deferred actions if we use class name

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
2025-03-06 15:10:24 +03:00
Adam Hathcock 9d5faa92e8 feat: Perf testing helpers for Jetbrains (#635)
* add perf project

* formatting

* add perf project to local
2025-03-06 11:04:14 +00:00
KatKatKateryna fd88fc2eeb stop color unpacking (#638)
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-03-05 20:31:02 +00:00
Jonathon Broughton 9d2ae1ca55 Fix(Navisworks): CNX-1329 - Fix Saved Sets Filter to Properly Handle Nested Folders (#631)
* Improve error messages for object conversion

- Updated exception messages to be more informative based on visibility settings.
- Simplified the logic for throwing exceptions when no model items are found.

* Refactor saved sets filter logic

- Introduced new methods for collecting saved sets and building hierarchical names.
- Simplified selection set resolution with a more concise approach.
- Updated initialisation of items to use arrays instead of lists.
- Improved error handling when resolving GUIDs for selection sets.
2025-03-05 20:25:35 +00:00
Claire Kuang 670a562d48 feat(civil3d): add civil3d receive (#644)
* adds receive to civil3d

* Update AutocadReceiveBaseBinding.cs

* remove usings

* Update Civil3dReceiveBinding.cs
2025-03-05 15:08:46 +00:00
Adam Hathcock e6d983302c Do some stack work to speed up Rhino hotspots (#590)
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-03-05 14:34:39 +00:00
Jedd Morgan fe5b77e766 Nuget publish only on release (#647) 2025-03-05 12:46:30 +00:00
Björn Steinhagen 663fe445bf Revert "feat(revit): linked model settings (#641)" (#645)
This reverts commit 74d2d2860c.
2025-03-05 15:03:59 +03:00
Björn Steinhagen 74d2d2860c feat(revit): linked model settings (#641)
* feat(revit): linked model settings

* docs: cache invalidation note
2025-03-04 16:35:22 +01:00
Jedd Morgan 2e405b2f28 Don't skip server from IFC importer (#640) 2025-03-04 13:54:50 +00:00
Adam Hathcock 331c631b35 fix: Update SDK to 276 (#637)
* Update SDK to 247

* update to SDK 276
2025-03-04 08:44:23 +00:00
Adam Hathcock ddd6039722 Change targets of common assemblies from NET Standard to platform specific. (#597)
* Update SDK to 257

* remove netstandard2 target from (most) things.  Target net48, net6, and net8

* update to SDK 267

* adjust ifc tester

* Update to SDK 268

* merge fixes
2025-02-27 15:46:15 +00:00
Jedd Morgan 835e3ba005 No files, no success (#608) 2025-02-27 15:04:35 +00:00
Jedd Morgan af548ba626 Fixed duplicate elements (#604)
Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
2025-02-27 14:08:10 +00:00
Jedd Morgan 3ff40757e0 Corrected tekla structures slug (#632) 2025-02-27 10:52:55 +00:00
Claire Kuang a8571fdd61 detaches featurelines so they are queryable (#627) 2025-02-27 13:41:59 +03:00
Oğuzhan Koral f8a6d27c6d revert revit task back for highlight view (#629) 2025-02-26 18:29:56 +00:00
Dogukan Karatas 4e1604f77e updates after build (#628) 2025-02-26 18:17:44 +00:00
Adam Hathcock 00af4ad338 fix: Use a concurrent dictionary to cache types since the converter is effectively a singleton (#624)
* Use a concurrent dictionary to cache types since the converter is effectively a singleton

* Don't modify the collection in the getter

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-26 20:34:06 +03:00
Jonathon Broughton 7fed9e03e9 enhancement(Navisworks): CNX-972 - less aggressive object merging (#622)
* Remove unused path constants and update namespace

Deleted an unnecessary file for path constants. Updated the namespace in the remaining file to better reflect its purpose and added a new constant for material separation.

* Remove unused send filters

- Deleted the send filters list and related parameters from the constructor.
- Cleaned up code to streamline the binding process.
- Updated comments for clarity on behaviour expectations.

* Update Navisworks object creation logic

- Added extraction of parent path from the group key.
- Changed applicationId to use the parent path instead of the group key.

* Add path cleaning method and simplify geometry resolution

- Introduced `GetCleanPath` to remove material signatures from paths.
- Updated `ResolveIndexPathToModelItem` to use the new path cleaning method.
- Simplified `ResolveGeometryLeafNodes` to use expression-bodied member syntax.

* Improve geometry node grouping logic

- Added material signature handling for merging nodes.
- Enhanced grouping to only include anonymous geometry nodes.
- Introduced a method to create material signatures based on properties.
- Updated the parent path extraction from composite keys.

* Added an extendable signature generation pattern

- Simplified the grouping of anonymous geometry nodes.
- Replaced material signature generation with a new method for better clarity.
- Added functionality to include additional material properties in the signature.
- Improved hash generation for consistent property representation.

* Update material separator in path constants

Changed the material separator from "::MATERIAL::" to "::". This simplifies the constant and may improve compatibility with other components.

* Changed how the parent path is derived from the group key.

- Introduced a cleaner method to get the parent path.
- Updated applicationId to use the full composite key for uniqueness.

* Updated node path retrieval to use a more concise method.

- Simplified the creation of `mergedIds` by using a single variable for group keys.
- Removed unnecessary comments and whitespace for cleaner code.

* Add missing import for Navisworks constants

Included the Navisworks constants import to ensure proper functionality.

* Replaced custom hash function with MD5, suppressing related warnings.
2025-02-26 14:25:09 +00:00
KatKatKateryna e9c2c85a7f Arcgis detailed progress and cancellation (#614)
* pass cancellation token to individual features

* move count to a separate function

* remove per-layer progress report

* fix count

* reorder

* count layers only once

* move count to "unpacking selection" activityFactory

* remove outdated comment
2025-02-26 18:16:00 +08:00
Jonathon Broughton 82c7877425 Refine property handling logic (#621)
- Excluded "Transform" category from processing.
- Added a list of excluded properties: "Hidden", "Required", "Internal_Type".
- Improved handling for the "Item" category to add non-excluded properties directly to root level.
- Ensured only non-empty property dictionaries are processed.
2025-02-25 14:52:48 +00:00
Jonathon Broughton 2338be46c2 feat(Navisworks): CNX-1065 Enable optional full hierarchy mode (#616)
* Add preserve model hierarchy feature

- Introduced PreserveModelHierarchySetting to manage hierarchy preservation.
- Updated NavisworksSendBinding to include new setting.
- Added HierarchyBuilder class for future functionality.
- Enhanced ToSpeckleSettingsManagerNavisworks with caching for the new setting.
- Modified conversion settings to support model hierarchy preservation.

* Add Navisworks hierarchy builder class

Implemented a new class to rebuild the Navisworks document hierarchy from geometry leaves, maintaining parent-child relationships. Key updates include:
- Added constructor and private fields for managing geometry and conversion services.
- Developed a method to build the hierarchical structure of Speckle objects.
- Implemented logic for climbing up the document structure to resolve missing ancestors.
- Introduced methods for converting model items and pruning empty collections.

* Refactor hierarchy handling in object builder

- Added support for preserving model hierarchy.
- Introduced a new hierarchy builder for nested structures.
- Adjusted flow to handle flat mode when hierarchy is not needed.

* Refactor model item conversion logic

- Simplified the conversion method for Navisworks ModelItem.
- Consolidated geometry and non-geometry object creation into single methods.
- Added parameter for property handler to streamline property retrieval.
- Improved clarity by reducing redundancy in code structure.

* Refactor hierarchy builder for cleaner conversion

- Replaced custom conversion method with a direct call to the converter.
- Removed redundant code related to converting ModelItem to Speckle Collection.
- Streamlined the process of handling model items in the hierarchy.

* Remove unnecessary comment in hierarchy builder

Cleaned up the code by deleting a redundant comment about resolving ModelItem from a path string. This helps improve readability without losing any functionality.
2025-02-25 14:40:52 +00:00
Adam Hathcock 8f72eb35d3 fix(Revit): Catch exceptions and reprocess them around RevitTask (#617)
* Catch exceptions and reprocess them around RevitTask

* Added SpeckleRevitTaskException to know when exceptions are jumping over revit task to handle the UI

* add comments

* Add fatch when

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-25 16:54:10 +03:00
Oğuzhan Koral a3f7069c37 Feat(navis): send filter dropdown navis poc (#619)
* Add Saved Sets Filter

* formatting

* !!!

* fml

* Unclear why formatting rules are not being applied

* !!!

* !

* fixed?

* Add new filter for saved sets in Navisworks

- Included a new file for NavisworksSavedSetsFilter.

* POC ISendFilterSelect

* Align saved sets filtler with ISendFilterSelect

* No DI for send filters

* reverse condition

* Remove ISendFilterSelect from revit views

* Add notes

* Improve object selection error handling

- Updated logic for retrieving model items to use selected paths.
- Enhanced error messages based on visibility settings of objects.
- Simplified null checks for selected items in filters.

---------

Co-authored-by: Jonathon Broughton <jonathon@stardotbmp.com>
2025-02-25 12:56:38 +00:00
Dogukan Karatas 3842e109b6 feat(tekla): speckle ribbon (#612)
* adds a ribbon

* updates speckle.svg

* updates logo

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-25 08:14:17 +01:00
Claire Kuang 4ae2106608 fixes pointcloud plane bug (#615) 2025-02-21 17:30:25 +00:00
Claire Kuang 3656587081 fix(autocad/Rhino): add support for receiving any convertible geometry in dataobject display values (#599)
* adds additional geometry conversions to autocad and rhino

* removes unused converters

* fixes zip bug

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-21 19:17:23 +03:00
Claire Kuang b315cebf3a fix(revit): missing directshape geo and other geometry fixes (#611)
* Claire/revit areas curves fix (#610)

* fixes display values for get_geometry method, and changes modelcurves to be sent as revitobject

also removes `level` prop in objects and adds the units and elevation to the level collection instead

* Update Speckle.Converters.RevitShared.projitems

* removes top level pointcloud converter

* Update RevitElementTopLevelConverterToSpeckle.cs
2025-02-21 18:18:07 +03:00
Oğuzhan Koral fb18466aba Source application should be app name and version (#613) 2025-02-20 21:30:23 +03:00
Jonathon Broughton b721c2fb31 fix(Navisworks): CNX-1299 Navisworks properties cleanup and NavisworksObject adoption (#607)
* Update property handling interface

Changed method to retrieve properties from Navisworks model items. Updated the method signature for clarity and improved functionality.

* Add property retrieval method to handler

Implemented a new method for getting properties from model items. It processes property sets and returns a dictionary of category values, enhancing the functionality of the property handler.

* Fix namespace formatting and improve property handling

- Cleaned up the namespace declaration.
- Added a check to ensure properties are a dictionary before processing.
- Streamlined property validation logic for better clarity.

* Simplified the `AddModelProperties` method signature by reducing parameters.

* Refactor property handling in base class

- Added a new method to retrieve properties from model items.
- Simplified the structure of processed property sets by removing nested dictionaries.

* Add hierarchical property retrieval method

Implemented a new method to get properties from model items.
- Introduced `GetProperties` to collect and filter hierarchical properties.
- Enhanced data handling with improved dictionary management for properties.

* Fix namespace formatting issues

Updated the namespace declarations in property handler files to ensure proper formatting.

* Refactor model item conversion logic

- Updated the method for converting Navisworks ModelItems.
- Simplified the creation of non-geometry objects.
- Removed unnecessary property handling code.
- Enhanced clarity by restructuring return values.

* Refactor model item conversion logic

- Simplified the conversion method for model items.
- Added a new method to handle geometry objects.
- Introduced property handling based on user settings.
- Improved clarity and maintainability of the code.

* Refactor geometry property handling

- Updated comments to clarify property merging rules.
- Removed unused methods for creating geometry and non-geometry objects.
- Simplified code structure for better readability.

* Refactor conversion method for brevity

Streamlined the `Convert` method to use an expression-bodied member. Removed unnecessary null check block and simplified the logic for better readability.

* Fix import statement formatting

Updated the import statement for consistency by removing an invisible character.

* Add class properties handling to property dictionaries

- Integrated class properties extraction into both property handlers.
- Updated logic to add or update entries in the property dictionaries based on extracted class properties.
- Ensured null checks for class properties before processing.

* Refactor property handling methods

- Removed the AssignPropertySets method for simplification.
- Streamlined GetProperties to directly return processed property sets.
- Cleaned up unnecessary checks and loops for better readability.

* Add ClassPropertiesExtractor to service registration

- Registered a new ClassPropertiesExtractor for better property handling.
- Kept existing property handlers and settings management intact.

* Refactor HierarchicalPropertyHandler for clarity

- Removed redundant property assignment logic.
- Integrated class properties extraction directly into the main method.
- Simplified error handling by eliminating unnecessary checks.

* Refactor property assignment methods

Removed the AssignProperties and AssignClassProperties methods to streamline property handling. Kept the abstract method for getting properties while maintaining the overall structure of the class.

* Refactor ClassPropertiesExtractor to instance method

Changed ClassPropertiesExtractor from static to instance class. Updated GetClassProperties method to be an instance method, allowing for better flexibility and potential state management in the future.
2025-02-20 09:52:30 +00:00
Claire Kuang 76aa953210 moves class properties to top level of properties dictionary (#606) 2025-02-19 17:05:38 +00:00
Jedd Morgan 52d15dc827 add support for vertex normals in rhino (#605) 2025-02-19 12:11:06 +00:00
Björn Steinhagen dbbc4f7fcd fix(revit): use correct unit-specific scaling for material quantities (#602) 2025-02-19 08:21:19 +00:00
Oğuzhan Koral 85b4a88407 Merge pull request #600 from specklesystems/dogukan/tekla-runtime-fix
fix(tekla): remove runtime identifier
2025-02-19 03:04:59 +03:00
Dogukan Karatas 65a2e674bb removes runtime identifier 2025-02-19 00:58:30 +01:00
Dimitrie Stefanescu 9a84e4469e Merge pull request #598 from specklesystems/dimitrie/cnx-1186-revit-rooms-not-visible-in-the-viewer
feat: moving back to translucid rooms.
2025-02-18 17:07:42 +00:00
Dimitrie Stefanescu b8a49d5fed feat: moving back to translucid rooms.
now people will be angry they cannot select furniture in some cases.
2025-02-18 17:01:36 +00:00
Dogukan Karatas 12dcf471d3 fix (tekla): updates the vebview2 dependency (#562)
* updates webview dependencies

* updates csproj

---------

Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-18 19:08:26 +03:00
Claire Kuang 42e45affbd refactor(civil3d): properties cleanup (#588)
* Cleans civil3d props

also removes catchment and network proxies. this info is now captured in assignments

* Update ClassPropertiesExtractor.cs

* some bug fixes

* Update PartDataExtractor.cs

* adds parcel areas and excludes labels
2025-02-18 16:38:20 +01:00
Dimitrie Stefanescu fcce4e3f63 feat: adds support for formulas in user strings (#594)
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-02-18 15:15:08 +00:00
Claire Kuang 370c5b2064 adds area boundary segments to display value of area (#592) 2025-02-18 15:06:54 +00:00
Claire Kuang 39dfb0f426 removes assignment of bearing to z (#593) 2025-02-18 14:53:58 +00:00
Adam Hathcock 1c62fbbe99 Update SDK to 268 (#567)
* Update SDK to 257

* update to SDK 267

* adjust ifc tester

* Update to SDK 268

* update SDK version to 270
2025-02-18 10:14:55 +00:00
Jedd Morgan 6f03aa8678 Jedd's IFC improvements (#510)
* ifc safe

* reverted LibraryImport as it would need more testing

* IFC app ids
2025-02-17 16:35:26 +00:00
Björn Steinhagen f882b0f5bd fix(etabs): ensure csi operations run on main thread to prevent etabs exceptions (#589)
* fix: ensure operations run on main thread to prevent etabsexceptions

* pr comments

* fix: ensure consistent exception handler usage in selection binding
2025-02-17 11:53:21 +01:00
Björn Steinhagen 4ffe9fe4b0 feat(revit): extract material type enum on structural asset (#586)
* feat: material type distinction

* refactor: mixed concerns

Some structural asset stuff was in the MaterialQuantitiesToSpeckle.cs

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-02-14 11:24:24 +00:00
Claire Kuang d50b095683 refactor(revit): properties cleanup (#581)
* clean properties in revit

also adds properties to non-dataobjects and changes grids to have a curve display value after removing curve prop on grids

* removes number from room since this is included in params

* refactors supported categories and throws when all selected objects are unsupported categories

* stupid typos

---------

Co-authored-by: Dimitrie Stefanescu <didimitrie@gmail.com>
2025-02-14 09:49:51 +00:00
Dimitrie Stefanescu daebbbef1c Merge pull request #587 from specklesystems/adam/cnx-1238-rhino-8-restarting-during-an-operation-throws-with-key-not
fix: (cancellation manager should return cancelled token instead of throwing exception)
2025-02-13 12:18:05 +00:00
Adam Hathcock b43631e46b fix and add tests 2025-02-13 10:54:49 +00:00
Adam Hathcock ea9768b1f2 check tokens more aggressively when doing operations 2025-02-13 10:50:12 +00:00
Adam Hathcock 2756555eb9 Cancellation manager shouldn't throw on get 2025-02-13 10:49:15 +00:00
Adam Hathcock 1f1422900e Adam/cnx 1217 arcgis toc not unblocked after cancellation during (#580)
* Send with QueuedTask

* more QueuedTask usage and format

* Fix highlight/selection changes
2025-02-13 09:32:10 +00:00
Dimitrie Stefanescu 45a76eada4 Dimitrie/cnx 1240 receiving materials in rhino 8 broken for layers (#585)
* reverts previous fix

* fix: applies the minimal fix

* chore: adds comment for future

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-02-12 18:54:16 +00:00
Björn Steinhagen 0e65b6aa57 feat(etabs): geometric properties through new cDatabaseTable extractor (#584)
* feature: database table extractor

* feature: frame length extraction

* feat: shell area extraction

* feat: frame length extraction

* feat: shell area extraction

* docs: cleaned up object extractors

* refactor: extensible database table extraction

* flexible indexing (can be defined by user, defaults to typical use-case of "UniqueName")
* better variable naming and more descriptive (better than csi's api)
* some fail safes e.g. when forgetting to put indexingColumn in array of columns to fetch

* refactor: using DatabaseTableExtractor for material name lookup

* lookup for material name of a shell can use the database table extractor and simplifies EtabsShellPropertiesExtractor a lot

* fix: openings shouldn't look for material assignments

Frustrating way Etabs handles openings - they shouldn't be a SHELL. Anyways. Rant over

* refactor: database table extractor handles dictionary lookups
2025-02-12 18:43:44 +00:00
Dimitrie Stefanescu 5c2c0ff303 Merge pull request #582 from specklesystems/dimitrie/cnx-1239-rhino-fix-the-documentisinit-post-copy-paste
Rhino: fixes change detection post copy paste events
2025-02-12 15:00:32 +00:00
Dimitrie Stefanescu a6fd4547ea feat: adds previous dix 2025-02-12 14:38:47 +00:00
Adam Hathcock 0d27eadfeb add deep clean local docs (#579) 2025-02-11 14:06:12 +00:00
Dimitrie Stefanescu 0b26e021cd fix: prevents fatal crash on old model cards (#548)
* fix: prevents fatal crash on old model cards

* fix: formatting

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-10 20:33:42 +03:00
Claire Kuang a0d5e3b2d4 fix(Autocad): missing solids on receive (#576)
* Fix threading bug

* untangle revit

* adds brepx converter

also changes groups to not be created if list conversion returns 1 or less objects

* revert rhino

* revert autocad

* revert rest

* remove event agg and rhino implementation

* remove event aggr from revit

* remove event aggr from autocad and civil

* remove event aggr tests

* remove event aggr from tekla

* Remove event aggr for navis

* remove event aggr from csi etabs

* remove event aggr for arcgis

* remove remaining pieces

* adds brep converter

* push autocad to run operations on main thread

* adds teklaidlemanager

* bring navis idle manager back

* run send on main

* adds extrusionx and subdx support

* adjusts converter return types to fallback case

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: Dogukan Karatas <karatasdogukan@gmail.com>
2025-02-10 20:25:24 +03:00
Claire Kuang 1ebc32f07e feat(autocad/rhino): add name and properties (#556)
* adds name and properties to rhino and autocad

* move properties extractor to converter and updates attributes event listener

* moves name and properties back to connector because abstract rhinoobjectconverter doesn't capture all top level converters

* Update RhinoObjectToSpeckleTopLevelConverter.cs

* Update ServiceRegistration.cs

* adds explicit conditions for object attribute change event

* feat: simplifies rhino implementation

* fix: comments out acad usage as we can't test it

* fix: civil services (removal of acad props extraction)

* Update RhinoSendBinding.cs

* Update PropertiesExtractor.cs

---------

Co-authored-by: Dimitrie Stefanescu <didimitrie@gmail.com>
2025-02-10 19:59:46 +03:00
Claire Kuang a3b1cd52ad fix(rhino): bakes render materials on receive instead of materials (#564)
* switches to baking render materials instead of materials

* makes sure to purge render materials before receive
2025-02-10 15:17:14 +00:00
Dogukan Karatas c7cfb8c6c7 feature (tekla): extract user-defined attributes (#566)
* adds uda's to the properties

* reformatted

* updates entry structure

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-02-10 15:06:34 +00:00
Oğuzhan Koral 93246157c7 Fix: threading on browser bridge + remove event aggr (#574)
* Fix threading bug

* untangle revit

* revert rhino

* revert autocad

* revert rest

* remove event agg and rhino implementation

* remove event aggr from revit

* remove event aggr from autocad and civil

* remove event aggr tests

* remove event aggr from tekla

* Remove event aggr for navis

* remove event aggr from csi etabs

* remove event aggr for arcgis

* remove remaining pieces

* push autocad to run operations on main thread

* adds teklaidlemanager

* bring navis idle manager back

* run send on main

* remove unused function

---------

Co-authored-by: Dogukan Karatas <karatasdogukan@gmail.com>
2025-02-10 17:50:26 +03:00
Oğuzhan Koral 18499bdc69 Chore: update code ownership (#575)
* update code ownership

* fix typo for claire :)
2025-02-07 10:35:08 +00:00
Jedd Morgan feaae9e5ee Event Aggregator Deadlock Fix (#568)
* deadlock fix

* Changed list construction

* typo
2025-02-06 12:07:23 +00:00
Björn Steinhagen 4ee48bdfae feat(revit): add density to material quantities (#558)
* feat: thermal and structural asset extraction initial scope

* feat: thermal and structural asset extraction poc

* feat: property set extraction (1/3)

* feat: property set extraction (2/3)

- scaling internal units can't be so complicated?
- to discuss :(

* feat: property set extraction (3/3)

- Simplification to just extract density from structural asset (if present)
- Just one property extraction => no need to create material proxy
- Scaled from internal units to match scaling to model units which occurs on other material quantities

* feat: display parameter unit with associated quantities

* feat: added name of structuralAsset to material quantities

* fix: safe string conversions

* fix: explicitly returning cached value

* fix: validation before dict insertion

* style: dict access

* fix: nullability

---------

Co-authored-by: KatKatKateryna <89912278+KatKatKateryna@users.noreply.github.com>
2025-02-06 08:49:28 +01:00
Adam Hathcock 1c11e4a6c5 Add Local to relevant csprojs and use local config in Local sln (#563) 2025-02-05 15:41:45 +00:00
Dimitrie Stefanescu 413c1ad562 Merge pull request #565 from specklesystems/dimitrie/cnx-1180-v3-send-stuck-sending-forever-for-curtain-walls-and-model
fix: ensures we don't go crazy on null categories
2025-02-05 15:51:34 +01:00
Dimitrie Stefanescu d9adca0154 fix: make ci happy - push and see 2025-02-05 14:43:40 +00:00
Dimitrie Stefanescu 74870a6a8e fix: formatting 2025-02-05 13:25:25 +00:00
Dimitrie Stefanescu cba391081c fix: ensures we don't go crazy on null categories 2025-02-05 13:18:13 +00:00
Dimitrie Stefanescu ccc3187e78 fix(rhino): only create groups if needed (#561) 2025-02-04 17:33:58 +00:00
Adam Hathcock 1e8ad93dbe Update to SDK 255 (#557) 2025-02-04 15:58:55 +00:00
kekesidavid a2b01c0bbb switched from trianglenet to libtessdotnet (#559) 2025-02-04 16:09:47 +01:00
kekesidavid a70a894089 extrude simple holed surfaces in tekla (#550)
* extrude simple holed surfaces in tekla

* typo

* units fix
2025-02-04 15:33:30 +01:00
Dimitrie Stefanescu 65baf4221d Merge pull request #555 from specklesystems/fix-clean
Add deep-clean-local.
2025-02-04 12:25:45 +01:00
Adam Hathcock 2a4b5f7218 add build and restore functions with output 2025-02-04 10:00:17 +00:00
Adam Hathcock cfa723d164 Add deep-clean-local. Be more explicit about what solution is being cleaned 2025-02-04 09:52:50 +00:00
Adam Hathcock 143da829d8 Revert to SDK 251 to avoid potential issues (#554) 2025-02-04 09:23:02 +00:00
Adam Hathcock a8a98fe824 Update to SDK 254 (#551) 2025-02-03 17:54:13 +00:00
Adam Hathcock efadfdc479 Update to SDK 252 (#546) 2025-02-03 14:08:53 +00:00
Dimitrie Stefanescu f7ee2555f4 Merge pull request #547 from specklesystems/dimitrie/cnx-1086-stuck-at-publish-when-trying-to-publish-not-supported-array
fix/feat: adds support for arrays (radial and linear) in revit
2025-02-03 14:42:34 +01:00
Dimitrie Stefanescu 286a1c070c Merge branch 'dev' into dimitrie/cnx-1086-stuck-at-publish-when-trying-to-publish-not-supported-array 2025-02-03 14:34:48 +01:00
Claire Kuang 4af90950ff fix(rhino): colors and materials are preserved on empty layers (#542)
* Update RhinoLayerBaker.cs

* fixes color and material assignment to layers with no objects

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-03 13:14:21 +00:00
Dimitrie Stefanescu a23f9c1ffa Merge remote-tracking branch 'origin/dimitrie/cnx-1086-stuck-at-publish-when-trying-to-publish-not-supported-array' into dimitrie/cnx-1086-stuck-at-publish-when-trying-to-publish-not-supported-array 2025-02-03 12:57:53 +00:00
Dimitrie Stefanescu 64dfa44692 fix: formatting 2025-02-03 12:57:44 +00:00
Dimitrie Stefanescu 573c63fa62 Merge branch 'dev' into dimitrie/cnx-1086-stuck-at-publish-when-trying-to-publish-not-supported-array 2025-02-03 13:57:05 +01:00
Dimitrie Stefanescu 52aeb36f19 fix/feat: adds support for arrays (radial and linear) in revit 2025-02-03 12:49:47 +00:00
Jedd Morgan 593f95daf6 Fix codecov reports (#545) 2025-02-03 12:43:57 +00:00
Adam Hathcock e5e02bdab1 Cancellationmanager revamp (#527)
* rhino and arc fix usage

* fix registration

* fix the rest

* use interface

* don't use rhino layer if there is no name

* formatting

* add tests

* formatting

* add to local and move

* Update OTEL to remove grpc dependency

* Fix deprecated method

* really fixed with no incremental builds for tests

* Fix references and lock

* Update nuggets
2025-02-03 12:11:09 +00:00
Dimitrie Stefanescu e9f3701a86 feat(rhino): wraps receive in an undo operation (#544)
* feat(rhino): wraps receive in an undo operation

* fix: formatting
2025-02-01 19:43:22 +03:00
Dimitrie Stefanescu 3a7baf0659 Merge pull request #543 from specklesystems/dimitrie/cnx-1152-rhino-change-tracking-not-working-in-first-open-doc
fix(rhino): isDocumentInit is set to true even on paste operations
2025-02-01 14:10:42 +01:00
Dimitrie Stefanescu 24bff4b1ce fix: isDocumentInit is set to true even on paste operations 2025-02-01 13:04:11 +00:00
Dimitrie Stefanescu 184c53c3a2 fix: exceptions on null layers (#540)
it does seem like a rhino layer can have null full name in some cases

Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
2025-01-30 16:41:57 +00:00
Björn Steinhagen 16ce6ac09f fix: catch tendon and link as warning (#538) 2025-01-30 16:46:11 +01:00
Adam Hathcock f379996f31 Better handle UnobservedTaskExceptions without the Event Aggregator. … (#539)
* Better handle UnobservedTaskExceptions without the Event Aggregator.  Logs will have them.

* formatting
2025-01-30 13:55:18 +00:00
kekesidavid 48e66f9084 Mesh generator logic to triangulate 2D and 3D surfaces (#529)
* added mesh generator logic to triangulate 2D and 3D surfaces from polygon inputs

* removed empty folder

* checking hole polygon vertex order, added comments

* csharpier

* added MeshTriangulation project to Local sln

* added reference to MeshTriangulator in Tekla Converters
2025-01-29 15:27:09 +01:00
Jedd Morgan f2249356d8 Add to build (#525) 2025-01-29 14:02:07 +00:00
Björn Steinhagen f4765b9e82 bjorn/cnx-1133-user-facing-attributes-not-consistent-for-joints (#536)
* style: user facing attributes for joint

* bug: using old strings
2025-01-29 14:46:29 +01:00
Claire Kuang e4a29085f3 chore(template): amends pr template to be more descriptive (#535)
* Update pull_request_template.md

* Update pull_request_template.md
2025-01-29 12:56:17 +00:00
Jonathon Broughton 462d01a3b2 feat(Navisworks): CNX-1043 Enable shared ribbon for v2 and v3 Navisworks connectors (#504)
* Add Speckle v2 and v3 launch buttons to the Navisworks ribbon

- Added `LaunchSpeckleConnector` class with constants for command and plugin names
- Updated `NavisworksRibbon.name` file to include display names for Speckle v2 and v3
- Updated `NavisworksRibbon.xaml` file to include ribbon panels and buttons for Speckle v2 and v3
- Updated `NavisworksRibbon.xaml.cs` file to include commands for launching Speckle v2 and v3 connectors
- Added resources for the icons of the new buttons

* Delete AppUtils.cs and Commands.cs, add Utilities.cs

- Delete AppUtils.cs and Commands.cs (Replaced by v2 and v3 Tools)
- Add Utilities.cs for plugin utilities functionality

* Update Speckle Connector for Navisworks to use the new SpeckleV3Tool plugin and developer ID. Also, initialize the services with the correct version of Navisworks.

* Update RibbonHandler class in Navisworks connector plugin:
- Refactor the CanExecuteCommand method to handle different commandIds.
- Add a static constructor to subscribe to the PluginRecordsChanged event.
- Implement OnPluginRecordsChanged method to reset the cached state of V2 plugin availability.
- Modify ExecuteCommand method to load and activate the appropriate plugin based on the commandId.
- Add a new IsValidVersion method to check if the current version of Navisworks is compatible with the plugin.

* Update ribbon handling logic in NavisworksRibbon.xaml.cs

- Find the v2 plugin and update the availability state
- Hide the v2 ribbon tab if it exists

* Fix ribbon handling for Speckle v3 and v2 tools

Refactor the code in `RibbonHandler` to improve the handling of commands for Speckle v3 and v2 tools. The changes include:
- Extracting a new method `HandleCommand` to handle the loading and activation of plugins
- Removing duplicated code by calling `HandleCommand` for both Speckle v3 and v2 tools
- Adding null checks when finding plugin records
- Returning early if plugin loading should be skipped

* XMLDOC comments added

- Added two summary comments to describe the purpose of the methods `CanExecuteCommand()` and `ExecuteCommand()`.

* Add Speckle V2 and V3 tools to Navisworks plugin

- Added `SpeckleV2Tool.cs` file with constants for Speckle V2 tool
- Added `SpeckleV3Tool.cs` file with constants for Speckle V3 tool

* Refactor Utilities.cs for Navisworks plugin

- Add conditional compilation for DEBUG mode

* Remove debug code and comments in Utilities.cs

- Remove debug code that prints available plugins to the Debug output window
- Remove unused using statement for System.Text

* Refactor plugin activation logic in NavisworksRibbon.xaml.cs and Utilities.cs

- Simplify ActivatePluginPane method in Utilities.cs
- Remove unused parameter 'command' from ActivatePluginPane method

* Update Speckle branding and UI elements

- Changed display names for Speckle versions to reflect beta status.
- Updated XAML to simplify ribbon panel structure.
- Adjusted constants in the tool class for consistency with new naming.

* Fix formatting and improve error messages

- Added missing newlines for better readability in code.
- Updated error message to enhance clarity for users.
- Cleaned up XML formatting in project files for consistency.
- Ensured all package references are properly formatted.

* Add missing namespace for Navisworks integration

- Included the HostApp namespace to improve functionality.
- Ensures better access to required classes and methods.

* Fix message box formatting in Navisworks plugin

Updated the message box string concatenation for better readability.
2025-01-29 10:57:44 +00:00
Jonathon Broughton 8ca43a1ad5 feat(Navisworks): CNX-1064 - Add hierarchy path property to converted Navisworks objects (#500)
* Add DisplayPathHelper class for generating display paths in Navisworks

This commit adds a new file, `DisplayPathHelper.cs`, which contains a helper class for generating display paths by traversing Navisworks model item ancestors. The `GenerateDisplayPath` method takes a `ModelItem` as input and returns a string representing the full path of display names from ancestors, stopping at the first object ancestor. If no first object ancestor is found, it returns just the model item's display name.

The helper class uses a constant `PATH_DELIMITER` to separate the display names in the generated path. It throws an exception if the input `modelItem` is null.

The algorithm works by starting from the first object ancestor and traversing backwards to the root, collecting non-empty display names along the way. Finally, it reverses the collected names and joins them with the delimiter to form the final display path string.

These changes improve code reusability and readability by encapsulating logic related to generating display paths in Navisworks models.

* Update NavisworksRootObjectBuilder.cs

- Modified the CreateNavisworksObject method to handle cases where the convertedBase or groupKey is null and return null in those cases
- Added a new private method GetDisplayPath to retrieve the modelItem and displayPath based on the applicationId
- Updated the CreateNavisworksObject methods to include the displayNamePath property in the returned NavisworksObject

* Refactor NavisworksRootObjectBuilder.cs: Add FindMeaningfulAncestorName method

This commit adds a new private method, FindMeaningfulAncestorName, to the NavisworksRootObjectBuilder class. This method is used to find the name of the most meaningful ancestor of a given NAV.ModelItem object. It iterates through the ancestors until it finds an ancestor with a non-empty DisplayName and no geometry. The found name is then used as the "name" property in the created NavisworksObject instances. Additionally, the "displayNamePath" property has been renamed to "path" for consistency.

* Refactor display path generation for Navisworks model items

- Update the helper class to generate display paths by traversing meaningful Navisworks model item ancestors.
- Skip nodes without meaningful names or geometry nodes when generating the display path.
- Reverse the collected names to build the path from root to leaf.

* Rename DisplayPathHelper.cs to HierarchyHelper.cs
- Renamed the file from "DisplayPathHelper.cs" to "HierarchyHelper.cs"
- Updated all references to the renamed file

Refactor helper class for generating display paths
- Refactored the helper class to extract hierarchical context from Navisworks model items in a single traversal
- Changed the method name from "GenerateDisplayPath" to "ExtractContext"
- Modified the method signature to return a tuple of strings (Name, Path)
- Updated the implementation logic accordingly

Improve traversal and extraction logic
- Improved the traversal logic by collecting both name and path information while traversing up the tree once
- Extracted meaningful name and path information from model items in a more efficient way
- Handled cases where model item has no meaningful name or is a geometry node

* Refactor NavisworksRootObjectBuilder.cs for improved context extraction

- Extracted the GetContext method to retrieve the name and path of a model item
- Replaced calls to GetDisplayPath with calls to GetContext for consistency
- Updated CreateNavisworksObject and ConvertBase methods to use the extracted context information instead of finding meaningful ancestor names
- Updated the "path" property in the returned NavisworksObject instances with the extracted path
2025-01-29 10:48:34 +00:00
Björn Steinhagen bb252a5115 bjorn/cnx-1112-get-user-facing-names-of-properties (#526)
* style: user facing names for frames

* style: user facing names for shells

* styling: user facing names for proxies

* style: dict utils as extension methods
2025-01-29 11:25:15 +01:00
Björn Steinhagen 4d7225fab4 bjorn/cnx-1119-remove-caching-from-progress (#534)
* Add PeriodicThreadedEvent to EA and use it

* All timers gone

* add tests

* bug: build issues

* bug: form not being disposed properly

* feat: remove caching

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
2025-01-29 11:08:02 +01:00
Adam Hathcock 9219cdfc53 Add PeriodicThreadedEvent to EA and use it (#530)
* Add PeriodicThreadedEvent to EA and use it

* All timers gone

* add tests

* bug: build issues

* bug: form not being disposed properly

---------

Co-authored-by: Björn <steinhagen.bjoern@gmail.com>
2025-01-29 09:28:03 +00:00
Björn Steinhagen 03f0b1fc56 bjorn/cnx-1111-switching-documents-does-not-invalidate-active-connector (#528)
* bug: close plugin when user switches model

* bug: refresh plugin when model changes

* style: remove log information
2025-01-28 15:43:42 +00:00
Adam Hathcock 9e18134c5e Use Event Aggregator with Navisworks (#523)
* Convert selection and idle events

* init NW2025

* testing NW

* formatting
2025-01-28 15:25:19 +00:00
Claire Kuang 67c7ddbf0a fix(all): aligns all panel, button, and tooltip text across connectors (#521)
* updates button labels and panel text

* adds rhino toolbar

* removes unnecessary images

* feat: Add rui to Rhino projects with AssemblyName as filename

---------

Co-authored-by: Alan Rynne <alan@speckle.systems>
2025-01-28 15:07:49 +00:00
Adam Hathcock 79a6062923 Use Event Aggregator with Autocad/Civil (#517)
* Rework doc selection

* add more events

* use idle events

* Fix autocad events and format
2025-01-28 10:12:29 +00:00
Jedd Morgan 81c3c420a7 added workflow back into sln (#524) 2025-01-27 15:38:22 +00:00
Björn Steinhagen 315a0cbf5e bjorn/cnx-1105-add-dynamic-setselection-support-no-events-available (#522)
* refresh GetSelection and UI icon

- refreshing GetSelection based on RVT22 approach
- adding Speckle Beta icon to the UI

* feat: changing default plugin size
2025-01-27 11:37:04 +01:00
Jedd Morgan d753ea47e2 Renamed CI workflows for clarity (#519) 2025-01-24 15:44:16 +00:00
Jedd Morgan da5caa8319 bump sdk (#515)
* bump sdk

* bump sdk for exception handling

* adjust tester

* update SDK

* fix tester again

* fix import

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
2025-01-24 14:04:06 +00:00
Adam Hathcock ca7714a8a3 Use Event Aggregator with Revit (#513)
* This is a workaround for Revit's order of operations when initializing

* Fix event listening

* Only allow methods on classes as opposed to anonymous lambdas

* formatting

* moved revit changed to fresh branch

* fix tests

* weakreference found should remove subscription

* Fix anonymous lambdas

* allow for static handlers and add tests

* Clean up

* formatting

* Change publish to avoid reentrancy issues.  Change from semaphore to lock statement
2025-01-24 13:12:43 +00:00
Adam Hathcock 4b5f3981d3 Some clean up for ETABs (#518)
* Some clean up

* have a model and resizable dialog
2025-01-23 15:50:01 +00:00
486 changed files with 17042 additions and 7402 deletions
+3 -3
View File
@@ -9,10 +9,10 @@
],
"rollForward": false
},
"gitversion.tool": {
"version": "6.0.2",
"dotnet-affected": {
"version": "5.0.0",
"commands": [
"dotnet-gitversion"
"dotnet-affected"
],
"rollForward": false
}
+29 -26
View File
@@ -4,33 +4,36 @@
# * @specklesystems/connectors
# Core
# Not needed, falls back on team approval
# Objects
# Converters require product owner approval, anything else falls back to team approval
Objects/ConverterAutocadCivil/* @clairekuang @connorivy
Objects/ConverterCSI/* @connorivy
Objects/ConverterDynamo/* @teocomi @alanrynne
Objects/ConverterMicrostation/* @connorivy
Objects/ConverterRevit/* @connorivy @teocomi
Objects/ConverterRhinoGh/* @alanrynne @clairekuang
Objects/ConverterTeklaStructures/* @connorivy
Objects/StructuralUtilities/PolygonMesher/* @connorivy
# Connectors
ConnectorAutocadCivil/* @clairekuang
ConnectorArchicad/* @jozseflkiss
ConnectorCSI/* @connorivy
ConnectorDynamo/* @teocomi @alanrynne
ConnectorGrasshopper/* @alanrynne @clairekuang
ConnectorMicrostation/* @clairekuang
ConnectorRevit/* @teocomi @connorivy
ConnectorRhino/* @clairekuang @alanrynne
ConnectorTeklaStructures/* @connorivy
/Connectors/ArcGIS/* @KatKatKateryna
/Connectors/Autocad/* @clairekuang @oguzhankoral @didimitrie
/Connectors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
/Connectors/CSi/* @bjoernsteinhagen @dogukankaratas
/Connectors/Navisworks/* @jsdbroughton
/Connectors/Revit/* @clairekuang @oguzhankoral @didimitrie
/Connectors/Rhino/* @clairekuang @oguzhankoral @didimitrie
/Connectors/Tekla/* @bjoernsteinhagen @dogukankaratas
# DesktopUI
# Converters
/Convertors/ArcGIS/* @KatKatKateryna
/Convertors/Autocad/* @clairekuang @oguzhankoral @didimitrie
/Convertors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
/Convertors/CSi/* @bjoernsteinhagen @dogukankaratas
/Convertors/Navisworks/* @jsdbroughton
/Convertors/Revit/* @clairekuang @oguzhankoral @didimitrie
/Convertors/Rhino/* @clairekuang @oguzhankoral @didimitrie
/Convertors/Tekla/* @bjoernsteinhagen @dogukankaratas
DesktopUI2/* @teocomi @clairekuang
# DUI
/DUI3/* @clairekuang @oguzhankoral @didimitrie
# Importers
/Importers/* @JR-Morgan @didimitrie @oguzhankoral @adamhathcock
# SDK
/SDK/* @JR-Morgan @clairekuang @didimitrie @oguzhankoral @adamhathcock
# Build
/Build/* @JR-Morgan @oguzhankoral @adamhathcock
+29 -38
View File
@@ -1,30 +1,46 @@
<!---
Provide a short summary in the Title above. Examples of good PR titles:
Provide a short summary in the Title above. Use the following template:
* "Feature: adds metrics to component"
category(project): summary
* "Fix: resolves duplication in comment thread"
Categories:
* "Update: apollo v2.34.0"
* feat: (new feature for the user, not a new feature for build script)
* fix: (bug fix for the user, not a fix to a build script)
* docs: (changes to the documentation)
* style: (formatting, missing semi colons, etc; no production code change)
* refactor: (refactoring production code, eg. renaming a variable)
* test: (adding missing tests, refactoring tests; no production code change)
* chore: (updating grunt tasks etc; no production code change)
Example:
feat(revit): added category filter to send
-->
## Description & motivation
## Description
<!---
Describe your changes, and why you're making them. What benefit will this have to others?
Describe your changes, and why you're making them.
Is this linked to an open Github issue, a thread in Speckle community,
or another pull request? Link it here.
If it is related to a Github issue, and resolves it, please link to the issue number, e.g.:
Fixes #85, Fixes #22, Fixes username/repo#123
Connects #123
Link related github issues here ->
Fixes #85, Fixes #22, Connects #123
-->
## User Value
<!---
Describe in 1 sentence the user value.
This can also be a link to the relevant thread in Speckle community, or a link to the Linear issue.
-->
## Changes:
<!---
@@ -68,35 +84,10 @@ Describe what tests have been added or amended, and why these demonstrate it wor
<!---
This checklist is mostly useful as a reminder of small things that can easily be
forgotten it is meant as a helpful tool rather than hoops to jump through.
Put an `x` between the square brackets, e.g. [x], for all the items that apply,
make notes next to any that haven't been addressed, and remove any items that are not relevant to this PR.
This checklist is a useful reminder of related tasks to uphold our repo quality. Amend this list as needed for the pr.
-->
- [ ] My pull request follows the guidelines in the [Contributing guide](https://github.com/specklesystems/speckle-server/blob/main/CONTRIBUTING.md)?
- [ ] My pull request does not duplicate any other open [Pull Requests](../../pulls) for the same update/change?
- [ ] My commits are related to the pull request and do not amend unrelated code or documentation.
- [ ] My code follows a similar style to existing code.
- [ ] I have added appropriate tests.
- [ ] I have updated or added relevant documentation.
## References
<!---
(Optional -- remove this section if not needed )
Include **important** links regarding the implementation of this PR.
This usually includes a RFC or an aggregation of issues and/or individual conversations
that helped put this solution together. This helps ensure we retain and share knowledge
regarding the implementation, and may help others understand motivation and design decisions etc..
-->
@@ -1,9 +1,7 @@
name: .NET Build
on:
pull_request: # Run build on every pull request that is not to main
branches-ignore:
- main
pull_request
jobs:
build:
@@ -34,6 +32,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
@@ -2,12 +2,14 @@ name: .NET Build and Publish
on:
push:
branches: ["main", "dev", "release/*"] # Continuous delivery on every long-lived branch
branches: ["main", "installer-test/**"]
tags: ["v3.*"] # Manual delivery on every 3.x tag
jobs:
build-windows:
runs-on: windows-latest
env:
SPECKLE_VERSION: "unset"
outputs:
version: ${{ steps.set-version.outputs.version }}
steps:
@@ -27,38 +29,35 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
- name: ⚒️ Run GitVersion on Windows
run: ./build.ps1 build-server-version
- name: ⚒️ Run build on Windows
run: ./build.ps1
run: ./build.ps1 zip
- name: ⬆️ Upload artifacts
uses: actions/upload-artifact@v4
with:
name: output-${{ env.GitVersion_FullSemVer }}
name: output-${{ env.SPECKLE_VERSION }}
path: output/*.*
compression-level: 0 # no compression
if-no-files-found: error
retention-days: 1
compression-level: 0 # no compression
- id: set-version
name: Set version to output
run: echo "version=${{ env.GitVersion_FullSemVer }}" >> "$Env:GITHUB_OUTPUT"
run: echo "version=${{ env.SPECKLE_VERSION }}" >> "$Env:GITHUB_OUTPUT"
deploy-installers:
runs-on: ubuntu-latest
needs: build-windows
env:
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'main'}}
IS_PUBLIC_RELEASE: ${{ github.ref_type == 'tag' }}
IS_TEST_INSTALLER: ${{ github.ref_type != 'tag' }}
steps:
- name: 🔫 Trigger Build Installers
uses: ALEEF02/workflow-dispatch@v3.0.0
continue-on-error: true
with:
workflow: Build Installers
repo: specklesystems/connector-installers
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build-windows.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build-windows.outputs.version }}", "public_release": ${{ env.IS_PUBLIC_RELEASE }}, "store_artifacts": ${{ env.IS_TEST_INSTALLER }} }'
ref: main
wait-for-completion: true
wait-for-completion-interval: 10s
@@ -89,9 +88,6 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
- name: ⚒️ Run GitVersion on Linux
run: ./build.sh build-server-version
- name: ⚒️ Run tests on Linux
run: ./build.sh test-only
@@ -101,8 +97,9 @@ jobs:
- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v5
with:
file: Converters/**/coverage.xml
files: Converters/**/coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: Push to nuget.org
if: (github.ref_type == 'tag')
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
+116
View File
@@ -0,0 +1,116 @@
using GlobExpressions;
using Microsoft.Build.Construction;
using static SimpleExec.Command;
namespace Build;
public static class Affected
{
public static readonly string Root = Environment.CurrentDirectory;
public const string AFFECTED_PROJECT = "affected.proj";
private static IEnumerable<string> GetAffectedProjects()
{
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
Console.WriteLine("Affected project file: " + projFile);
var project = ProjectRootElement.Open(projFile) ?? throw new InvalidOperationException();
var references = project.ItemGroups.SelectMany(x => x.Items).Where(x => x.ItemType == "ProjectReference");
foreach (var refe in references)
{
var referencePath = refe.Include[(Root.Length + 1)..];
referencePath = Path.GetDirectoryName(referencePath) ?? throw new InvalidOperationException();
if (Path.DirectorySeparatorChar != '/')
{
referencePath = referencePath.Replace(Path.DirectorySeparatorChar, '/');
}
yield return referencePath;
}
}
public static async Task<IEnumerable<string>> GetTestProjects()
{
await ComputeAffected();
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
if (File.Exists(projFile))
{
var references = GetAffectedProjects();
return references.Where(x => x.Contains("Tests"));
}
return Glob.Files(Root, "**/*.Tests.csproj");
}
public static async Task<ProjectGroup[]> GetAffectedProjectGroups()
{
await ComputeAffected();
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
if (File.Exists(projFile))
{
var references = GetAffectedProjects().ToList();
var groups = new List<ProjectGroup>();
foreach (var projectGroup in Consts.ProjectGroups)
{
foreach (var referencePath in references)
{
if (projectGroup.Projects.Any(x => x.ProjectPath.Contains(referencePath)))
{
groups.Add(projectGroup);
break;
}
}
}
foreach (var group in groups)
{
Console.WriteLine("Affected project group being built: " + group.HostAppSlug);
}
return groups.ToArray();
}
Console.WriteLine("Using all project groups: " + string.Join(',', Consts.ProjectGroups));
return Consts.ProjectGroups;
}
private static bool s_affectedComputed;
public static async Task ComputeAffected()
{
if (s_affectedComputed)
{
return;
}
var currentTag = await Versions.GetCurrentTag();
var currentVersion = await Versions.ComputeVersion();
var lastTag = await Versions.GetPreviousTag(currentTag);
var lastVersion = await Versions.ComputePreviousVersion(currentTag);
Console.WriteLine($"Last tag: {lastTag}, Current tag: {currentTag}");
Console.WriteLine($"Last parsed version: {lastVersion}, Current parsed version: {currentVersion}");
var sort = currentVersion.CompareSortOrderTo(lastVersion);
if (sort == -1)
{
Console.WriteLine($"Current version {currentVersion} is less than: {lastVersion}");
s_affectedComputed = true;
return;
}
var majorEquals = currentVersion.Major == lastVersion.Major;
if (!majorEquals)
{
Console.WriteLine($"Current version {currentVersion} is not matching major version: {lastVersion}");
s_affectedComputed = true;
return;
}
//use tags no matter the version if major versions match
var (currentCommit, _) = await ReadAsync("git", $"rev-list -n 1 {currentTag}");
var (lastCommit, _) = await ReadAsync("git", $"rev-list -n 1 {lastTag}");
await RunAsync("dotnet", $"affected -v --from {currentCommit.Trim()} --to {lastCommit.Trim()}", Root);
s_affectedComputed = true;
}
}
+1
View File
@@ -10,6 +10,7 @@
<PackageReference Include="Bullseye" />
<PackageReference Include="Glob" />
<PackageReference Include="Microsoft.Build" />
<PackageReference Include="Semver" />
<PackageReference Include="SimpleExec" />
</ItemGroup>
</Project>
+12 -4
View File
@@ -4,7 +4,7 @@ public static class Consts
{
public static readonly string[] Solutions = ["Speckle.Connectors.sln"];
public static readonly InstallerProject[] InstallerManifests =
public static readonly ProjectGroup[] ProjectGroups =
{
new("arcgis", [new("Connectors/ArcGIS/Speckle.Connectors.ArcGIS3", "net6.0-windows")]),
new(
@@ -49,20 +49,28 @@ public static class Consts
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2022", "net48"),
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2023", "net48"),
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2024", "net48"),
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2025", "net48")
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2025", "net48"),
new("Connectors/Navisworks/Speckle.Connectors.Navisworks2026", "net48")
]
),
new(
"tekla-structures",
"teklastructures",
[
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
]
),
new(
"etabs",
[
new("Connectors/CSi/Speckle.Connectors.ETABS21", "net48"),
new("Connectors/CSi/Speckle.Connectors.ETABS22", "net8.0-windows"),
]
)
};
}
public readonly record struct InstallerProject(string HostAppSlug, IReadOnlyList<InstallerAsset> Projects)
public readonly record struct ProjectGroup(string HostAppSlug, IReadOnlyList<InstallerAsset> Projects)
{
public override string ToString() => $"{HostAppSlug}";
}
+137 -103
View File
@@ -12,12 +12,12 @@ const string TEST = "test";
const string TEST_ONLY = "test-only";
const string FORMAT = "format";
const string ZIP = "zip";
const string VERSION = "version";
const string RESTORE_TOOLS = "restore-tools";
const string BUILD_SERVER_VERSION = "build-server-version";
const string CLEAN_LOCKS = "clean-locks";
const string CHECK_SOLUTIONS = "check-solutions";
const string DEEP_CLEAN = "deep-clean";
const string DEEP_CLEAN_LOCAL = "deep-clean-local";
const string DETECT_AFFECTED = "detect-affected";
//need to pass arguments
/*var arguments = new List<string>();
@@ -27,18 +27,59 @@ if (args.Length > 1)
args = new[] { arguments.First() };
//arguments = arguments.Skip(1).ToList();
}*/
void Build(string solution, string configuration)
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine($"Building solution '{solution}' as '{configuration}'");
Console.WriteLine();
Run("dotnet", $"build \".\\{solution}\" --configuration {configuration} --no-restore");
}
void Restore(string solution)
{
Console.WriteLine();
Console.WriteLine($"Restoring solution '{solution}'");
Console.WriteLine();
Run("dotnet", $"restore \".\\{solution}\" --no-cache");
}
void DeleteFiles(string pattern)
{
foreach (var f in Glob.Files(".", pattern))
{
Console.WriteLine("Found and will delete: " + f);
File.Delete(f);
}
}
void DeleteDirectories(string pattern)
{
foreach (var f in Glob.Directories(".", pattern))
{
if (f.StartsWith("Build"))
{
continue;
}
Console.WriteLine("Found and will delete: " + f);
Directory.Delete(f, true);
}
}
void CleanSolution(string solution, string configuration)
{
Console.WriteLine("Cleaning solution: " + solution);
DeleteDirectories("**/bin");
DeleteDirectories("**/obj");
DeleteFiles("**/*.lock.json");
Restore(solution);
Build(solution, configuration);
}
Target(
CLEAN_LOCKS,
() =>
{
foreach (var f in Glob.Files(".", "**/*.lock.json"))
{
Console.WriteLine("Found and will delete: " + f);
File.Delete(f);
}
Console.WriteLine("Running restore now.");
Run("dotnet", "restore .\\Speckle.Connectors.sln --no-cache");
DeleteFiles("**/*.lock.json");
Restore("Speckle.Connectors.sln");
}
);
@@ -46,26 +87,14 @@ Target(
DEEP_CLEAN,
() =>
{
foreach (var f in Glob.Directories(".", "**/bin"))
{
if (f.StartsWith("Build"))
{
continue;
}
Console.WriteLine("Found and will delete: " + f);
Directory.Delete(f, true);
}
foreach (var f in Glob.Directories(".", "**/obj"))
{
if (f.StartsWith("Build"))
{
continue;
}
Console.WriteLine("Found and will delete: " + f);
Directory.Delete(f, true);
}
Console.WriteLine("Running restore now.");
Run("dotnet", "restore .\\Speckle.Connectors.sln --no-cache");
CleanSolution("Speckle.Connectors.sln", "debug");
}
);
Target(
DEEP_CLEAN_LOCAL,
() =>
{
CleanSolution("Local.sln", "local");
}
);
@@ -95,17 +124,6 @@ Target(
}
);
Target(
VERSION,
async () =>
{
var (output, _) = await ReadAsync("dotnet", "minver -v w");
output = output.Trim();
Console.WriteLine($"Version: {output}");
Run("echo", $"\"version={output}\" >> $GITHUB_OUTPUT");
}
);
Target(
RESTORE_TOOLS,
() =>
@@ -114,6 +132,18 @@ Target(
}
);
Target(
DETECT_AFFECTED,
DependsOn(RESTORE_TOOLS),
async () =>
{
foreach (var group in await Affected.GetAffectedProjectGroups())
{
Console.WriteLine("Affected project group being built: " + group.HostAppSlug);
}
}
);
Target(
FORMAT,
DependsOn(RESTORE_TOOLS),
@@ -125,20 +155,14 @@ Target(
Target(
RESTORE,
DependsOn(FORMAT),
DependsOn(FORMAT, DETECT_AFFECTED),
Consts.Solutions,
s =>
async s =>
{
Run("dotnet", $"restore {s} --locked-mode");
}
);
Target(
BUILD_SERVER_VERSION,
DependsOn(RESTORE_TOOLS),
() =>
{
Run("dotnet", "tool run dotnet-gitversion /output json /output buildserver");
var version = await Versions.ComputeVersion();
var fileVersion = await Versions.ComputeFileVersion();
Console.WriteLine($"Restoring: {s} - Version: {version} & {fileVersion}");
await RunAsync("dotnet", $"restore \"{s}\" --locked-mode");
}
);
@@ -146,14 +170,14 @@ Target(
BUILD,
DependsOn(RESTORE),
Consts.Solutions,
s =>
async s =>
{
var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0";
Console.WriteLine($"Version: {version} & {fileVersion}");
Run(
var version = await Versions.ComputeVersion();
var fileVersion = await Versions.ComputeFileVersion();
Console.WriteLine($"Restoring: {s} - Version: {version} & {fileVersion}");
await RunAsync(
"dotnet",
$"build {s} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
$"build \"{s}\" -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
);
}
);
@@ -163,23 +187,26 @@ Target(CHECK_SOLUTIONS, Solutions.CompareConnectorsToLocal);
Target(
TEST,
DependsOn(BUILD, CHECK_SOLUTIONS),
Glob.Files(".", "**/*.Tests.csproj"),
file =>
async () =>
{
Run("dotnet", $"test {file} -c Release --no-build --no-restore --verbosity=minimal");
foreach (var s in await Affected.GetTestProjects())
{
await RunAsync("dotnet", $"test \"{s}\" -c Release --no-build --no-restore --verbosity=minimal");
}
}
);
//all tests on purpose
Target(
TEST_ONLY,
DependsOn(FORMAT),
Glob.Files(".", "**/*.Tests.csproj"),
file =>
{
Run("dotnet", $"restore {file} --locked-mode");
Run("dotnet", $"build \"{file}\" -c Release --no-incremental");
Run(
"dotnet",
$"test {file} -c Release --no-restore --verbosity=minimal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage /p:AltCoverVerbosity=Warning"
$"test \"{file}\" -c Release --no-build --verbosity=minimal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage /p:AltCoverVerbosity=Warning"
);
}
);
@@ -188,20 +215,20 @@ Target(
BUILD_LINUX,
DependsOn(FORMAT),
Glob.Files(".", "**/Speckle.Importers.Ifc.csproj"),
file =>
async file =>
{
Run("dotnet", $"restore {file} --locked-mode");
var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0";
await RunAsync("dotnet", $"restore \"{file}\" --locked-mode");
var version = await Versions.ComputeVersion();
var fileVersion = await Versions.ComputeFileVersion();
Console.WriteLine($"Version: {version} & {fileVersion}");
Run(
await RunAsync(
"dotnet",
$"build {file} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
$"build \"{file}\" -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
);
RunAsync(
await RunAsync(
"dotnet",
$"pack {file} -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
$"pack \"{file}\" -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
);
}
);
@@ -209,47 +236,54 @@ Target(
Target(
ZIP,
DependsOn(TEST),
Consts.InstallerManifests,
x =>
async () =>
{
var outputDir = Path.Combine(".", "output");
var slugDir = Path.Combine(outputDir, x.HostAppSlug);
Directory.CreateDirectory(outputDir);
Directory.CreateDirectory(slugDir);
foreach (var asset in x.Projects)
var version = await Versions.ComputeVersion();
foreach (var group in await Affected.GetAffectedProjectGroups())
{
var fullPath = Path.Combine(".", asset.ProjectPath, "bin", "Release", asset.TargetName);
if (!Directory.Exists(fullPath))
Console.WriteLine($"Zipping: {group.HostAppSlug} as {version}");
var outputDir = Path.Combine(".", "output");
var slugDir = Path.Combine(outputDir, group.HostAppSlug);
Directory.CreateDirectory(outputDir);
Directory.CreateDirectory(slugDir);
foreach (var asset in group.Projects)
{
throw new InvalidOperationException("Could not find: " + fullPath);
var fullPath = Path.Combine(".", asset.ProjectPath, "bin", "Release", asset.TargetName);
if (!Directory.Exists(fullPath))
{
throw new InvalidOperationException("Could not find: " + fullPath);
}
var assetName = Path.GetFileName(asset.ProjectPath);
var connectorDir = Path.Combine(slugDir, assetName);
Directory.CreateDirectory(connectorDir);
foreach (var directory in Directory.EnumerateDirectories(fullPath, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(directory.Replace(fullPath, connectorDir));
}
foreach (var file in Directory.EnumerateFiles(fullPath, "*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
File.Copy(file, file.Replace(fullPath, connectorDir), true);
}
}
var assetName = Path.GetFileName(asset.ProjectPath);
var connectorDir = Path.Combine(slugDir, assetName);
Directory.CreateDirectory(connectorDir);
foreach (var directory in Directory.EnumerateDirectories(fullPath, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(directory.Replace(fullPath, connectorDir));
}
foreach (var file in Directory.EnumerateFiles(fullPath, "*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
File.Copy(file, file.Replace(fullPath, connectorDir), true);
}
var outputPath = Path.Combine(outputDir, $"{group.HostAppSlug}.zip");
File.Delete(outputPath);
Console.WriteLine($"Zipping: '{slugDir}' to '{outputPath}'");
ZipFile.CreateFromDirectory(slugDir, outputPath);
}
var outputPath = Path.Combine(outputDir, $"{x.HostAppSlug}.zip");
File.Delete(outputPath);
Console.WriteLine($"Zipping: '{slugDir}' to '{outputPath}'");
ZipFile.CreateFromDirectory(slugDir, outputPath);
// Directory.Delete(slugDir, true);
string githubEnv = Environment.GetEnvironmentVariable("GITHUB_ENV") ?? "Unset";
Console.WriteLine($"GITHUB_ENV: {githubEnv}");
File.AppendAllText(githubEnv, $"SPECKLE_VERSION={version}{Environment.NewLine}");
}
);
Target("default", DependsOn(FORMAT, ZIP), () => Console.WriteLine("Done!"));
Target("default", DependsOn(TEST), () => Console.WriteLine("Done!"));
await RunTargetsAndExitAsync(args).ConfigureAwait(true);
+79
View File
@@ -0,0 +1,79 @@
using Semver;
using static SimpleExec.Command;
namespace Build;
public static class Versions
{
private static string? s_currentTag;
private static SemVersion? s_currentVersion;
public static async Task<string> GetCurrentTag()
{
if (s_currentTag is not null)
{
return s_currentTag;
}
//finds current tag or makes one
var (currentTag, _) = await ReadAsync("git", "describe --tags");
currentTag = currentTag.Trim();
s_currentTag = currentTag;
return s_currentTag;
}
public static async Task<SemVersion> ComputeVersion()
{
if (s_currentVersion is not null)
{
return s_currentVersion;
}
var currentTag = await GetCurrentTag();
if (!SemVersion.TryParse(currentTag, SemVersionStyles.AllowLowerV, out var currentVersion))
{
throw new InvalidOperationException($"Could not parse version: '{currentTag}'");
}
s_currentVersion = currentVersion;
return s_currentVersion;
}
private static string? s_currentFileVersion;
public static async Task<string> ComputeFileVersion()
{
if (s_currentFileVersion is not null)
{
return s_currentFileVersion;
}
var currentVersion = await ComputeVersion();
s_currentFileVersion = currentVersion.WithoutPrereleaseOrMetadata() + ".0";
return s_currentFileVersion;
}
public static async Task<string> GetPreviousTag(string currentTag)
{
//finds a tag starting with current tag and adds no abbrevation
var (lastTag, _) = await ReadAsync("git", $"describe --abbrev=0 --tags {currentTag}^");
lastTag = lastTag.Trim();
return lastTag;
}
private static SemVersion? s_previousVersion;
public static async Task<SemVersion> ComputePreviousVersion(string currentTag)
{
if (s_previousVersion is not null)
{
return s_previousVersion;
}
var lastTag = await GetPreviousTag(currentTag);
if (!SemVersion.TryParse(lastTag, SemVersionStyles.AllowLowerV, out var lastVersion))
{
throw new InvalidOperationException($"Could not parse version: '{lastTag}'");
}
s_previousVersion = lastVersion;
return s_previousVersion;
}
}
+14
View File
@@ -53,6 +53,15 @@
"resolved": "1.14.1",
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
},
"Semver": {
"type": "Direct",
"requested": "[3.0.0, )",
"resolved": "3.0.0",
"contentHash": "9jZCicsVgTebqkAujRWtC9J1A5EQVlu0TVKHcgoCuv345ve5DYf4D1MjhKEnQjdRZo6x/vdv6QQrYFs7ilGzLA==",
"dependencies": {
"Microsoft.Extensions.Primitives": "5.0.1"
}
},
"SimpleExec": {
"type": "Direct",
"requested": "[12.0.0, )",
@@ -75,6 +84,11 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "5.0.1",
"contentHash": "5WPSmL4YeP7eW+Vc8XZ4DwjYWBAiSwDV9Hm63JJWcz1Ie3Xjv4KuJXzgCstj48LkLfVCYa7mLcx7y+q6yqVvtw=="
},
"Microsoft.NET.StringTools": {
"type": "Transitive",
"resolved": "17.11.4",
@@ -19,7 +19,7 @@ namespace Speckle.Connectors.ArcGIS.Bindings;
public sealed class ArcGISReceiveBinding : IReceiveBinding
{
public string Name { get; } = "receiveBinding";
private readonly CancellationManager _cancellationManager;
private readonly ICancellationManager _cancellationManager;
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly IOperationProgressManager _operationProgressManager;
@@ -32,7 +32,7 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
public ArcGISReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<ArcGISReceiveBinding> logger,
@@ -60,7 +60,7 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
throw new InvalidOperationException("No download model card was found.");
}
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
@@ -76,8 +76,8 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
.ServiceProvider.GetRequiredService<ReceiveOperation>()
.Execute(
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
cancellationToken
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
@@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Microsoft.Extensions.DependencyInjection;
@@ -15,7 +16,6 @@ using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
@@ -39,13 +39,14 @@ public sealed class ArcGISSendBinding : ISendBinding
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly CancellationManager _cancellationManager;
private readonly ICancellationManager _cancellationManager;
private readonly ISendConversionCache _sendConversionCache;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<ArcGISSendBinding> _logger;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
private readonly IThreadContext _threadContext;
private readonly ISpeckleApplication _speckleApplication;
/// <summary>
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
@@ -64,14 +65,14 @@ public sealed class ArcGISSendBinding : ISendBinding
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<ArcGISSendBinding> logger,
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
MapMembersUtils mapMemberUtils,
IThreadContext threadContext,
IEventAggregator eventAggregator,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
@@ -86,11 +87,15 @@ public sealed class ArcGISSendBinding : ISendBinding
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
_mapMemberUtils = mapMemberUtils;
_threadContext = threadContext;
_speckleApplication = speckleApplication;
Parent = parent;
Commands = new SendBindingUICommands(parent);
SubscribeToArcGISEvents();
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
_store.DocumentChanged += (_, _) =>
{
_sendConversionCache.ClearCache();
};
}
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
@@ -100,7 +105,7 @@ public sealed class ArcGISSendBinding : ISendBinding
LayersRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForLayersRemovedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
),
true
);
@@ -108,7 +113,7 @@ public sealed class ArcGISSendBinding : ISendBinding
StandaloneTablesRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
),
true
);
@@ -116,7 +121,7 @@ public sealed class ArcGISSendBinding : ISendBinding
MapPropertyChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapPropertyChangedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
),
true
); // Map units, CRS etc.
@@ -124,8 +129,7 @@ public sealed class ArcGISSendBinding : ISendBinding
MapMemberPropertiesChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () =>
await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
),
true
); // e.g. Layer name
@@ -134,7 +138,7 @@ public sealed class ArcGISSendBinding : ISendBinding
_ =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await _threadContext.RunOnWorker(SubscribeToMapMembersDataSourceChange);
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
}),
true
);
@@ -372,24 +376,28 @@ public sealed class ArcGISSendBinding : ISendBinding
throw new InvalidOperationException("No publish model card was found.");
}
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
List<MapMember> mapMembers = modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
.Where(obj => obj != null)
.ToList();
List<MapMember> mapMembers = await QueuedTask.Run(() =>
{
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
return modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
.Where(obj => obj != null)
.ToList();
});
if (mapMembers.Count == 0)
{
@@ -397,26 +405,29 @@ public sealed class ArcGISSendBinding : ISendBinding
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
// subscribe to the selected layer events
foreach (MapMember mapMember in mapMembers)
await QueuedTask.Run(() =>
{
if (mapMember is FeatureLayer featureLayer)
// subscribe to the selected layer events
foreach (MapMember mapMember in mapMembers)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
if (mapMember is FeatureLayer featureLayer)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
}
else if (mapMember is StandaloneTable table)
{
SubscribeToTableDataSourceChange(table);
}
}
else if (mapMember is StandaloneTable table)
{
SubscribeToTableDataSourceChange(table);
}
}
});
var sendResult = await scope
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
.Execute(
mapMembers,
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
cancellationToken
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
@@ -1,9 +1,9 @@
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
@@ -21,24 +21,28 @@ public class BasicConnectorBinding : IBasicConnectorBinding
public BasicConnectorBindingCommands Commands { get; }
private readonly DocumentModelStore _store;
private readonly ISpeckleApplication _speckleApplication;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public BasicConnectorBinding(
DocumentModelStore store,
IBrowserBridge parent,
ISpeckleApplication speckleApplication,
IEventAggregator eventAggregator
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_store = store;
_speckleApplication = speckleApplication;
_topLevelExceptionHandler = topLevelExceptionHandler;
Parent = parent;
Commands = new BasicConnectorBindingCommands(parent);
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
_store.DocumentChanged += (_, _) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await Commands.NotifyDocumentChanged();
});
}
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
public string GetSourceApplicationName() => _speckleApplication.Slug;
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
@@ -63,19 +67,20 @@ public class BasicConnectorBinding : IBasicConnectorBinding
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public Task HighlightObjects(IReadOnlyList<string> objectIds)
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
{
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
return Task.CompletedTask;
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
}
public Task HighlightModel(string modelCardId)
public async Task HighlightModel(string modelCardId)
{
var model = _store.GetModelById(modelCardId);
if (model is null)
{
return Task.CompletedTask;
return;
}
var objectIds = new List<ObjectID>();
@@ -92,22 +97,24 @@ public class BasicConnectorBinding : IBasicConnectorBinding
if (objectIds is null)
{
return Task.CompletedTask;
return;
}
HighlightObjectsOnView(objectIds);
return Task.CompletedTask;
await HighlightObjectsOnView(objectIds);
}
private void HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
{
MapView mapView = MapView.Active;
await QueuedTask.Run(() =>
{
MapView mapView = MapView.Active;
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
ClearSelectionInTOC();
ClearSelection();
SelectMapMembersInTOC(mapMembersFeatures);
SelectMapMembersAndFeatures(mapMembersFeatures);
mapView.ZoomToSelected();
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
ClearSelectionInTOC();
ClearSelection();
SelectMapMembersInTOC(mapMembersFeatures);
SelectMapMembersAndFeatures(mapMembersFeatures);
mapView.ZoomToSelected();
});
}
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
@@ -20,7 +20,7 @@
<ArcGIS defaultAssembly="Speckle.Connectors.ArcGIS3.dll" defaultNamespace="Speckle.Connectors.ArcGIS" xmlns="http://schemas.esri.com/DADF/Registry" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.esri.com/DADF/Registry file:///C:/Program%20Files/ArcGIS/Pro/bin/ArcGIS.Desktop.Framework.xsd">
<AddInInfo id="{6CB1D25C-B8BF-4A33-9099-C1F8D1B32EFC}" version="1.0" desktopVersion="3.0.34047">
<Name>Speckle</Name>
<Description>Speckle connector for ArcGIS</Description>
<Description>Next Gen Speckle Connector (Beta) for ArcGIS</Description>
<Image>Images\AddinDesktop32.png</Image>
<Author>Speckle Systems</Author>
<Company>Speckle Systems</Company>
@@ -33,14 +33,14 @@
<insertModule id="ConnectorArcGIS_Module" className="SpeckleModule" autoLoad="false" caption="SpeckleModule">
<!-- uncomment to have the control hosted on a separate tab-->
<tabs>
<!--<tab id="Speckle_Tab1" caption="New Tab">
<tab id="Speckle_Tab1" caption="Speckle">
<group refID="Speckle_Group1"/>
</tab>-->
</tab>
</tabs>
<groups>
<!-- comment this out if you have no controls on the Addin tab to avoid
an empty group-->
<group id="Speckle_Group1" caption="Speckle" appearsOnAddInTab="true" keytip="G1">
an empty group. change appearsOnAddinTab to "True" if control is to be in the addin tab-->
<group id="Speckle_Group1" caption="Speckle" appearsOnAddInTab="false" keytip="G1">
<!-- host controls within groups -->
<button refID="SpeckleDUI3_SpeckleDUI3OpenButton" size="large" />
</group>
@@ -59,7 +59,7 @@
</controls>
<dockPanes>
<dockPane id="SpeckleDUI3_SpeckleDUI3" caption="Speckle (Beta) for ArcGIS" className="SpeckleDUI3ViewModel" keytip="DockPane" initiallyVisible="true" dock="group" dockWith="esri_core_projectDockPane">
<dockPane id="SpeckleDUI3_SpeckleDUI3" caption="Speckle (Beta)" className="SpeckleDUI3ViewModel" keytip="DockPane" initiallyVisible="true" dock="group" dockWith="esri_core_projectDockPane">
<content className="SpeckleDUI3Wrapper" />
</dockPane>
</dockPanes>
@@ -10,6 +10,7 @@ using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
@@ -27,7 +28,7 @@ public static class ArcGISConnectorModule
public static void AddArcGIS(this IServiceCollection serviceCollection)
{
serviceCollection.AddConnectorUtils();
serviceCollection.AddDUI<ArcGISThreadContext, ArcGISDocumentStore>();
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
serviceCollection.AddDUIView();
// Register bindings
@@ -184,6 +184,7 @@ public class ArcGISColorUnpacker
if (StoredColor is int existingColorProxyId)
{
AddObjectIdToColorProxyCache(rowApplicationId, existingColorProxyId);
return;
}
// get the color from the renderer and row
@@ -1,6 +1,7 @@
using System.Diagnostics.Contracts;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.Utils;
@@ -53,7 +54,20 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
_colorManager = colorManager;
}
public HostObjectBuilderResult Build(
public Task<HostObjectBuilderResult> Build(
Base rootObject,
string projectName,
string modelName,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
return QueuedTask.Run(
() => BuildInternal(rootObject, projectName, modelName, onOperationProgressed, cancellationToken)
);
}
private HostObjectBuilderResult BuildInternal(
Base rootObject,
string projectName,
string modelName,
@@ -226,7 +240,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
// TODO: validated a correct set regarding bakedobject ids
return new(bakedObjectIds, results);
return new HostObjectBuilderResult(bakedObjectIds, results);
}
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
@@ -1,5 +1,6 @@
using ArcGIS.Core.Data.Raster;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
@@ -49,7 +50,14 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
_mapMemberUtils = mapMemberUtils;
}
public async Task<RootObjectBuilderResult> BuildAsync(
public Task<RootObjectBuilderResult> Build(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
private async Task<RootObjectBuilderResult> BuildInternal(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
@@ -94,19 +102,26 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
// Mapmember dynamically attached properties are also added at this step.
List<ADM.MapMember> unpackedLayers;
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
long allFeaturesCount;
ADM.Map map = ADM.MapView.Active.Map;
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
using (var _ = _activityFactory.Start("Unpacking selection"))
{
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
allFeaturesCount = layersWithFeatureCount.Values.Sum();
}
List<SendConversionResult> results = new(unpackedLayers.Count);
onOperationProgressed.Report(new("Converting", null));
using (var convertingActivity = _activityFactory.Start("Converting objects"))
{
int count = 0;
foreach (ADM.MapMember layer in unpackedLayers)
long count = 0;
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
{
cancellationToken.ThrowIfCancellationRequested();
string layerApplicationId = layer.GetSpeckleApplicationId();
@@ -134,15 +149,33 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
switch (layer)
{
case ADM.FeatureLayer featureLayer:
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(featureLayer);
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
featureLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
break;
case ADM.RasterLayer rasterLayer:
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(rasterLayer);
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
rasterLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedRasterLayerObjects);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(lasDatasetLayer);
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
lasDatasetLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedLasDatasetObjects);
break;
default:
@@ -150,6 +183,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
sdkStatus = SdkActivityStatusCode.Error;
break;
}
count += layerFeatureCount;
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
convertingActivity?.SetStatus(sdkStatus);
}
@@ -166,7 +201,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
convertingActivity?.RecordException(ex);
}
onOperationProgressed.Report(new("Converting", (double)++count / layers.Count));
await Task.Yield();
}
}
@@ -182,7 +216,41 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
return new RootObjectBuilderResult(rootCollection, results);
}
private List<Base> ConvertFeatureLayerObjects(ADM.FeatureLayer featureLayer)
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
{
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
foreach (ADM.MapMember layer in unpackedLayers)
{
switch (layer)
{
case ADM.FeatureLayer featureLayer:
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
break;
case ADM.RasterLayer rasterLayer:
// count Raster layer as 1 feature: not optimal but this is the approach for now
layersFeatureCount.Add(rasterLayer, 1);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
var dataset = lasDatasetLayer.GetLasDataset();
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
layersFeatureCount.Add(
lasDatasetLayer,
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
);
break;
}
}
return layersFeatureCount;
}
private List<Base> ConvertFeatureLayerObjects(
ADM.FeatureLayer featureLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
@@ -196,6 +264,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
{
while (rowCursor.MoveNext())
{
// allow cancellation before every feature
cancellationToken.ThrowIfCancellationRequested();
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
using (ACD.Row row = rowCursor.Current)
{
@@ -209,6 +280,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// process the object color
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
@@ -216,19 +289,38 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
}
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
private List<Base> ConvertRasterLayerObjects(ADM.RasterLayer rasterLayer)
private List<Base> ConvertRasterLayerObjects(
ADM.RasterLayer rasterLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
Raster raster = rasterLayer.GetRaster();
// check cancellation token before conversion
cancellationToken.ThrowIfCancellationRequested();
Base converted = _rootToSpeckleConverter.Convert(raster);
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
converted.applicationId = applicationId;
convertedObjects.Add(converted);
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
return convertedObjects;
}
private List<Base> ConvertLasDatasetLayerObjects(ADM.LasDatasetLayer lasDatasetLayer)
private List<Base> ConvertLasDatasetLayerObjects(
ADM.LasDatasetLayer lasDatasetLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
@@ -242,6 +334,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
{
while (ptCursor.MoveNext())
{
// allow cancellation before every point
cancellationToken.ThrowIfCancellationRequested();
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
{
Base converted = _rootToSpeckleConverter.Convert(pt);
@@ -252,6 +347,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// process the object color
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
}
@@ -1,36 +0,0 @@
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Speckle.Connectors.Common.Threading;
namespace Speckle.Connectors.ArcGIS.Utils;
//don't check for GUI as it's the same check we do in ThreadContext
public class ArcGISThreadContext : ThreadContext
{
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
{
if (QueuedTask.OnWorker)
{
return action();
}
else
{
return QueuedTask.Run(async () => await action());
}
}
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(async () => await action());
protected override Task<T> MainToWorker<T>(Func<T> action)
{
if (QueuedTask.OnWorker)
{
return Task.FromResult(action());
}
else
{
return QueuedTask.Run(action);
}
}
protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
}
@@ -1,10 +1,10 @@
using System.Xml.Linq;
using ArcGIS.Desktop.Core.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
@@ -13,18 +13,15 @@ namespace Speckle.Connectors.ArcGIS.Utils;
public class ArcGISDocumentStore : DocumentModelStore
{
private readonly IThreadContext _threadContext;
private readonly IEventAggregator _eventAggregator;
public ArcGISDocumentStore(
IJsonSerializer jsonSerializer,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
IThreadContext threadContext
)
: base(jsonSerializer)
{
_threadContext = threadContext;
_eventAggregator = eventAggregator;
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
ProjectSavingEvent.Subscribe(
_ =>
@@ -42,16 +39,13 @@ public class ArcGISDocumentStore : DocumentModelStore
},
true
);
}
public override async Task OnDocumentStoreInitialized()
{
// in case plugin was loaded into already opened Map, read metadata from the current Map
if (!IsDocumentInit && MapView.Active != null)
{
IsDocumentInit = true;
LoadState();
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
OnDocumentChanged();
}
}
@@ -76,7 +70,7 @@ public class ArcGISDocumentStore : DocumentModelStore
/// <summary>
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
/// </summary>
private async void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
{
if (args.IncomingView is null)
{
@@ -85,12 +79,12 @@ public class ArcGISDocumentStore : DocumentModelStore
IsDocumentInit = true;
LoadState();
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
OnDocumentChanged();
}
protected override void HostAppSaveState(string modelCardState) =>
_threadContext
.RunOnWorker(() =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
@@ -119,8 +113,8 @@ public class ArcGISDocumentStore : DocumentModelStore
.FireAndForget();
protected override void LoadState() =>
_threadContext
.RunOnWorker(() =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
var metadata = map.GetMetadata();
@@ -166,11 +166,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -226,14 +221,21 @@
"resolved": "4.5.1",
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
},
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.connectors.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -241,8 +243,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -259,6 +261,7 @@
"type": "Project",
"dependencies": {
"Esri.ArcGISPro.Extensions30": "[3.2.0.49743, )",
"Speckle.Common.MeshTriangulation": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )"
}
},
@@ -266,9 +269,15 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"LibTessDotNet": {
"type": "CentralTransitive",
"requested": "[1.1.15, )",
"resolved": "1.1.15",
"contentHash": "KuA7N3Nv/lIeawJdQBQJR6oqWD9KETHLbWzBqapwFs+Tby+R5I4crkKujKMm5bXcSuFZ8LNtflFQVadsWCbBjg=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -296,37 +305,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
"net6.0-windows7.0/win-x64": {
@@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -164,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -264,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -274,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -299,7 +294,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -335,37 +330,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -164,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -264,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -274,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -299,7 +294,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -335,37 +330,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -164,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -264,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -274,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -300,7 +295,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,37 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -13,8 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" />
<FrameworkReference Include="Microsoft.WindowsDesktop.App"/>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -155,11 +155,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -220,9 +215,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -230,8 +225,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -256,7 +251,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -292,36 +287,42 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -4,7 +4,6 @@ using Speckle.Connectors.Autocad.HostApp.Extensions;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
@@ -22,6 +21,7 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
private readonly DocumentModelStore _store;
private readonly ISpeckleApplication _speckleApplication;
private readonly IThreadContext _threadContext;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly ILogger<AutocadBasicConnectorBinding> _logger;
public BasicConnectorBindingCommands Commands { get; }
@@ -32,8 +32,8 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
IAccountManager accountManager,
ISpeckleApplication speckleApplication,
ILogger<AutocadBasicConnectorBinding> logger,
IEventAggregator eventAggregator,
IThreadContext threadContext
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_store = store;
@@ -41,13 +41,16 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
_accountManager = accountManager;
_speckleApplication = speckleApplication;
Commands = new BasicConnectorBindingCommands(parent);
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
_logger = logger;
_threadContext = threadContext;
_topLevelExceptionHandler = topLevelExceptionHandler;
_store.DocumentChanged += (_, _) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await Commands.NotifyDocumentChanged();
});
}
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
public string GetSourceApplicationName() => _speckleApplication.Slug;
@@ -76,6 +79,8 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
{
// POC: Will be addressed to move it into AutocadContext!
@@ -0,0 +1,119 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
namespace Speckle.Connectors.Autocad.Bindings;
public abstract class AutocadReceiveBaseBinding : IReceiveBinding
{
public string Name => "receiveBinding";
public IBrowserBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly ICancellationManager _cancellationManager;
private readonly IServiceProvider _serviceProvider;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<AutocadReceiveBinding> _logger;
private readonly ISpeckleApplication _speckleApplication;
private readonly IThreadContext _threadContext;
private ReceiveBindingUICommands Commands { get; }
protected AutocadReceiveBaseBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
)
{
_store = store;
_cancellationManager = cancellationManager;
_serviceProvider = serviceProvider;
_operationProgressManager = operationProgressManager;
_logger = logger;
_speckleApplication = speckleApplication;
_threadContext = threadContext;
Parent = parent;
Commands = new ReceiveBindingUICommands(parent);
}
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
public async Task Receive(string modelCardId) =>
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
private async Task ReceiveInternal(string modelCardId)
{
using var scope = _serviceProvider.CreateScope();
InitializeSettings(scope.ServiceProvider);
try
{
// Get receiver card
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No download model card was found.");
}
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
Application.DocumentManager.DocumentActivationEnabled = false;
// Receive host objects
var operationResults = await scope
.ServiceProvider.GetRequiredService<ReceiveOperation>()
.Execute(
modelCard.GetReceiveInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelReceiveResult(
modelCardId,
operationResults.BakedObjectIds,
operationResults.ConversionResults
);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
finally
{
// reenable document activation
Application.DocumentManager.DocumentActivationEnabled = true;
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
Application.DocumentManager.CurrentDocument.Editor.Regen();
}
}
}
@@ -1,110 +1,49 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converters.Autocad;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Autocad.Bindings;
public sealed class AutocadReceiveBinding : IReceiveBinding
public sealed class AutocadReceiveBinding : AutocadReceiveBaseBinding
{
public string Name => "receiveBinding";
public IBrowserBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly CancellationManager _cancellationManager;
private readonly IServiceProvider _serviceProvider;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<AutocadReceiveBinding> _logger;
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
private readonly ISpeckleApplication _speckleApplication;
private ReceiveBindingUICommands Commands { get; }
public AutocadReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication
ISpeckleApplication speckleApplication,
IThreadContext threadContext
)
: base(
store,
parent,
cancellationManager,
serviceProvider,
operationProgressManager,
logger,
speckleApplication,
threadContext
)
{
_store = store;
_cancellationManager = cancellationManager;
_serviceProvider = serviceProvider;
_operationProgressManager = operationProgressManager;
_logger = logger;
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
_speckleApplication = speckleApplication;
Parent = parent;
Commands = new ReceiveBindingUICommands(parent);
}
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
public async Task Receive(string modelCardId)
protected override void InitializeSettings(IServiceProvider serviceProvider)
{
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
serviceProvider
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
try
{
// Get receiver card
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No download model card was found.");
}
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
Application.DocumentManager.DocumentActivationEnabled = false;
// Receive host objects
var operationResults = await scope
.ServiceProvider.GetRequiredService<ReceiveOperation>()
.Execute(
modelCard.GetReceiveInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
cancellationToken
);
await Commands.SetModelReceiveResult(
modelCardId,
operationResults.BakedObjectIds,
operationResults.ConversionResults
);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
finally
{
// reenable document activation
Application.DocumentManager.DocumentActivationEnabled = true;
}
}
}
@@ -9,9 +9,9 @@ namespace Speckle.Connectors.Autocad.Bindings;
public class AutocadSelectionBinding : ISelectionBinding
{
private const string SELECTION_EVENT = "setSelection";
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
private const string SELECTION_EVENT = "setSelection";
private readonly HashSet<Document> _visitedDocuments = new();
public string Name => "selectionBinding";
@@ -20,13 +20,13 @@ public class AutocadSelectionBinding : ISelectionBinding
public AutocadSelectionBinding(
IBrowserBridge parent,
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
{
_topLevelExceptionHandler = topLevelExceptionHandler;
Parent = parent;
_threadContext = threadContext;
Parent = parent;
// POC: Use here Context for doc. In converters it's OK but we are still lacking to use context into bindings.
// It is with the case of if binding created with already a document
@@ -1,8 +1,8 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using Autodesk.AutoCAD.DatabaseServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Autocad.HostApp.Extensions;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Caching;
@@ -11,7 +11,6 @@ using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
@@ -23,6 +22,7 @@ using Speckle.Sdk.Common;
namespace Speckle.Connectors.Autocad.Bindings;
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
public abstract class AutocadSendBaseBinding : ISendBinding
{
public string Name => "sendBinding";
@@ -31,16 +31,16 @@ public abstract class AutocadSendBaseBinding : ISendBinding
public IBrowserBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly IAutocadIdleManager _idleManager;
private readonly List<ISendFilter> _sendFilters;
private readonly CancellationManager _cancellationManager;
private readonly ICancellationManager _cancellationManager;
private readonly IServiceProvider _serviceProvider;
private readonly ISendConversionCache _sendConversionCache;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<AutocadSendBinding> _logger;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly ISpeckleApplication _speckleApplication;
private readonly IThreadContext _threadContext;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IAppIdleManager _idleManager;
/// <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,26 +48,24 @@ public abstract class AutocadSendBaseBinding : ISendBinding
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
/// </summary>
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
private ConcurrentBag<string> ChangedObjectIds { get; set; } = new();
protected AutocadSendBaseBinding(
DocumentModelStore store,
IAutocadIdleManager idleManager,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager idleManager
)
{
_store = store;
_idleManager = idleManager;
_serviceProvider = serviceProvider;
_cancellationManager = cancellationManager;
_sendFilters = sendFilters.ToList();
@@ -77,6 +75,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
_speckleApplication = speckleApplication;
_threadContext = threadContext;
_topLevelExceptionHandler = topLevelExceptionHandler;
_idleManager = idleManager;
Parent = parent;
Commands = new SendBindingUICommands(parent);
@@ -89,12 +88,12 @@ public abstract class AutocadSendBaseBinding : ISendBinding
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
}
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
_store.DocumentChanged += (_, _) =>
{
_sendConversionCache.ClearCache();
};
}
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
private readonly List<string> _docSubsTracker = new();
private void SubscribeToObjectChanges(Document doc)
@@ -110,28 +109,25 @@ public abstract class AutocadSendBaseBinding : ISendBinding
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
}
private void OnObjectChanged(DBObject dbObject)
{
private void OnObjectChanged(DBObject dbObject) =>
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
}
private void OnChangeChangedObjectIds(DBObject dBObject)
{
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), async () => await RunExpirationChecks());
ChangedObjectIds.Add(dBObject.GetSpeckleApplicationId());
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), async () => await RunExpirationChecks());
}
private async Task RunExpirationChecks()
{
var senders = _store.GetSenders();
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
List<string> expiredSenderIds = new();
_sendConversionCache.EvictObjects(objectIdsList);
_sendConversionCache.EvictObjects(ChangedObjectIds);
foreach (SenderModelCard modelCard in senders)
{
var intersection = modelCard.SendFilter.NotNull().RefreshObjectIds().Intersect(objectIdsList).ToList();
var intersection = modelCard.SendFilter.NotNull().RefreshObjectIds().Intersect(ChangedObjectIds).ToList();
bool isExpired = intersection.Count != 0;
if (isExpired)
{
@@ -148,7 +144,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
public List<ICardSetting> GetSendSettings() => [];
public async Task Send(string modelCardId) =>
await _threadContext.RunOnWorkerAsync(async () => await SendInternal(modelCardId));
await _threadContext.RunOnMainAsync(async () => await SendInternal(modelCardId));
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
@@ -165,7 +161,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
using var scope = _serviceProvider.CreateScope();
InitializeSettings(scope.ServiceProvider);
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
@@ -187,9 +183,9 @@ public abstract class AutocadSendBaseBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
.Execute(
autocadObjects,
modelCard.GetSendInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
cancellationToken
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
@@ -1,12 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Converters.Autocad;
@@ -21,23 +19,21 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
public AutocadSendBinding(
DocumentModelStore store,
IAutocadIdleManager idleManager,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager appIdleManager
)
: base(
store,
idleManager,
parent,
sendFilters,
cancellationManager,
@@ -46,9 +42,9 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
operationProgressManager,
logger,
speckleApplication,
topLevelExceptionHandler,
threadContext,
eventAggregator
topLevelExceptionHandler,
appIdleManager
)
{
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
@@ -1,5 +1,4 @@
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
@@ -7,22 +6,21 @@ namespace Speckle.Connectors.Autocad.HostApp;
public class AutocadDocumentStore : DocumentModelStore
{
private readonly string _nullDocumentName = "Null Doc";
private const string NULL_DOCUMENT_NAME = "Null Doc";
private string _previousDocName;
private readonly AutocadDocumentManager _autocadDocumentManager;
private readonly IEventAggregator _eventAggregator;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public AutocadDocumentStore(
IJsonSerializer jsonSerializer,
AutocadDocumentManager autocadDocumentManager,
ITopLevelExceptionHandler topLevelExceptionHandler,
IEventAggregator eventAggregator
ITopLevelExceptionHandler topLevelExceptionHandler
)
: base(jsonSerializer)
{
_autocadDocumentManager = autocadDocumentManager;
_eventAggregator = eventAggregator;
_previousDocName = _nullDocumentName;
_topLevelExceptionHandler = topLevelExceptionHandler;
_previousDocName = NULL_DOCUMENT_NAME;
// POC: Will be addressed to move it into AutocadContext!
if (Application.DocumentManager.MdiActiveDocument != null)
@@ -42,9 +40,9 @@ public class AutocadDocumentStore : DocumentModelStore
// OnDocChangeInternal((Document)args.DocumentWindow.Document);
}
private async void OnDocChangeInternal(Document? doc)
private void OnDocChangeInternal(Document? doc)
{
var currentDocName = doc != null ? doc.Name : _nullDocumentName;
var currentDocName = doc != null ? doc.Name : NULL_DOCUMENT_NAME;
if (_previousDocName == currentDocName)
{
return;
@@ -52,7 +50,7 @@ public class AutocadDocumentStore : DocumentModelStore
_previousDocName = currentDocName;
LoadState();
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
OnDocumentChanged();
}
protected override void LoadState()
@@ -12,10 +12,7 @@ public sealed class AutocadIdleManager(IIdleCallManager idleCallManager)
{
private readonly IIdleCallManager _idleCallManager = idleCallManager;
protected override void AddEvent()
{
Application.Idle += AutocadAppOnIdle;
}
protected override void AddEvent() => Application.Idle += AutocadAppOnIdle;
private void AutocadAppOnIdle(object? sender, EventArgs e) =>
_idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
@@ -31,7 +31,7 @@ public class AutocadHostObjectBuilder(
RootObjectUnpacker rootObjectUnpacker
) : IHostObjectBuilder
{
public HostObjectBuilderResult Build(
public Task<HostObjectBuilderResult> Build(
Base rootObject,
string projectName,
string modelName,
@@ -83,7 +83,7 @@ public class AutocadHostObjectBuilder(
colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
}
// 5 - Convert atomic objects
// 4 - Convert atomic objects
HashSet<ReceiveConversionResult> results = new();
HashSet<string> bakedObjectIds = new();
Dictionary<string, IReadOnlyCollection<Entity>> applicationIdMap = new();
@@ -116,7 +116,7 @@ public class AutocadHostObjectBuilder(
}
}
// 6 - Convert instances
// 5 - Convert instances
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = instanceBaker.BakeInstances(
instanceComponentsWithPath,
applicationIdMap,
@@ -129,7 +129,7 @@ public class AutocadHostObjectBuilder(
results.RemoveWhere(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
results.UnionWith(instanceConversionResults);
// 7 - Create groups
// 6 - Create groups
if (unpackedRoot.GroupProxies != null)
{
IReadOnlyCollection<ReceiveConversionResult> groupResults = groupBaker.CreateGroups(
@@ -139,7 +139,7 @@ public class AutocadHostObjectBuilder(
results.UnionWith(groupResults);
}
return new HostObjectBuilderResult(bakedObjectIds, results);
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
}
private void PreReceiveDeepClean(string baseLayerPrefix)
@@ -160,15 +160,21 @@ public class AutocadHostObjectBuilder(
var converted = converter.Convert(obj);
// 2: handle result
if (converted is Entity entity)
switch (converted)
{
var bakedEntity = BakeObject(entity, obj, layerName);
convertedEntities.Add(bakedEntity);
}
else if (converted is List<(Entity, Base)> fallbackConversionResult)
{
var bakedFallbackEntities = BakeObjectsAsGroup(fallbackConversionResult, obj, layerName, baseLayerNamePrefix);
convertedEntities.UnionWith(bakedFallbackEntities);
case Entity entity:
var bakedEntity = BakeObject(entity, obj, layerName);
convertedEntities.Add(bakedEntity);
break;
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix);
convertedEntities.UnionWith(bakedFallbackEntities);
break;
default:
// TODO: capture defualt case with report object here? Same as in Rhino
break;
}
tr.Commit();
@@ -208,6 +214,11 @@ public class AutocadHostObjectBuilder(
entities.Add(conversionResult);
}
if (entities.Count <= 1) // return if empty list or only one, because we don't want to create empty or single item groups.
{
return entities;
}
var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.TopTransaction;
var groupDictionary = (DBDictionary)
tr.GetObject(Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId, OpenMode.ForWrite);
@@ -16,7 +16,7 @@ using Speckle.Sdk.Models.Instances;
namespace Speckle.Connectors.Autocad.Operations.Send;
public abstract class AutocadRootObjectBaseBuilder : RootObjectBuilderBase<AutocadRootObject>
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadRootObject>
{
private readonly IRootToSpeckleConverter _converter;
private readonly string[] _documentPathSeparator = ["\\"];
@@ -58,7 +58,7 @@ public abstract class AutocadRootObjectBaseBuilder : RootObjectBuilderBase<Autoc
proxy classes yet. So I'm supressing this one now!!!
"""
)]
public override RootObjectBuilderResult Build(
public Task<RootObjectBuilderResult> Build(
IReadOnlyList<AutocadRootObject> objects,
SendInfo sendInfo,
IProgress<CardProgress> onOperationProgressed,
@@ -133,7 +133,7 @@ public abstract class AutocadRootObjectBaseBuilder : RootObjectBuilderBase<Autoc
// add any additional properties (most likely from verticals)
AddAdditionalProxiesToRoot(root);
return new RootObjectBuilderResult(root, results);
return Task.FromResult(new RootObjectBuilderResult(root, results));
}
}
@@ -31,7 +31,7 @@ public class AutocadCommand
return;
}
PaletteSet = new PaletteSet($"Speckle (Beta) for {AppUtils.App.Name}", s_id)
PaletteSet = new PaletteSet($"Speckle (Beta)", s_id)
{
Size = new Size(400, 500),
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right)
@@ -52,7 +52,7 @@ public class AutocadCommand
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
PaletteSet.AddVisual($"Speckle (Beta) for {AppUtils.App.Name} WebView", panelWebView);
PaletteSet.AddVisual("Speckle (Beta)", panelWebView);
FocusPalette();
}
@@ -46,20 +46,20 @@ public class AutocadRibbon
private void Create()
{
RibbonTab tab = FindOrMakeTab("Add-ins");
RibbonPanelSource source = new() { Title = "Speckle 2 (New Beta)" };
RibbonTab tab = FindOrMakeTab("Speckle");
RibbonPanelSource source = new() { Title = "Speckle (Beta)" };
RibbonPanel panel = new() { Source = source };
tab.Panels.Add(panel);
RibbonToolTip speckleToolTip =
new()
{
Title = "Speckle 2 (New Beta)",
Content = "Speckle Connector for " + AppUtils.App.Name,
Title = "Speckle (Beta)",
Content = $"Next Gen Speckle Connector (Beta) for {AppUtils.App.Name}",
IsHelpEnabled = true // Without this "Press F1 for help" does not appear in the tooltip
};
_ = CreateSpeckleButton("Connector " + AppUtils.App.Name + " (New)", source, null, speckleToolTip, "logo");
_ = CreateSpeckleButton("Speckle (Beta)", source, null, speckleToolTip, "logo");
}
private void ComponentManager_ItemInitialized(object? sender, RibbonItemEventArgs e)
@@ -9,6 +9,7 @@
<Import_RootNamespace>Speckle.Connectors.AutocadShared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBaseBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSelectionBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBinding.cs" />
@@ -21,6 +22,7 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadGroupBaker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadGroupUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadInstanceBaker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadInstanceUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadLayerBaker.cs" />
@@ -29,7 +31,6 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadDocumentManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadDocumentModelStore.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadMaterialUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Extensions\DatabaseExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Extensions\DocumentExtensions.cs" />
@@ -10,8 +10,8 @@
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" />
<PackageReference Include="Speckle.Civil3D.API" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2022.0.2" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -173,11 +173,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -309,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -345,37 +340,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -11,8 +11,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" />
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -173,11 +173,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -309,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -345,37 +340,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -11,8 +11,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" />
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2024.0.0" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -173,11 +173,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -309,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -345,37 +340,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -13,9 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" />
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" />
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -164,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -229,9 +224,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -239,8 +234,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -266,7 +261,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -302,36 +297,42 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -0,0 +1,60 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.Bindings;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Converters.Autocad;
using Speckle.Converters.Civil3dShared;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Civil3dShared.Bindings;
public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
{
private readonly ICivil3dConversionSettingsFactory _civil3dConversionSettingsFactory;
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
public Civil3dReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
)
: base(
store,
parent,
cancellationManager,
serviceProvider,
operationProgressManager,
logger,
speckleApplication,
threadContext
)
{
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
}
// POC: we're registering the conversion settings for autocad here because we need the autocad conversion settings to be able to use the autocad typed converters.
// POC: We need a separate receive binding for civil3d due to using a different unit converter (needed for conversion settings construction)
protected override void InitializeSettings(IServiceProvider serviceProvider)
{
serviceProvider
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
.Initialize(_civil3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
serviceProvider
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
}
}
@@ -1,13 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.Bindings;
using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Converters.Autocad;
@@ -24,10 +22,9 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
public Civil3dSendBinding(
DocumentModelStore store,
IAutocadIdleManager idleManager,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
@@ -35,13 +32,12 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager appIdleManager
)
: base(
store,
idleManager,
parent,
sendFilters,
cancellationManager,
@@ -50,9 +46,9 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
operationProgressManager,
logger,
speckleApplication,
topLevelExceptionHandler,
threadContext,
eventAggregator
topLevelExceptionHandler,
appIdleManager
)
{
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
@@ -6,7 +6,6 @@ using Speckle.Connectors.Civil3dShared.Bindings;
using Speckle.Connectors.Civil3dShared.Operations.Send;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Converters.Civil3dShared.Helpers;
using Speckle.Converters.Civil3dShared.ToSpeckle;
using Speckle.Sdk;
@@ -17,18 +16,20 @@ public static class Civil3dConnectorModule
public static void AddCivil3d(this IServiceCollection serviceCollection)
{
serviceCollection.AddAutocadBase();
serviceCollection.LoadSend();
// register civil specific send classes
// add send
serviceCollection.LoadSend();
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
serviceCollection.AddSingleton<IBinding, Civil3dSendBinding>();
// automatically detects the Class:IClass interface pattern to register all generated interfaces
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
// add receive
serviceCollection.LoadReceive();
serviceCollection.AddSingleton<IBinding, Civil3dReceiveBinding>();
// additional classes
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
serviceCollection.AddScoped<CatchmentGroupHandler>();
serviceCollection.AddScoped<PipeNetworkHandler>();
// automatically detects the Class:IClass interface pattern to register all generated interfaces
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
}
}
@@ -4,7 +4,6 @@ using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.Civil3dShared.Helpers;
using Speckle.Converters.Civil3dShared.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Sdk.Logging;
@@ -16,14 +15,10 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
{
private readonly AutocadLayerUnpacker _layerUnpacker;
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
private readonly CatchmentGroupHandler _catchmentGroupHandler;
private readonly PipeNetworkHandler _pipeNetworkHandler;
public Civil3dRootObjectBuilder(
AutocadLayerUnpacker layerUnpacker,
PropertySetDefinitionHandler propertySetDefinitionHandler,
CatchmentGroupHandler catchmentGroupHandler,
PipeNetworkHandler pipeNetworkHandler,
IRootToSpeckleConverter converter,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
@@ -46,8 +41,6 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
{
_layerUnpacker = layerUnpacker;
_propertySetDefinitionHandler = propertySetDefinitionHandler;
_catchmentGroupHandler = catchmentGroupHandler;
_pipeNetworkHandler = pipeNetworkHandler;
}
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
@@ -57,11 +50,8 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
return (layer, autocadLayer);
}
// POC: probably will need to add Network proxies as well
public override void AddAdditionalProxiesToRoot(Collection rootObject)
{
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
}
}
@@ -9,13 +9,13 @@
<Import_RootNamespace>Speckle.Connectors.Civil3dShared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dReceiveBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dRootObjectBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dSendBinding.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
<Folder Include="$(MSBuildThisFileDirectory)Bindings\" />
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
</ItemGroup>
</Project>
@@ -1,4 +1,5 @@
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
@@ -10,7 +11,8 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
{
private readonly ISpeckleApplication _speckleApplication;
private readonly DocumentModelStore _store;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
public string Name => "baseBinding";
public IBrowserBridge Parent { get; }
public BasicConnectorBindingCommands Commands { get; }
@@ -18,13 +20,27 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
public CsiSharedBasicConnectorBinding(
IBrowserBridge parent,
ISpeckleApplication speckleApplication,
DocumentModelStore store
DocumentModelStore store,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
{
_threadContext = threadContext;
Parent = parent;
_speckleApplication = speckleApplication;
_store = store;
Commands = new BasicConnectorBindingCommands(parent);
_topLevelExceptionHandler = topLevelExceptionHandler;
Commands = new BasicConnectorBindingCommands(Parent);
_store.DocumentChanged += (_, _) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
// enforce main thread
await _threadContext.RunOnMainAsync(async () =>
{
await Commands.NotifyDocumentChanged();
});
});
}
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
@@ -33,15 +49,24 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
public DocumentInfo? GetDocumentInfo() => new DocumentInfo("ETABS Model", "ETABS Model", "1");
public DocumentInfo? GetDocumentInfo() => new("ETABS Model", "ETABS Model", "1");
public DocumentModelStore GetDocumentState() => _store;
public void AddModel(ModelCard model) => _store.AddModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void AddModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.AddModel(model), true));
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void UpdateModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.UpdateModel(model), true));
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void RemoveModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModel(model), true));
public void RemoveModels(List<ModelCard> models) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModels(models), true));
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
@@ -1,21 +1,78 @@
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.CSiShared.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Converters.CSiShared.Utils;
using Timer = System.Timers.Timer;
namespace Speckle.Connectors.CSiShared.Bindings;
public class CsiSharedSelectionBinding : ISelectionBinding
public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
{
public string Name => "selectionBinding";
public IBrowserBridge Parent { get; }
private bool _disposed;
private readonly Timer _selectionTimer;
private readonly ICsiApplicationService _csiApplicationService;
private readonly IThreadContext _threadContext;
private HashSet<string> _lastSelection = new();
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public CsiSharedSelectionBinding(IBrowserBridge parent, ICsiApplicationService csiApplicationService)
public IBrowserBridge Parent { get; }
public string Name => "selectionBinding";
public CsiSharedSelectionBinding(
IBrowserBridge parent,
ICsiApplicationService csiApplicationService,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
{
_threadContext = threadContext;
Parent = parent;
_csiApplicationService = csiApplicationService;
_topLevelExceptionHandler = topLevelExceptionHandler;
_selectionTimer = new Timer(1000);
_selectionTimer.Elapsed += (_, _) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckSelectionChanged));
_selectionTimer.Start();
}
private void CheckSelectionChanged()
{
// timer callbacks are on a background thread, but CSI API calls must be on main thread
var currentSelection = GetSelection();
var currentIds = new HashSet<string>(currentSelection.SelectedObjectIds);
if (!_lastSelection.SetEquals(currentIds))
{
_lastSelection = currentIds;
// ensure UI updates also run on main thread
_threadContext.RunOnMain(
() =>
_topLevelExceptionHandler.CatchUnhandled(
() => Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection)
)
);
}
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_selectionTimer?.Dispose();
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
@@ -27,29 +84,25 @@ public class CsiSharedSelectionBinding : ISelectionBinding
public SelectionInfo GetSelection()
{
int numberItems = 0;
int[] objectType = Array.Empty<int>();
string[] objectName = Array.Empty<string>();
int[] objectType = [];
string[] objectName = [];
_csiApplicationService.SapModel.SelectObj.GetSelected(ref numberItems, ref objectType, ref objectName);
var encodedIds = new List<string>(numberItems);
var typeCounts = new Dictionary<string, int>();
for (int i = 0; i < numberItems; i++)
{
var typeKey = (ModelObjectType)objectType[i];
var typeName = typeKey.ToString();
encodedIds.Add(ObjectIdentifier.Encode(objectType[i], objectName[i]));
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
}
var summary =
encodedIds.Count == 0
? "No objects selected."
: $"{encodedIds.Count} objects ({string.Join(", ",
typeCounts.Select(kv => $"{kv.Value} {kv.Key}"))})";
return new SelectionInfo(encodedIds, summary);
}
}
@@ -29,7 +29,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly CancellationManager _cancellationManager;
private readonly ICancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<CsiSharedSendBinding> _logger;
private readonly ICsiApplicationService _csiApplicationService;
@@ -42,7 +42,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IOperationProgressManager operationProgressManager,
ILogger<CsiSharedSendBinding> logger,
ICsiConversionSettingsFactory csiConversionSettingsFactory,
@@ -84,7 +84,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
.Initialize(_csiConversionSettingsFactory.Create(_csiApplicationService.SapModel));
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
List<ICsiWrapper> wrappers = modelCard
.SendFilter.NotNull()
@@ -101,9 +101,9 @@ public sealed class CsiSharedSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
.Execute(
wrappers,
modelCard.GetSendInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
cancellationToken
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
@@ -1,5 +1,3 @@
using Speckle.Sdk.Common;
namespace Speckle.Connectors.CSiShared.HostApp;
/// <summary>
@@ -15,19 +13,4 @@ namespace Speckle.Connectors.CSiShared.HostApp;
public interface ICsiApplicationService
{
cSapModel SapModel { get; }
void Initialize(cSapModel sapModel, cPluginCallback pluginCallback);
}
public class CsiApplicationService : ICsiApplicationService
{
private cSapModel? _sapModel;
public cSapModel SapModel => _sapModel.NotNull();
private cPluginCallback? _pluginCallback;
public void Initialize(cSapModel sapModel, cPluginCallback pluginCallback)
{
_sapModel = sapModel;
_pluginCallback = pluginCallback;
}
}
@@ -1,46 +1,99 @@
using System.IO;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
using Speckle.Sdk;
using Speckle.Sdk.Helpers;
using Speckle.Sdk.Logging;
using Timer = System.Timers.Timer;
namespace Speckle.Connectors.CSiShared.HostApp;
public class CsiDocumentModelStore : DocumentModelStore
public class CsiDocumentModelStore : DocumentModelStore, IDisposable
{
private readonly ISpeckleApplication _speckleApplication;
private readonly ILogger<CsiDocumentModelStore> _logger;
private readonly ICsiApplicationService _csiApplicationService;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
private readonly Timer _modelCheckTimer;
private string _lastModelFilename = string.Empty;
private bool _disposed;
private string HostAppUserDataPath { get; set; }
private string DocumentStateFile { get; set; }
private string ModelPathHash { get; set; }
public CsiDocumentModelStore(
IJsonSerializer jsonSerializerSettings,
IJsonSerializer jsonSerializer,
ISpeckleApplication speckleApplication,
ILogger<CsiDocumentModelStore> logger,
ICsiApplicationService csiApplicationService
ICsiApplicationService csiApplicationService,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
: base(jsonSerializerSettings)
: base(jsonSerializer)
{
_threadContext = threadContext;
_speckleApplication = speckleApplication;
_logger = logger;
_csiApplicationService = csiApplicationService;
_topLevelExceptionHandler = topLevelExceptionHandler;
// initialize timer to check for model changes
_modelCheckTimer = new Timer(1000);
// timer runs on background thread but model checks must be on main thread
_modelCheckTimer.Elapsed += (_, _) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckModelChanges));
_modelCheckTimer.Start();
}
private void CheckModelChanges()
{
string currentFilename = _csiApplicationService.SapModel.GetModelFilename();
if (string.IsNullOrEmpty(currentFilename) || currentFilename == _lastModelFilename)
{
return;
}
_lastModelFilename = currentFilename;
SetPaths();
LoadState();
OnDocumentChanged();
}
public override Task OnDocumentStoreInitialized()
{
var currentFilename = _csiApplicationService.SapModel.GetModelFilename();
if (!string.IsNullOrEmpty(currentFilename))
{
_lastModelFilename = currentFilename;
SetPaths();
LoadState();
}
return Task.CompletedTask;
}
private void SetPaths()
{
ModelPathHash = Crypt.Md5(_csiApplicationService.SapModel.GetModelFilepath(), length: 32);
HostAppUserDataPath = Path.Combine(
SpecklePathProvider.UserSpeckleFolderPath,
"ConnectorsFileData",
_speckleApplication.Slug
);
DocumentStateFile = Path.Combine(HostAppUserDataPath, $"{ModelPathHash}.json");
try
{
ModelPathHash = Crypt.Md5(_csiApplicationService.SapModel.GetModelFilename(), length: 32);
HostAppUserDataPath = Path.Combine(
SpecklePathProvider.UserSpeckleFolderPath,
"ConnectorsFileData",
_speckleApplication.Slug
);
DocumentStateFile = Path.Combine(HostAppUserDataPath, $"{ModelPathHash}.json");
_logger.LogDebug($"Paths set - Hash: {ModelPathHash}, File: {DocumentStateFile}");
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Error in setting paths for CsiDocumentModelStore");
}
}
protected override void HostAppSaveState(string modelCardState)
@@ -51,29 +104,53 @@ public class CsiDocumentModelStore : DocumentModelStore
{
Directory.CreateDirectory(HostAppUserDataPath);
}
File.WriteAllText(DocumentStateFile, modelCardState);
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex.Message);
_logger.LogError(ex, "Failed to save state");
}
}
protected override void LoadState()
{
if (!Directory.Exists(HostAppUserDataPath))
try
{
if (!File.Exists(DocumentStateFile))
{
ClearAndSave();
return;
}
string serializedState = File.ReadAllText(DocumentStateFile);
LoadFromString(serializedState);
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to load state, initializing empty state");
ClearAndSave();
}
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (!File.Exists(DocumentStateFile))
if (disposing)
{
ClearAndSave();
return;
_modelCheckTimer.Dispose();
}
string serializedState = File.ReadAllText(DocumentStateFile);
LoadFromString(serializedState);
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
@@ -34,11 +34,8 @@ public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
_settingsStore.Current.SapModel.PropFrame.GetMaterial(sectionName, ref materialName);
// append to General Data of properties dictionary
Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.GENERAL_DATA
);
generalData["material"] = materialName;
Dictionary<string, object?> generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Material"] = materialName;
}
private void GetSectionProperties(string sectionName, Dictionary<string, object?> properties)
@@ -72,22 +69,26 @@ public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
ref radiusOfGyrationAboutMinorAxis
);
Dictionary<string, object?> mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(
properties,
string distanceUnit = _settingsStore.Current.SpeckleUnits;
string areaUnit = $"{distanceUnit}²"; // // TODO: Formalize this better
string modulusUnit = $"{distanceUnit}³"; // // TODO: Formalize this better
string inertiaUnit = $"{distanceUnit}\u2074"; // TODO: Formalize this better
Dictionary<string, object?> mechanicalProperties = properties.EnsureNested(
SectionPropertyCategory.SECTION_PROPERTIES
);
mechanicalProperties["area"] = crossSectionalArea;
mechanicalProperties["As2"] = shearAreaInMajorAxisDirection;
mechanicalProperties["As3"] = shearAreaInMinorAxisDirection;
mechanicalProperties["torsion"] = torsionalConstant;
mechanicalProperties["I22"] = momentOfInertiaAboutMajorAxis;
mechanicalProperties["I33"] = momentOfInertiaAboutMinorAxis;
mechanicalProperties["S22"] = sectionModulusAboutMajorAxis;
mechanicalProperties["S33"] = sectionModulusAboutMinorAxis;
mechanicalProperties["Z22"] = plasticModulusAboutMajorAxis;
mechanicalProperties["Z33"] = plasticModulusAboutMinorAxis;
mechanicalProperties["R22"] = radiusOfGyrationAboutMajorAxis;
mechanicalProperties["R33"] = radiusOfGyrationAboutMinorAxis;
mechanicalProperties.AddWithUnits("Area", crossSectionalArea, areaUnit);
mechanicalProperties.AddWithUnits("As2", shearAreaInMajorAxisDirection, areaUnit);
mechanicalProperties.AddWithUnits("As3", shearAreaInMinorAxisDirection, areaUnit);
mechanicalProperties.AddWithUnits("J", torsionalConstant, inertiaUnit);
mechanicalProperties.AddWithUnits("I22", momentOfInertiaAboutMajorAxis, inertiaUnit);
mechanicalProperties.AddWithUnits("I33", momentOfInertiaAboutMinorAxis, inertiaUnit);
mechanicalProperties.AddWithUnits("S22", sectionModulusAboutMajorAxis, modulusUnit);
mechanicalProperties.AddWithUnits("S33", sectionModulusAboutMinorAxis, modulusUnit);
mechanicalProperties.AddWithUnits("Z22", plasticModulusAboutMajorAxis, modulusUnit);
mechanicalProperties.AddWithUnits("Z33", plasticModulusAboutMinorAxis, modulusUnit);
mechanicalProperties.AddWithUnits("R22", radiusOfGyrationAboutMajorAxis, distanceUnit);
mechanicalProperties.AddWithUnits("R33", radiusOfGyrationAboutMinorAxis, distanceUnit);
}
private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
@@ -98,20 +99,17 @@ public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
Dictionary<string, object?> modifiers =
new()
{
["crossSectionalAreaModifier"] = stiffnessModifiersArray[0],
["shearAreaInLocal2DirectionModifier"] = stiffnessModifiersArray[1],
["shearAreaInLocal3DirectionModifier"] = stiffnessModifiersArray[2],
["torsionalConstantModifier"] = stiffnessModifiersArray[3],
["momentOfInertiaAboutLocal2AxisModifier"] = stiffnessModifiersArray[4],
["momentOfInertiaAboutLocal3AxisModifier"] = stiffnessModifiersArray[5],
["mass"] = stiffnessModifiersArray[6],
["weight"] = stiffnessModifiersArray[7],
["Cross-section (Axial) Area"] = stiffnessModifiersArray[0],
["Shear Area in 2 Direction"] = stiffnessModifiersArray[1],
["Shear Area in 3 Direction"] = stiffnessModifiersArray[2],
["Torsional Constant"] = stiffnessModifiersArray[3],
["Moment of Inertia about 2 Axis"] = stiffnessModifiersArray[4],
["Moment of Inertia about 3 Axis"] = stiffnessModifiersArray[5],
["Mass"] = stiffnessModifiersArray[6],
["Weight"] = stiffnessModifiersArray[7],
};
Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.GENERAL_DATA
);
generalData["modifiers"] = modifiers;
Dictionary<string, object?> generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Modifiers"] = modifiers;
}
}
@@ -18,14 +18,14 @@ public class CsiMaterialPropertyExtractor
/// </summary>
private static class MechanicalPropertyNames
{
public const string MODULUS_OF_ELASTICITY = "modulusOfElasticity";
public const string MODULUS_OF_ELASTICITY_ARRAY = "modulusOfElasticityArray";
public const string POISSON_RATIO = "poissonRatio";
public const string POISSON_RATIO_ARRAY = "poissonRatioArray";
public const string THERMAL_COEFFICIENT = "thermalCoefficient";
public const string THERMAL_COEFFICIENT_ARRAY = "thermalCoefficientArray";
public const string SHEAR_MODULUS = "shearModulus";
public const string SHEAR_MODULUS_ARRAY = "shearModulusArray";
public const string MODULUS_OF_ELASTICITY = "Modulus of Elasticity, E";
public const string MODULUS_OF_ELASTICITY_ARRAY = "Modulus of Elasticity Array, E";
public const string POISSON_RATIO = "Poisson's Ratio, U";
public const string POISSON_RATIO_ARRAY = "Poisson's Ratio Array, U";
public const string THERMAL_COEFFICIENT = "Coefficient of Thermal Expansion, A";
public const string THERMAL_COEFFICIENT_ARRAY = "Coefficient of Thermal Expansion Array, A";
public const string SHEAR_MODULUS = "Shear Modulus, G";
public const string SHEAR_MODULUS_ARRAY = "Shear Modulus Array, G";
}
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
@@ -38,8 +38,8 @@ public class CsiMaterialPropertyExtractor
public void ExtractProperties(string materialName, Dictionary<string, object?> properties)
{
GetGeneralProperties(materialName, properties);
GetWeightAndMassProperties(materialName, properties);
GetMechanicalProperties(materialName, properties);
GetWeightAndMassProperties(materialName, properties); // TODO: Add units
GetMechanicalProperties(materialName, properties); // TODO: Add units
}
private void GetGeneralProperties(string materialName, Dictionary<string, object?> properties)
@@ -58,10 +58,10 @@ public class CsiMaterialPropertyExtractor
ref materialGuid
);
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
generalData["name"] = materialName;
generalData["type"] = materialType.ToString();
generalData["notes"] = materialNotes;
var generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Name"] = materialName;
generalData["Type"] = materialType.ToString();
generalData["Notes"] = materialNotes;
}
}
@@ -76,9 +76,9 @@ public class CsiMaterialPropertyExtractor
ref massPerUnitVolume
);
var weightAndMass = DictionaryUtils.EnsureNestedDictionary(properties, "Weight and Mass");
weightAndMass["w"] = weightPerUnitVolume;
weightAndMass["m"] = massPerUnitVolume;
var weightAndMass = properties.EnsureNested("Weight and Mass");
weightAndMass["Weight per Unit Volume"] = weightPerUnitVolume;
weightAndMass["Mass per Unit Volume"] = massPerUnitVolume;
}
private void GetMechanicalProperties(string materialName, Dictionary<string, object?> properties)
@@ -101,8 +101,8 @@ public class CsiMaterialPropertyExtractor
_ => throw new ArgumentException($"Unknown symmetry type: {materialDirectionalSymmetryKey}")
};
var mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(properties, "Mechanical Properties");
mechanicalProperties["directionalSymmetryType"] = materialDirectionalSymmetryValue.ToString();
var mechanicalProperties = properties.EnsureNested("Mechanical Properties");
mechanicalProperties["Directional Symmetry Type"] = materialDirectionalSymmetryValue.ToString();
GetMechanicalPropertiesByType(materialName, materialDirectionalSymmetryValue, mechanicalProperties);
}
@@ -38,8 +38,8 @@ public class CsiShellSectionPropertyExtractor : IShellSectionPropertyExtractor
_ => throw new ArgumentException($"Unknown property type: {propertyTypeKey}"),
};
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
generalData["propertyType"] = propertyTypeValue;
var generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Property Type"] = propertyTypeValue.ToString();
}
private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
@@ -50,19 +50,19 @@ public class CsiShellSectionPropertyExtractor : IShellSectionPropertyExtractor
Dictionary<string, object?> modifiers =
new()
{
["f11"] = stiffnessModifiersArray[0],
["f22"] = stiffnessModifiersArray[1],
["f12"] = stiffnessModifiersArray[2],
["m11"] = stiffnessModifiersArray[3],
["m22"] = stiffnessModifiersArray[3],
["m12"] = stiffnessModifiersArray[4],
["v13"] = stiffnessModifiersArray[5],
["v23"] = stiffnessModifiersArray[6],
["mass"] = stiffnessModifiersArray[7],
["weight"] = stiffnessModifiersArray[8]
["Membrane f11 Direction"] = stiffnessModifiersArray[0],
["Membrane f22 Direction"] = stiffnessModifiersArray[1],
["Membrane f12 Direction"] = stiffnessModifiersArray[2],
["Bending m11 Direction"] = stiffnessModifiersArray[3],
["Bending m22 Direction"] = stiffnessModifiersArray[3],
["Bending m12 Direction"] = stiffnessModifiersArray[4],
["Shear v13 Direction"] = stiffnessModifiersArray[5],
["Shear v23 Direction"] = stiffnessModifiersArray[6],
["Mass"] = stiffnessModifiersArray[7],
["Weight"] = stiffnessModifiersArray[8]
};
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
generalData["modifiers"] = modifiers;
var generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Modifiers"] = modifiers;
}
}
@@ -1,12 +1,12 @@
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.CSiShared.HostApp.Helpers;
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared;
using Speckle.Converters.CSiShared.Extensions;
using Speckle.Sdk;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
@@ -30,7 +30,6 @@ namespace Speckle.Connectors.CSiShared.Builders;
public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
{
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
private readonly ISendConversionCache _sendConversionCache;
private readonly IConverterSettingsStore<CsiConversionSettings> _converterSettings;
private readonly CsiSendCollectionManager _sendCollectionManager;
private readonly MaterialUnpacker _materialUnpacker;
@@ -41,7 +40,6 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
public CsiRootObjectBuilder(
IRootToSpeckleConverter rootToSpeckleConverter,
ISendConversionCache sendConversionCache,
IConverterSettingsStore<CsiConversionSettings> converterSettings,
CsiSendCollectionManager sendCollectionManager,
MaterialUnpacker materialUnpacker,
@@ -51,7 +49,6 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
ICsiApplicationService csiApplicationService
)
{
_sendConversionCache = sendConversionCache;
_converterSettings = converterSettings;
_sendCollectionManager = sendCollectionManager;
_materialUnpacker = materialUnpacker;
@@ -71,7 +68,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
/// 2. Converts each object with caching and progress tracking
/// 3. Creates proxies for materials and sections
/// </remarks>
public async Task<RootObjectBuilderResult> BuildAsync(
public async Task<RootObjectBuilderResult> Build(
IReadOnlyList<ICsiWrapper> csiObjects,
SendInfo sendInfo,
IProgress<CardProgress> onOperationProgressed,
@@ -94,7 +91,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
cancellationToken.ThrowIfCancellationRequested();
using var _2 = _activityFactory.Start("Convert");
var result = ConvertCsiObject(csiObject, rootObjectCollection, sendInfo.ProjectId);
var result = ConvertCsiObject(csiObject, rootObjectCollection);
results.Add(result);
count++;
@@ -123,28 +120,40 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
/// <summary>
/// Converts a single Csi wrapper "object" to a data object with appropriate collection management.
/// </summary>
private SendConversionResult ConvertCsiObject(ICsiWrapper csiObject, Collection typeCollection, string projectId)
private SendConversionResult ConvertCsiObject(ICsiWrapper csiObject, Collection typeCollection)
{
string applicationId = $"{csiObject.ObjectType}{csiObject.Name}"; // TODO: NO! Use GUID
string sourceType = csiObject.ObjectName;
string applicationId = csiObject switch
{
CsiJointWrapper jointWrapper => jointWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
CsiFrameWrapper frameWrapper => frameWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
CsiCableWrapper cableWrapper => cableWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
CsiTendonWrapper tendonWrapper => tendonWrapper.ObjectName, // No GetGUID method in the Csi API available
CsiShellWrapper shellWrapper => shellWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
CsiSolidWrapper solidWrapper => solidWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
CsiLinkWrapper linkWrapper => linkWrapper.GetSpeckleApplicationId(_csiApplicationService.SapModel),
_ => throw new ArgumentException($"Unsupported wrapper type: {csiObject.GetType()}", nameof(csiObject))
};
try
{
Base converted;
if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
{
converted = value;
}
else
{
converted = _rootToSpeckleConverter.Convert(csiObject);
}
Base converted = _rootToSpeckleConverter.Convert(csiObject);
var collection = _sendCollectionManager.AddObjectCollectionToRoot(converted, typeCollection);
collection.elements.Add(converted);
return new(Status.SUCCESS, applicationId, sourceType, converted);
}
// Expected not implemented:
// TODO: SAP 2000: CsiCableWrapper, CsiSolidWrapper
// TODO: ETABS: CsiLinkWrapper, CsiTendonWrapper
// NOTE: CsiLinkWrapper - not important to data extraction workflow
// NOTE: CsiTendonWrapper - not typically modelled in ETABS, rather SAFE
catch (NotImplementedException ex)
{
_logger.LogError(ex, sourceType);
return new(Status.WARNING, applicationId, sourceType, null, ex);
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, sourceType);
@@ -10,8 +10,8 @@ public abstract class CSiPluginBase : cPluginContract, IDisposable
public void Main(ref cSapModel sapModel, ref cPluginCallback pluginCallback)
{
_panel = CreateForm();
_panel.SetSapModel(ref sapModel, ref pluginCallback);
_panel.FormClosed += (s, e) => Dispose();
_panel.Initialize(ref sapModel, ref pluginCallback);
_panel.FormClosed += (_, _) => Dispose();
if (string.Equals(s_modality, "Non-Modal", StringComparison.OrdinalIgnoreCase))
{
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms.Integration;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common;
@@ -11,29 +12,23 @@ using Speckle.Sdk.Host;
namespace Speckle.Connectors.CSiShared;
[DesignerCategory("")]
public abstract class SpeckleFormBase : Form
public abstract class SpeckleFormBase : Form, ICsiApplicationService
{
protected ElementHost Host { get; set; }
public static new ServiceProvider? Container { get; set; }
private cSapModel _sapModel;
private ElementHost Host { get; set; }
private cPluginCallback _pluginCallback;
private bool _disposed;
#pragma warning disable CA2213
private ServiceProvider _container;
#pragma warning restore CA2213
protected SpeckleFormBase()
{
Text = "Speckle (Beta)";
var services = new ServiceCollection();
ConfigureServices(services);
Container = services.BuildServiceProvider();
Container.UseDUI(false);
var webview = Container.GetRequiredService<DUI3ControlWebView>();
Host = new() { Child = webview, Dock = DockStyle.Fill };
Controls.Add(Host);
FormClosing += Form1Closing;
Size = new System.Drawing.Size(400, 600);
}
public cSapModel SapModel { get; private set; }
protected virtual void ConfigureServices(IServiceCollection services)
{
services.Initialize(GetHostApplication(), GetVersion());
@@ -45,23 +40,61 @@ public abstract class SpeckleFormBase : Form
protected abstract HostAppVersion GetVersion();
public void SetSapModel(ref cSapModel sapModel, ref cPluginCallback pluginCallback)
public void Initialize(ref cSapModel sapModel, ref cPluginCallback pluginCallback)
{
_sapModel = sapModel;
// store app-specific model and callback references (callback if at all possible?)
SapModel = sapModel;
_pluginCallback = pluginCallback;
var csiService = Container.GetRequiredService<ICsiApplicationService>();
csiService.Initialize(sapModel, pluginCallback);
string assemblyName =
Assembly.GetExecutingAssembly().GetName().Name
?? throw new InvalidOperationException("Could not determine executing assembly name");
string resourcePath = $"{assemblyName}.Resources.et_element_Speckle.bmp";
// load and set the speckle icon from embedded resources
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath))
{
if (stream == null)
{
throw new InvalidOperationException($"Could not find resource: {resourcePath}");
}
using var bmp = new Bitmap(stream);
Icon = Icon.FromHandle(bmp.GetHicon());
}
// configure dependency injection services
var services = new ServiceCollection();
services.AddSingleton<ICsiApplicationService>(this);
ConfigureServices(services);
// build service container and initialize ui framework
_container = services.BuildServiceProvider();
_container.UseDUI();
// setup webview control and form properties
var webview = _container.GetRequiredService<DUI3ControlWebView>();
Host = new() { Child = webview, Dock = DockStyle.Fill };
Controls.Add(Host);
FormBorderStyle = FormBorderStyle.Sizable;
// this.TopLevel = true;
// TODO: Get IntrPtr for Csi window
FormClosing += Form1Closing;
}
protected void Form1Closing(object? sender, FormClosingEventArgs e)
{
Host.Dispose();
_pluginCallback.Finish(0);
}
private void Form1Closing(object? sender, FormClosingEventArgs e) => _pluginCallback.Finish(0);
public new void ShowDialog()
protected override void Dispose(bool disposing)
{
base.ShowDialog();
if (!_disposed)
{
if (disposing)
{
_container.Dispose();
Host.Dispose();
base.Dispose(disposing);
}
_disposed = true;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

@@ -23,7 +23,6 @@ public static class ServiceRegistration
public static IServiceCollection AddCsi(this IServiceCollection services)
{
services.AddSingleton<IBrowserBridge, BrowserBridge>();
services.AddSingleton<ICsiApplicationService, CsiApplicationService>();
services.AddConnectorUtils();
services.AddDUI<DefaultThreadContext, CsiDocumentModelStore>();
@@ -8,6 +8,11 @@
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Speckle.Connectors.CSiShared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\et_element_Speckle.bmp">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedBasicConnectorBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSelectionBinding.cs" />
@@ -30,4 +35,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utils\ObjectIdentifiers.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)Resources\et_element_Speckle.bmp" />
</ItemGroup>
</Project>
@@ -2,14 +2,13 @@
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU</Platforms>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<ETABSVersion>21</ETABSVersion>
<DefineConstants>$(DefineConstants);ETABS21</DefineConstants>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<ItemGroup>
@@ -164,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -264,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -274,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -292,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.etabs21": {
@@ -334,37 +329,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -2,14 +2,13 @@
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU</Platforms>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<ETABSVersion>22</ETABSVersion>
<DefineConstants>$(DefineConstants);ETABS22;ETABS22_OR_GREATER</DefineConstants>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<ItemGroup>
@@ -155,11 +155,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -220,9 +215,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -230,8 +225,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -248,7 +243,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.etabs22": {
@@ -290,36 +285,42 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
}
}
@@ -48,9 +48,14 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
return DEFAULT_LEVEL;
}
if (properties.TryGetValue("Object ID", out var objectId) && objectId is Dictionary<string, object> parameters)
if (
properties.TryGetValue(ObjectPropertyCategory.OBJECT_ID, out var objectId)
&& objectId is Dictionary<string, object> parameters
)
{
return parameters.TryGetValue("level", out var level) ? level?.ToString() ?? DEFAULT_LEVEL : DEFAULT_LEVEL;
return parameters.TryGetValue(CommonObjectProperty.LEVEL, out var level)
? level?.ToString() ?? DEFAULT_LEVEL
: DEFAULT_LEVEL;
}
return DEFAULT_LEVEL;
@@ -72,9 +77,12 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
&& obj["properties"] is Dictionary<string, object> properties
)
{
if (properties.TryGetValue("Object ID", out var objectId) && objectId is Dictionary<string, object> parameters)
if (
properties.TryGetValue(ObjectPropertyCategory.OBJECT_ID, out var objectId)
&& objectId is Dictionary<string, object> parameters
)
{
if (parameters.TryGetValue("designOrientation", out var orientation))
if (parameters.TryGetValue(CommonObjectProperty.DESIGN_ORIENTATION, out var orientation))
{
return GetCategoryFromDesignOrientation(orientation?.ToString(), type);
}
@@ -58,21 +58,19 @@ public class EtabsFrameSectionPropertyExtractor : IApplicationFrameSectionProper
if (sectionIndex != -1)
{
// General Data
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
generalData["type"] = propTypes[sectionIndex].ToString();
var generalData = properties.EnsureNested(SectionPropertyCategory.GENERAL_DATA);
generalData["Section Shape"] = propTypes[sectionIndex].ToString();
// Section Dimensions
var sectionDimensions = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.SECTION_DIMENSIONS
);
sectionDimensions["t3"] = t3[sectionIndex];
sectionDimensions["t2"] = t2[sectionIndex];
sectionDimensions["tf"] = tf[sectionIndex];
sectionDimensions["tw"] = tw[sectionIndex];
sectionDimensions["t2b"] = t2b[sectionIndex];
sectionDimensions["tfb"] = tfb[sectionIndex];
sectionDimensions["area"] = area[sectionIndex];
string unit = _settingsStore.Current.SpeckleUnits;
var sectionDimensions = properties.EnsureNested(SectionPropertyCategory.SECTION_DIMENSIONS);
sectionDimensions.AddWithUnits("t3", t3[sectionIndex], unit);
sectionDimensions.AddWithUnits("t2", t2[sectionIndex], unit);
sectionDimensions.AddWithUnits("tf", tf[sectionIndex], unit);
sectionDimensions.AddWithUnits("tw", tw[sectionIndex], unit);
sectionDimensions.AddWithUnits("t2b", t2b[sectionIndex], unit);
sectionDimensions.AddWithUnits("tfb", tfb[sectionIndex], unit);
sectionDimensions.AddWithUnits("Area", area[sectionIndex], $"{unit}²");
}
}
}
@@ -54,7 +54,7 @@ public class EtabsShellSectionPropertyExtractor : IApplicationShellSectionProper
continue;
}
var nestedProperties = DictionaryUtils.EnsureNestedDictionary(properties, nestedDictionary.Key);
var nestedProperties = properties.EnsureNested(nestedDictionary.Key);
foreach (var kvp in nestedValues)
{
nestedProperties[kvp.Key] = kvp.Value;
@@ -78,16 +78,16 @@ public class WallSectionResolver(IConverterSettingsStore<CsiConversionSettings>
);
Dictionary<string, object?> generalData = [];
generalData["name"] = sectionName;
generalData["type"] = wallPropType.ToString();
generalData["material"] = matProp;
generalData["modelingType"] = shellType.ToString();
generalData["color"] = color;
generalData["notes"] = notes;
generalData["Property Name"] = sectionName;
generalData["Property Type"] = wallPropType.ToString();
generalData["Material"] = matProp;
generalData["Modeling Type"] = shellType.ToString();
generalData["Display Color"] = color;
generalData["Notes"] = notes;
Dictionary<string, object?> propertyData = [];
propertyData["type"] = "Wall";
propertyData["thickness"] = thickness;
propertyData["Type"] = "Wall";
propertyData.AddWithUnits("Thickness", thickness, settingsStore.Current.SpeckleUnits);
Dictionary<string, object?> properties = [];
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
@@ -121,15 +121,15 @@ public class SlabSectionResolver(IConverterSettingsStore<CsiConversionSettings>
);
Dictionary<string, object?> generalData = [];
generalData["name"] = sectionName;
generalData["material"] = matProp;
generalData["modelingType"] = shellType.ToString();
generalData["color"] = color;
generalData["notes"] = notes;
generalData["Property Name"] = sectionName;
generalData["Material"] = matProp;
generalData["Modeling Type"] = shellType.ToString();
generalData["Display Color"] = color;
generalData["Notes"] = notes;
Dictionary<string, object?> propertyData = [];
propertyData["type"] = slabType.ToString();
propertyData["thickness"] = thickness;
propertyData["Type"] = slabType.ToString();
propertyData.AddWithUnits("Thickness", thickness, settingsStore.Current.SpeckleUnits);
Dictionary<string, object?> properties = [];
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
@@ -163,15 +163,15 @@ public class DeckSectionResolver(IConverterSettingsStore<CsiConversionSettings>
);
Dictionary<string, object?> generalData = [];
generalData["name"] = sectionName;
generalData["type"] = deckType.ToString();
generalData["material"] = deckMatProp;
generalData["modelingType"] = shellType.ToString();
generalData["color"] = color;
generalData["notes"] = notes;
generalData["Property Name"] = sectionName;
generalData["Property Type"] = deckType.ToString();
generalData["Material"] = deckMatProp;
generalData["Modeling Type"] = shellType.ToString();
generalData["Display Color"] = color;
generalData["Notes"] = notes;
Dictionary<string, object?> propertyData = [];
propertyData["thickness"] = thickness;
propertyData.AddWithUnits("Thickness", thickness, settingsStore.Current.SpeckleUnits);
Dictionary<string, object?> properties = [];
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
@@ -7,7 +7,7 @@ public abstract class EtabsPluginBase : CSiPluginBase
{
public override int Info(ref string text)
{
text = "Hey Speckler! This is our next-gen ETABS Connector.";
text = "Next Gen Speckle Connector for ETABS";
return 0;
}
@@ -9,14 +9,14 @@
<NavisworksVersion>2020</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2020;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2020.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2020.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -39,15 +39,6 @@
"resolved": "2020.0.0",
"contentHash": "biB2RR0HNxrbHD7zBZoJUhwzPwVE5IFg9l4/747bHOLRJC3FM5UtzdjGwvRZwfOlFyM4P26NYARSiCaxSNIBpg=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -173,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -301,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2020": {
@@ -345,28 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -9,14 +9,14 @@
<NavisworksVersion>2021</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2021;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2021.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2021.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -39,15 +39,6 @@
"resolved": "2021.0.0",
"contentHash": "cY7sU8dxISfTQLinUIOki/azS+bIX28uEZQO4ijrq0eOUhJlKcKWS273kHPoL0+T0Xrkd+1OWj2YFa2PbHGgwQ=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -173,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -301,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2021": {
@@ -345,28 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -9,14 +9,14 @@
<NavisworksVersion>2022</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2022;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2022.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2022.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -39,15 +39,6 @@
"resolved": "2022.0.0",
"contentHash": "x0RW4Iqw8YHVK4ZiLEyLLfI5ffuRBR0KhEvmy9ZpT8SLNeDL/c6jn+7JWBVFUJPu+ObVnU+KqJjLdHmphN0lMQ=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -173,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -301,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2022": {
@@ -345,28 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -9,14 +9,14 @@
<NavisworksVersion>2023</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2023;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2023.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2023.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -39,15 +39,6 @@
"resolved": "2023.0.0",
"contentHash": "+qRmcyLD3DpuSSwX2IbEwp0gJllbiKgv313PZfEfh8I2uvxf+5YNqDzY0OGOxWIdPKqaQmdUZ1ELzoDtucCWzA=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -173,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -301,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2023": {
@@ -345,28 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -9,14 +9,14 @@
<NavisworksVersion>2024</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2024;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2024.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2024.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
@@ -39,15 +39,6 @@
"resolved": "2024.0.0",
"contentHash": "SnkvhcENMy3YLWbzy4lCweMuWdAbNzAtwvffFH2xVHmnm/2INnMGucYGazAHN496d6wgl9YRGa4qftgVsg7T7A=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -173,11 +164,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -273,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -283,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -301,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2024": {
@@ -345,28 +331,43 @@
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -9,14 +9,14 @@
<NavisworksVersion>2025</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2025;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Objects"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2025.0.0"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2025.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Microsoft.Web.WebView2" VersionOverride="1.0.2045.28" />
</ItemGroup>
@@ -45,15 +45,6 @@
"resolved": "2025.0.0",
"contentHash": "+q2IObnUGqtC1O/ddy2p0HKm1eXRo7Yi80oD9VIWClidvGb3rVsXKZWBHiv4HwSn5JcOMSEt1cdSlRQLm8Ehjg=="
},
"Speckle.Objects": {
"type": "Direct",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.234"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -179,11 +170,6 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
@@ -279,9 +265,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
@@ -289,8 +275,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.234, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
@@ -307,7 +293,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.234, )"
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2025": {
@@ -345,28 +331,43 @@
"resolved": "2.2.0",
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.234, )",
"resolved": "3.1.0-dev.234",
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -0,0 +1,9 @@
{
"profiles": {
"Speckle.Connector.Navisworks2026": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Autodesk\\Navisworks Manage 2026\\Roamer.exe",
"commandLineArgs": " -licensing AdLM"
}
}
}
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<FileAlignment>512</FileAlignment>
<NavisworksBuildNumber>v23</NavisworksBuildNumber>
<NavisworksVersion>2026</NavisworksVersion>
<DefineConstants>$(DefineConstants);TRACE;NAVIS2026;NAVIS</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
<ItemGroup>
<Reference Include="WindowsFormsIntegration"/>
<PackageReference Include="Speckle.Navisworks.API" VersionOverride="2026.0.1" ExcludeAssets="runtime"/>
<PackageReference Include="Microsoft.Web.WebView2" VersionOverride="1.0.2365.46" />
<PackageReference Include="System.Reactive" VersionOverride="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2026\Speckle.Converters.Navisworks2026.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
</ItemGroup>
</Project>
@@ -0,0 +1,389 @@
{
"version": 2,
"dependencies": {
".NETFramework,Version=v4.8": {
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
"resolved": "1.0.3",
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
"dependencies": {
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
}
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Microsoft.Web.WebView2": {
"type": "Direct",
"requested": "[1.0.2365.46, )",
"resolved": "1.0.2365.46",
"contentHash": "8L/Wv1r6NRSYpaaywBE/zcjDShTlTCEqBgsrB0xPQ11umziTtSNTu/rcLVazoQhHfVnQvX/fruMtdJCiPTDuyQ=="
},
"PolySharp": {
"type": "Direct",
"requested": "[1.14.1, )",
"resolved": "1.14.1",
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
},
"Speckle.InterfaceGenerator": {
"type": "Direct",
"requested": "[0.9.6, )",
"resolved": "0.9.6",
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
},
"Speckle.Navisworks.API": {
"type": "Direct",
"requested": "[2026.0.1, )",
"resolved": "2026.0.1",
"contentHash": "IjIxv+EGmEVYquljXMCNxdBY7kGBeMxEecIdXvyzBj3dLLhJjqpmyfA2Yheq4pfK4AmE6LWZ5mQyD+39onApRw=="
},
"System.Reactive": {
"type": "Direct",
"requested": "[6.0.0, )",
"resolved": "6.0.0",
"contentHash": "31kfaW4ZupZzPsI5PVe77VhnvFF55qgma7KZr/E0iFTs6fmdhhG8j0mgEx620iLTey1EynOkEfnyTjtNEpJzGw==",
"dependencies": {
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0",
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
"System.Net.WebSockets.Client.Managed": "1.0.22",
"System.Reactive": "5.0.0"
}
},
"GraphQL.Client.Abstractions": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
"dependencies": {
"GraphQL.Primitives": "6.0.0"
}
},
"GraphQL.Client.Abstractions.Websocket": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0"
}
},
"GraphQL.Primitives": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
"dependencies": {
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
"dependencies": {
"Microsoft.Data.Sqlite.Core": "7.0.5",
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
}
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"Microsoft.Extensions.Configuration": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
"dependencies": {
"Microsoft.Extensions.Primitives": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Primitives": "2.2.0",
"System.ComponentModel.Annotations": "4.5.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
"dependencies": {
"System.Memory": "4.5.1",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
"type": "Transitive",
"resolved": "1.0.3",
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
"dependencies": {
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
"dependencies": {
"System.Memory": "4.5.3"
}
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
},
"SQLitePCLRaw.provider.dynamic_cdecl": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"System.Buffers": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
"resolved": "4.5.0",
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
"dependencies": {
"System.Buffers": "4.4.0",
"System.Numerics.Vectors": "4.4.0",
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
}
},
"System.Net.WebSockets.Client.Managed": {
"type": "Transitive",
"resolved": "1.0.22",
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
"dependencies": {
"System.Buffers": "4.4.0",
"System.Numerics.Vectors": "4.4.0"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"speckle.connectors.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.8, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.8, )",
"Speckle.Sdk.Dependencies": "[3.1.8, )"
}
},
"speckle.connectors.dui.webview": {
"type": "Project",
"dependencies": {
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
"Speckle.Connectors.DUI": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
"type": "Project"
},
"speckle.converters.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.8, )"
}
},
"speckle.converters.navisworks2026": {
"type": "Project",
"dependencies": {
"Speckle.Connectors.DUI": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )",
"Speckle.Navisworks.API": "[2026.0.1, )",
"System.Reactive": "[6.0.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
"Microsoft.Extensions.Options": "2.2.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "rM1t+E8NIWFCPC3ndnMAI71B9ONiPFsz6GuIIdc5kth5AggQRGArPCalJBwA33ith2WtbjWOanI+PhHmpGQgGw==",
"dependencies": {
"Speckle.Sdk": "3.1.8"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "qIYRiYHO2UkKuy8ZbjYltKCqLesIcJOcCGTEzyTCbyij5aC1x8HnwFjGMeonUCPaeipEKhI/4HidEZ0CwWvnXg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.8"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.8, )",
"resolved": "3.1.8",
"contentHash": "+MWIemub3nlPnDJ7sHl5nDGFDIIfiBU2VxqNmTGKzWNtCjsDi6KYw5zpbvXnaNcIqFoexv3TKCurjvT2ejzyQw=="
}
},
".NETFramework,Version=v4.8/win-x64": {
"Microsoft.Web.WebView2": {
"type": "Direct",
"requested": "[1.0.2365.46, )",
"resolved": "1.0.2365.46",
"contentHash": "8L/Wv1r6NRSYpaaywBE/zcjDShTlTCEqBgsrB0xPQ11umziTtSNTu/rcLVazoQhHfVnQvX/fruMtdJCiPTDuyQ=="
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
}
}
}
}
@@ -1,5 +1,3 @@
using Speckle.Connector.Navisworks.HostApp;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
@@ -15,23 +13,17 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
public BasicConnectorBindingCommands Commands { get; }
private readonly DocumentModelStore _store;
private readonly ISendConversionCache _sendConversionCache;
private readonly ISpeckleApplication _speckleApplication;
private readonly NavisworksDocumentEvents _documentEvents;
public NavisworksBasicConnectorBinding(
IBrowserBridge parent,
DocumentModelStore store,
ISendConversionCache sendConversionCache,
ISpeckleApplication speckleApplication,
NavisworksDocumentEvents documentEvents
ISpeckleApplication speckleApplication
)
{
Parent = parent;
_store = store;
_sendConversionCache = sendConversionCache;
_speckleApplication = speckleApplication;
_documentEvents = documentEvents;
Commands = new BasicConnectorBindingCommands(parent);
}
@@ -58,6 +50,8 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
@@ -6,7 +6,7 @@ namespace Speckle.Connector.Navisworks.Bindings;
public class NavisworksSelectionBinding : ISelectionBinding
{
private readonly IAppIdleManager _appIdleManager;
private readonly IAppIdleManager _idleManager;
private readonly IElementSelectionService _selectionService;
private const string SELECTION_EVENT = "setSelection";
public string Name { get; } = "selectionBinding";
@@ -18,27 +18,28 @@ public class NavisworksSelectionBinding : ISelectionBinding
IElementSelectionService selectionService
)
{
_idleManager = idleManager;
_selectionService = selectionService;
_appIdleManager = idleManager;
Parent = parent;
NavisworksApp.ActiveDocument.CurrentSelection.Changed += OnSelectionChange;
}
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
_appIdleManager.SubscribeToIdle(nameof(NavisworksSelectionBinding), async () => await UpdateSelectionAsync());
_idleManager.SubscribeToIdle(nameof(UpdateSelectionAsync), async () => await UpdateSelectionAsync());
private async Task UpdateSelectionAsync()
{
var selInfo = GetSelection();
await Parent.Send<SelectionInfo>(SELECTION_EVENT, selInfo);
await Parent.Send(SELECTION_EVENT, selInfo);
}
public SelectionInfo GetSelection()
{
// Ensure there is an active document and a valid selection
var activeDocument = NavisworksApp.ActiveDocument;
if (activeDocument == null || activeDocument.CurrentSelection.SelectedItems.IsEmpty)
var selection = activeDocument?.CurrentSelection?.SelectedItems ?? [];
if (selection.Count == 0)
{
// Return an empty list if no valid selection exists
return new SelectionInfo([], "No selection available");
@@ -46,13 +47,13 @@ public class NavisworksSelectionBinding : ISelectionBinding
// Ensure only visible elements are processed by filtering using IsElementVisible
var selectedObjectsIds = new HashSet<string>(
activeDocument
.CurrentSelection.SelectedItems.Where(_selectionService.IsVisible) // Exclude hidden elements
selection
.Where(_selectionService.IsVisible) // Exclude hidden elements
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
);
return new SelectionInfo(
[.. selectedObjectsIds],
selectedObjectsIds,
$"{selectedObjectsIds.Count} object{(selectedObjectsIds.Count != 1 ? "s" : "")}"
);
}
@@ -1,9 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Operations.Send.Filters;
using Speckle.Connector.Navisworks.Operations.Send.Settings;
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Exceptions;
@@ -29,8 +31,7 @@ public class NavisworksSendBinding : ISendBinding
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly CancellationManager _cancellationManager;
private readonly ICancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<NavisworksSendBinding> _logger;
private readonly ISpeckleApplication _speckleApplication;
@@ -38,27 +39,27 @@ public class NavisworksSendBinding : ISendBinding
private readonly INavisworksConversionSettingsFactory _conversionSettingsFactory;
private readonly ToSpeckleSettingsManagerNavisworks _toSpeckleSettingsManagerNavisworks;
private readonly IElementSelectionService _selectionService;
private readonly IThreadContext _threadContext;
public NavisworksSendBinding(
DocumentModelStore store,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
CancellationManager cancellationManager,
ICancellationManager cancellationManager,
IOperationProgressManager operationProgressManager,
ILogger<NavisworksSendBinding> logger,
ISpeckleApplication speckleApplication,
ISdkActivityFactory activityFactory,
INavisworksConversionSettingsFactory conversionSettingsFactory,
ToSpeckleSettingsManagerNavisworks toSpeckleSettingsManagerNavisworks,
IElementSelectionService selectionService
IElementSelectionService selectionService,
IThreadContext threadContext
)
{
Parent = parent;
Commands = new SendBindingUICommands(parent);
_store = store;
_serviceProvider = serviceProvider;
_sendFilters = sendFilters.ToList();
_cancellationManager = cancellationManager;
_operationProgressManager = operationProgressManager;
_logger = logger;
@@ -67,12 +68,18 @@ public class NavisworksSendBinding : ISendBinding
_conversionSettingsFactory = conversionSettingsFactory;
_toSpeckleSettingsManagerNavisworks = toSpeckleSettingsManagerNavisworks;
_selectionService = selectionService;
_threadContext = threadContext;
SubscribeToNavisworksEvents();
}
private static void SubscribeToNavisworksEvents() { }
public List<ISendFilter> GetSendFilters() => _sendFilters;
// 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.
public List<ISendFilter> GetSendFilters() =>
[
new NavisworksSelectionFilter() { IsDefault = true },
new NavisworksSavedSetsFilter(new ElementSelectionService())
];
public List<ICardSetting> GetSendSettings() =>
[
@@ -80,9 +87,13 @@ public class NavisworksSendBinding : ISendBinding
new OriginModeSetting(OriginMode.ModelOrigin),
new IncludeInternalPropertiesSetting(false),
new ConvertHiddenElementsSetting(false),
new PreserveModelHierarchySetting(false),
];
public async Task Send(string modelCardId)
public async Task Send(string modelCardId) =>
await _threadContext.RunOnMainAsync(async () => await SendInternal(modelCardId));
private async Task SendInternal(string modelCardId)
{
using var activity = _activityFactory.Start();
try
@@ -93,11 +104,23 @@ public class NavisworksSendBinding : ISendBinding
InitializeConverterSettings(scope, modelCard);
CancellationToken token = _cancellationManager.InitCancellationTokenSource(modelCardId);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
var navisworksModelItems = GetNavisworksModelItems(modelCard);
var progress = _operationProgressManager.CreateOperationProgressEventHandler(
Parent,
modelCard.ModelCardId.NotNull(),
cancellationItem.Token
);
var sendResult = await ExecuteSendOperation(scope, modelCard, navisworksModelItems, token);
var navisworksModelItems = await GetNavisworksModelItems(modelCard, progress);
var sendResult = await ExecuteSendOperation(
scope,
modelCard,
navisworksModelItems,
progress,
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
}
@@ -112,12 +135,16 @@ public class NavisworksSendBinding : ISendBinding
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
finally
{
// otherwise the id of the operation persists on the cancellation manager and triggers 'Operations cancelled because of document swap!' message to UI.
_cancellationManager.CancelOperation(modelCardId);
}
}
private SenderModelCard GetModelCard(string modelCardId) =>
_store.GetModelById(modelCardId) is not SenderModelCard modelCard
? throw new InvalidOperationException("No publish model card was found.")
: modelCard;
_store.GetModelById(modelCardId) as SenderModelCard
?? throw new InvalidOperationException("No publish model card was found.");
private void InitializeConverterSettings(IServiceScope scope, SenderModelCard modelCard) =>
scope
@@ -127,43 +154,56 @@ public class NavisworksSendBinding : ISendBinding
originMode: _toSpeckleSettingsManagerNavisworks.GetOriginMode(modelCard),
visualRepresentationMode: _toSpeckleSettingsManagerNavisworks.GetVisualRepresentationMode(modelCard),
convertHiddenElements: _toSpeckleSettingsManagerNavisworks.GetConvertHiddenElements(modelCard),
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard)
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard),
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard)
)
);
private List<NAV.ModelItem> GetNavisworksModelItems(SenderModelCard modelCard)
private async Task<List<NAV.ModelItem>> GetNavisworksModelItems(
SenderModelCard modelCard,
IProgress<CardProgress> onOperationProgressed
)
{
var selectedPaths = modelCard.SendFilter.NotNull().RefreshObjectIds();
var convertHiddenElementsSetting =
modelCard.Settings!.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool? ?? false;
var message = convertHiddenElementsSetting
? "No visible objects were found to convert. Please update your publish filter!"
: "No objects were found to convert. Please update your publish filter, or check items are visible!";
if (selectedPaths.Count == 0)
{
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
throw new SpeckleSendFilterException(message);
}
onOperationProgressed.Report(new CardProgress("Getting selection...", null));
await Task.CompletedTask;
var modelItems = modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(_selectionService.GetModelItemFromPath)
.SelectMany(_selectionService.GetGeometryNodes)
.Where(_selectionService.IsVisible)
.ToList();
return modelItems.Count == 0
? throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!")
: modelItems;
var modelItems = new List<NAV.ModelItem>();
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));
count++;
}
return modelItems.Count == 0 ? throw new SpeckleSendFilterException(message) : modelItems;
}
private async Task<SendOperationResult> ExecuteSendOperation(
IServiceScope scope,
SenderModelCard modelCard,
List<NAV.ModelItem> navisworksModelItems,
IProgress<CardProgress> onOperationProgressed,
CancellationToken token
) =>
await scope
.ServiceProvider.GetRequiredService<SendOperation<NAV.ModelItem>>()
.Execute(
navisworksModelItems,
modelCard.GetSendInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId.NotNull(), token),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
onOperationProgressed,
token
);
@@ -7,7 +7,6 @@ using Speckle.Connector.Navisworks.Operations.Send.Settings;
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI;
@@ -53,6 +52,8 @@ public static class NavisworksConnectorServiceRegistration
serviceCollection.AddScoped<NavisworksMaterialUnpacker>();
serviceCollection.AddScoped<NavisworksColorUnpacker>();
serviceCollection.AddSingleton<IAppIdleManager, NavisworksIdleManager>();
// Sending operations
serviceCollection.AddScoped<IRootObjectBuilder<NAV.ModelItem>, NavisworksRootObjectBuilder>();
serviceCollection.AddScoped<SendOperation<NAV.ModelItem>>();
@@ -60,14 +61,13 @@ public static class NavisworksConnectorServiceRegistration
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
// Register Intercom/interop
serviceCollection.AddTransient<CancellationManager>();
serviceCollection.AddSingleton<IAppIdleManager, NavisworksIdleManager>();
serviceCollection.AddSingleton<NavisworksDocumentModelStore>();
serviceCollection.AddSingleton<DocumentModelStore>(sp => sp.GetRequiredService<NavisworksDocumentModelStore>());
serviceCollection.AddSingleton<NavisworksDocumentEvents>();
// register filters
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
}
}
@@ -1,23 +1,31 @@
using static Speckle.Converter.Navisworks.Helpers.ElementSelectionHelper;
using Speckle.InterfaceGenerator;
using static Speckle.Converter.Navisworks.Helpers.ElementSelectionHelper;
namespace Speckle.Connector.Navisworks.Services;
public interface IElementSelectionService
{
string GetModelItemPath(NAV.ModelItem modelItem);
NAV.ModelItem GetModelItemFromPath(string path);
bool IsVisible(NAV.ModelItem modelItem);
IReadOnlyCollection<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem);
}
[GenerateAutoInterface]
public class ElementSelectionService : IElementSelectionService
{
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) => IsElementVisible(modelItem);
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 IReadOnlyCollection<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem) =>
ResolveGeometryLeafNodes(modelItem);
public IEnumerable<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem) => ResolveGeometryLeafNodes(modelItem);
}
@@ -43,12 +43,13 @@ public class NavisworksColorUnpacker(
Dictionary<string, ColorProxy> colorProxies = [];
Dictionary<string, string> mergedIds = [];
// Build mergedIds map once
foreach (var group in groupedNodes)
{
foreach (var node in group.Value)
string groupKey = group.Key;
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
{
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
mergedIds[nodePath] = groupKey;
}
}
@@ -56,13 +57,13 @@ public class NavisworksColorUnpacker(
{
try
{
// Skip non-2D elements
if (!Is2DElement(navisworksObject))
{
continue;
}
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
var geometry = navisworksObject.Geometry;
@@ -77,7 +78,6 @@ public class NavisworksColorUnpacker(
geometry.OriginalColor,
defaultColor
);
var colorId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),

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