Compare commits

...

113 Commits

Author SHA1 Message Date
Adam Hathcock e7ee172f90 Merge pull request #988 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
Dev to Main for release (NO SQUASH)
2025-07-16 16:36:09 +01:00
Adam Hathcock d49b1eea33 Merge pull request #987 from specklesystems/main-dev
Main to dev
2025-07-16 16:22:47 +01:00
Adam Hathcock d8afd74171 Merge remote-tracking branch 'origin/dev' into main-dev
# Conflicts:
#	Connectors/Rhino/Speckle.Connectors.GrasshopperShared/Components/Objects/SpeckleBlockInstancePassthrough.cs
2025-07-16 16:16:28 +01:00
Oğuzhan Koral b88f50ced6 Feat(gh): Add optional version message for senders (#986)
* Add optional version message for senders

* Rework to not have optional parameters

---------

Co-authored-by: Adam Hathcock <adam@hathcock.uk>
2025-07-16 15:37:13 +01:00
Adam Hathcock e130045930 feat: Rhino importer with CLI parameters (#910)
* Make a Rhino 8 importer

* adjust things to not require SDK changes

* something like this

* rhino importer cli sketch

* fix deps and solutions

* things build

* move to files

* change signatures of things to not require sendinfo or accounts

* formatting

* Fix test

* Reuse some account

* Fix logging and possible error

* formatting

* add active doc disposal

* add global try/catch

* merge fix

* add rhino importer

* add SLN and use it

* have to put back the extension rename

* SDK update

* Try out loading the plugin manually

* don't need the mac SLN

* fix lock

* fix lock again?

* Use the location of the assembly, not current

* Fix lock file

* fix lock on windows

---------

Co-authored-by: Chuck Driesler <cdriesler.iv@gmail.com>
2025-07-15 22:06:56 +03:00
Adam Hathcock ae72cc3adb Update the SDK to 3.4.5 (#982) 2025-07-15 17:25:48 +03:00
Claire Kuang 816539ce18 chore(grasshopper): renames model link to speckle model (#985) 2025-07-15 11:30:26 +02:00
Claire Kuang c6cdb0d893 remove new appid on passthrough mutation (#984) 2025-07-15 08:54:57 +00:00
Claire Kuang dd026e24a3 feat(grasshopper): updates properties nodes to only work with properties inputs (#983)
* updates query properties and properties selector to accept properties as input

* Update AccountManagerComponent.cs
2025-07-15 09:18:44 +01:00
Adam Hathcock 76015ed30c Null check a nurbs trim to avoid exception (#965)
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-07-14 09:48:34 +01:00
Claire Kuang b9fbf60df5 feat(grasshopper): add gh specific type support to props (#981)
* adds additional raw converters to grasshopper

* adds plane, vector, and interval to supported property value types

* Update Speckle.Converters.RhinoShared.projitems

* merge conflict resolutions
2025-07-11 16:03:41 +01:00
Jedd Morgan 50d69a0f0e Bump GrasshopperAsyncComponent (#976)
.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-07-11 09:29:12 +01:00
Claire Kuang 2f8477e072 feat(grasshopper): add support for dataobjects (#979)
* chore(grasshopper): rename speckle object to speckle geometry (#968)

* renames speckleobjectwrapper to specklegeometrywrapper

* renames files

* feat: add `SpeckleDataObjectWrapper`, `SpeckleDataObjectWrapperGoo`, `SpeckleDataObjectWrapperParam` (#969)

* feat(grasshopper): implement `DataObject` casting with property sync (#970)

* feat: `CastFrom` start with `SpeckleGeometryWrapper`

* feat: `Name` and `Properties` syncing on `DataObject` level

* feat: next cast phase

* fix: parameterless constructor

* fix: `SpeckleGeometryWrapperGoo` cast

* refactor: pr review comments

* feat: `Path` and `Parent`

* fix: deep copy on the geo

* feat(grasshopper): load data objects (#972)

* load now creates dataobjects

includes fixes to expand collection and query objects

* adds helper and fixes filter speckle objects node

* feat: add preview support for `DataObject` (#973)

* feat(grasshopper): add baking support for `SpeckleDataObjectWrapper` (#974)

* feat: add baking

* fix: pr comment

* feat(grasshopper): adds dataobject passthrough node (#975)

* adds passthrough node

also fixes deconstruct

* Update LocalToGlobalMapHandler.cs

* feat(grasshopper): adds dataobject icons (#977)

* adds icon pngs

* changes icons and icon order

* feat(grasshopper): add DataObject publishing support (#978)

* feat: publish `DataObject` first pass

* feat: `DataObject` consideration for `PropertyGroupPathsSelector`

* docs: remaining todo

* feat: add `DataObject` support to `GetObjectProperties` component

* refactor: pr review comments

---------

Co-authored-by: Björn Steinhagen <steinhagen.bjoern@gmail.com>
2025-07-11 09:28:46 +01:00
Jonathon Broughton 973a91ac5a fix(navisworks): CNX-2102 - Refines origin mode validation logic to include fallback default (#967)
* Refines origin mode handling logic

Improves validation of origin mode settings to ensure
valid values are processed correctly. If the origin
mode is null or invalid, a default is returned, reducing
errors and clarifying logic.

Cache eviction has been maintained for previous types
only when necessary, enhancing performance efficiency.

* Simplifies the retrieval of the origin mode setting by consolidating conditions into a single if statement.

* Improves cache eviction logic by removing redundant checks and ensuring defaults are applied correctly.
2025-07-08 17:42:17 +00:00
Claire Kuang 60a39b775c adds list properties (#971) 2025-07-08 10:33:04 +01:00
Jonathon Broughton f84b5e7c90 Fixes AnimationViewpointCut causing blocks in publishing (#966)
Simplifies the handling of saved viewpoints and group items.

Removes legacy defensive checks and clarifies conditions for adding viewpoints.

Ensures that only non-empty groups are processed, improving efficiency.

Relates to ongoing feature enhancements.

Co-authored-by: Adam Hathcock <adamhathcock@users.noreply.github.com>
2025-07-03 17:49:17 +01:00
Claire Kuang 5e93f23d06 remove new app id on passthrough nodes (#964)
.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-07-03 14:25:40 +01:00
Adam Hathcock 471613a77f Merge pull request #961 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
Dev to Main for 3.5.0 release
2025-06-30 16:17:10 +01:00
Adam Hathcock 778ddf4b47 Merge pull request #962 from specklesystems/main-dev
Main to dev
2025-06-30 16:08:01 +01:00
Adam Hathcock 180c1d8345 Merge branch 'dev' into main-dev 2025-06-30 16:03:14 +01:00
Claire Kuang ae847d8625 chore(grasshopper): update icon order (#963)
* cleans up params

* Update SpeckleMaterialWrapperParam.cs

* update operations icons
2025-06-30 15:03:01 +00:00
Adam Hathcock a4ba43a632 Merge branch 'dev' into main-dev 2025-06-30 15:58:51 +01:00
Oğuzhan Koral b7d23aea8d Feat(gh): sign in component (#955)
* Sign in component

* Delete debug writeline

* adds icon

* changes some text

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-30 14:52:03 +00:00
Adam Hathcock bb8634f650 Merge branch 'dev' into main-dev 2025-06-30 15:42:48 +01:00
Adam Hathcock 34c56e7c41 Update to SDK 3.4.4 (#960) 2025-06-30 14:40:03 +00:00
Claire Kuang a92986c1ce Update SpecklePropertyGoo.cs (#959) 2025-06-30 15:23:07 +01:00
Björn Steinhagen 831e5c0a82 feat(grasshopper): block support (#949)
* feat(grasshopper): add `SpeckleBlockDefinition` support (#891)

* feat: initial commit `SpeckleBlockDefinitionWrapper`

* feat: `SpeckleBlockDefinitionWrapper``Bake`and `DrawPreview`

* feat: Casting for `SpeckleBlockDefinitionWrapperGoo`

* feat: `SpeckleBlockDefinitionParam` functionality to `BakeGeometry`

* feat: `CreateSpeckleBlockDefinition`

* fix: casting and other things

* fix: defining objects of a definition, not all instance objects (LOL)

* refactor: preview

- still not previewing nicely though

* refactor: transform in helpers class

* chore: `CreateSpeckleBlockDefinition` icon

* docs: pr comment re. api limitation

* feat(grasshopper): add `SpeckleBlockInstance` support (#893)

* feat: add `SpeckleBlockInstanceWrapper` class

empty

* chore: adds `SpeckleBlockInstanceWrapperGoo`

* chore: adds `SpeckleBlockInstanceParameters`

* chore: `SpeckleBlockInstanceWrapper` wrapped `Base` is `InstanceProxy`

* docs: tiny typo

* feat: `SpeckleBlockInstanceWrapper` and parameters

* fix: missing default constructor and naming refactor

* feat: initial commit for `SpeckleBlockDefinitionWrapper`

* Revert "feat: initial commit for `SpeckleBlockDefinitionWrapper`"

This reverts commit a3c1fcf978.

* fix: `SpeckleBlockInstanceWrapper`

- `type` correction for `Properties`
- keeping transforms in sync (kinda, waiting for PR merge)
- `DeepCopy()`

* fix: `SpeckleBlockInstanceWrapperGoo`

- `CastFrom`and `CastTo`methods
- `Duplicate` method

* fix: `SpeckleBlockInstanceParam`

- adds missing implementations

* feat: placeholders for `Bake` and `DrawPreview`

* feat: `CreateSpeckleBlockInstance`

* feat: `ModelObjects`

* fix: Rhino7 preprocessor directives

* fix: casting for GH created / referenced instances

* fix: `Transform` casting

* chore: icon for `CreateSpeckleBlockInstance`

* feat: casting to and from `CreateSpeckleBlockInstance`

* chore: removing redundant code

* feat: validating `SpeckleWrapper`

* chore: updates to `.ToString()`

* fix: recompute when `doc` definition changes

* refactor: `!string.IsNullOrWhiteSpace()`

* feat: deconstruct

* fix: cast for `RhinoObject`

* refactor: consolidate duplicate baking code

* Cleans up casting logic in instance and definitions

* refactor: `RhinoObject` coming from referenced instances

* docs: comments

* refactor: code clean up for `ModelInstanceDefinition`

* refactor: consistency across wrappers

* fix: intercept block definitions from pure gh

* docs: gh defined model block definition

* docs: api limitation on `ModelInstanceDefinition` constructor

* fix: stop instances from overwriting shared block definitions on bake

* feat: disallowing block definitions in collections for now

* feat: baking instances within collection

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* feat (grasshopper): update publish to handle block instances and definitions (#909)

* feat: add `SpeckleBlockInstanceWrapper` class

empty

* chore: adds `SpeckleBlockInstanceWrapperGoo`

* chore: adds `SpeckleBlockInstanceParameters`

* chore: `SpeckleBlockInstanceWrapper` wrapped `Base` is `InstanceProxy`

* docs: tiny typo

* feat: `SpeckleBlockInstanceWrapper` and parameters

* fix: missing default constructor and naming refactor

* feat: initial commit for `SpeckleBlockDefinitionWrapper`

* Revert "feat: initial commit for `SpeckleBlockDefinitionWrapper`"

This reverts commit a3c1fcf978.

* fix: `SpeckleBlockInstanceWrapper`

- `type` correction for `Properties`
- keeping transforms in sync (kinda, waiting for PR merge)
- `DeepCopy()`

* fix: `SpeckleBlockInstanceWrapperGoo`

- `CastFrom`and `CastTo`methods
- `Duplicate` method

* fix: `SpeckleBlockInstanceParam`

- adds missing implementations

* feat: placeholders for `Bake` and `DrawPreview`

* feat: `CreateSpeckleBlockInstance`

* feat: `ModelObjects`

* fix: Rhino7 preprocessor directives

* fix: casting for GH created / referenced instances

* fix: `Transform` casting

* chore: icon for `CreateSpeckleBlockInstance`

* feat: casting to and from `CreateSpeckleBlockInstance`

* chore: removing redundant code

* feat: validating `SpeckleWrapper`

* chore: updates to `.ToString()`

* fix: recompute when `doc` definition changes

* refactor: `!string.IsNullOrWhiteSpace()`

* feat: deconstruct

* fix: cast for `RhinoObject`

* refactor: consolidate duplicate baking code

* Cleans up casting logic in instance and definitions

* refactor: `RhinoObject` coming from referenced instances

* docs: comments

* refactor: code clean up for `ModelInstanceDefinition`

* refactor: consistency across wrappers

* fix: intercept block definitions from pure gh

* docs: gh defined model block definition

* docs: api limitation on `ModelInstanceDefinition` constructor

* fix: stop instances from overwriting shared block definitions on bake

* feat: disallowing block definitions in collections for now

* feat: baking instances within collection

* feat: update publish to handle block instances and definitions

* refactpr: consolidating switch statements

* feat: runtime message on unsupported inputs for creating collections

* docs: `GrasshopperBlockPacker`

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* Update Helpers.cs

* Update Helpers.cs

* fix: removing unresolved references

`ISpeckleGoo` removed on `props` pr

* refactor: `SpeckleBlockInstanceWrapper` to use `BakingHelper`

* fix: compiler errors

* fix: still need explicit cases

* refactor(grasshopper): make `SpeckleBlockInstanceWrapper` inherit from `SpeckleObjectWrapper` (#917)

* feat: first pass

* fix: deconstruct speckle params

* refactor: cleanup

* docs: `GeometryBase`note on `SpeckleBlockInstanceWrapper`

* refactor: CreateGoo() to remove type checking in ExpandCollection

* refactor: incorporating pr comments

* fixes deconstruct component

adds removed support for materials and collections

consolidates logic for name and output creation

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* adds new icons for blocks

* feat(grasshopper): nested block support (#934)

* fix dev merge changes

* feat(grasshopper): adds color and materials to instances (#945)

* adds color and materials to instances

also includes refactoring for passthrough nodes

* some more appid and name changes

* removes unnecessary casting

also fixes some bugs with missing applicationIds on cast

* Update SpeckleBlockInstanceWrapper.ModelObjects.cs

* Update SpeckleBlockInstancePassthrough.cs

* fixes broken url

* feat(grasshopper): update load to handle blocks (#947)

* feat: block recognition in receive pipeline

* feat: `GrasshopperBlockUnpacker`

* feat: working nested blocks and removing `LocalToGlobalUnpacker`

* chore: cleanup

* refactor: remove unnecessary check

* refactor: better naming

* pr review fixes

* adds colors and materials to instance and defs on load

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* adds create goo to wrapper class

also adds missing instance casting to create collection

* moves all param classes to their own file (#950)

* chore: xml comment on the parameterless constructor

* fix: `SpeckleBlockInstanceWrapper` inheritance in `DeepCopy()`

* fix: preserve id in `SpeckleBlockInstanceWrapper` round-trip casting

* fix: url broken

* fix: auto-sync block instance definition references

* fix: throw if id null

review comment

* fix(grasshopper): improve block instance preview for nested instances (#951)

* fix: display block instances

- problem on deeply nested instances
- good poc

* chore: missing method in block definition

* fix: re-instating changes after param classes refactor

* fix: add 3-level depth limit for block instance DrawPreview methods

* fixes collection preview and some isvalid props

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* chore: removing todo comments

* fix(grasshopper): a bunch of instance vs object casting issues (#954)

* adds instance converter and filter objects casting helper

* adds missing casting an fixes casting to speckle object passthrough

* cleans up more casting logic

* more casting fixes

* Update InstanceReferenceGeometryToSpeckleConverter.cs

* fixes goos inputs and outputs for expand collection, query, filter, etc

* removes deep copying from casting

* more mutations on object passthrough

* fixes missing model object instance  casting properties

* fixes build

* model instance and def casting issues for nesting

* im literally crying

* Update InstanceReferenceGeometryToSpeckleConverter.cs

* fix: POC disabling cyclomatic complexity

* refactors speckle object code to reduce complexity

* further strips model object casting since rhino objects can be passed as model objects

* light at the end of the tunnel

* last commit i swear

fixes model insstance casting since this actually registers as IGH_GeometricGoo of type reference

* last LAST commit on god

---------

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

* fix(grasshopper): receive pipeline polish (#957)

* fix: loading, publish and query

* docs: explanations

* fix: format

* docs: remove old comment

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>

* fix(grasshopper): prevent duplicate nested block instances in receive (#958)

* fix: `consumedObjectIds` tracking preventing duplicate nested block instances

* refactor: remove redundant `isDefinitionObject` logic

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-30 15:36:02 +02:00
Oğuzhan Koral 2adfee6f49 Reset menu list on closed according to search text (#956) 2025-06-27 19:14:23 +01:00
kekesidavid 4bb67318a8 feat(revit): Reference Point Setting on Receive (#948)
* Receive settings

* wip

* wip

* resolved warnings

* cleanup

* cleanup

* netlify url restored

* review comments fixed

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-06-27 13:53:30 +02:00
Adam Hathcock dadf07a3c3 Detect by OS, Windows only (#943) 2025-06-25 10:51:13 +01:00
Claire Kuang 7f6c8bb1a3 fix(grasshopper): deconstructing collections now has elements (#946)
* Update DeconstructSpeckleParam.cs

* Update DeconstructSpeckleParam.cs
2025-06-25 09:24:52 +00:00
Adam Hathcock eb8db87d9f feat (Grasshopper) dev enable account auth by dev token (#937)
* adds url by token component

* Add gubbins for passing Account objects and AccountResource objects to include token usage

* format

* add bits to make things work?

* revert usage of SpeckleApplication

* review fixes

* more reverts

* Fix tests

* token is correct now

* fix build

* fixes url resource exception and adds new icon

* Made model cards dumb and moved conversions

* can build NW

* actually, remove dead code

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-25 08:42:37 +00:00
Claire Kuang bf91a8d6a3 chore(grasshopper): various touchups (#942)
* adds view in browser and exposures

* updates categories

* removes obscure
2025-06-24 11:35:40 +01:00
Oğuzhan Koral bce949951c Scale elevation with internal (#941) 2025-06-23 18:58:04 +03:00
Oğuzhan Koral 744b185cfe Feat(revit): proxify levels with their all props (#940)
* Unpack levels as proxy

* Dynamically attach elevation and units to data object

* Do not add level properties to collection

* Bump SDK to 3.4.3
2025-06-23 17:48:18 +03:00
Adam Hathcock 8919ba2491 Merge pull request #939 from specklesystems/adam/revert-non-windows-build
Revert "(feat) non windows building (#935)"
2025-06-23 15:48:25 +03:00
Claire Kuang fc82dda558 fix(rhino): toolbar now loads in rhino 7 (#932)
* Update Speckle.Connectors.Rhino.rui

* Update Speckle.Connectors.Rhino.rui

* Update Speckle.Connectors.Rhino.rui
2025-06-23 11:44:33 +00:00
Claire Kuang d70fe9df73 adds latest version handlers (#938)
and reformats dividers and toolstrips
2025-06-23 09:56:43 +01:00
Claire Kuang d2c78695fe adds owner selected to collection and object param (#933)
also changes the output type of create collection to be a collection param, to enable previewing

Co-authored-by: Björn Steinhagen <steinhagen.bjoern@gmail.com>
2025-06-20 14:29:28 +01:00
Adam Hathcock 4aa087e38d (feat) non windows building (#935)
* add check for non-windows building

* Remove mac solution
2025-06-20 12:49:23 +01:00
Adam Hathcock a3cbb1bcb6 Merge pull request #936 from specklesystems/adam/recieve-spam
Don't mark cancelled or conversion exceptions as errors
2025-06-20 12:48:43 +01:00
Adam Hathcock 60823dda97 Remove error from test 2025-06-20 10:59:08 +01:00
Adam Hathcock 40650bfed2 Don't mark cancelled or conversion exceptions as errors 2025-06-20 10:38:48 +01:00
Claire Kuang b0423af14b feat(grasshopper): adds create properties by keyvalue (#930)
* adds keyvalue component

* fixes some bugs

* more bugs

* adds modes to speckle props passthrough node

* Update Speckle.Connectors.GrasshopperShared.projitems

* adds new icon

* removes unused method
2025-06-20 08:14:14 +00:00
kekesidavid 636af5c7c2 fix (civil3d) extract properties from c3d block references (#931)
* extract properties from c3d block references

* cleans up property set structure and adds properties to autocad root to speckle

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-19 14:19:39 +01:00
Jedd Morgan efc532fce0 refactor(grsashopper): Update grasshopper async to 2.0.1 (#919)
* easy changes

* generics are fun

* second pass

* reverted cancellation changes

* bring back receive

* ConfigureAwait(false);

* worker count

* lock files, that will need to be changed before pr

* updates

* notnull

* minor tweaks

* made stable tag

* locks

* locks

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-19 06:24:26 +00:00
Claire Kuang 4bf54550aa Update EllipseToHostConverter.cs (#929) 2025-06-17 15:06:31 +00:00
Claire Kuang 43773c63eb feat(grasshopper): adds variable type outputs to the query objects node (#926)
* adds type outputs to query node

* Update Speckle.Connectors.GrasshopperShared.projitems

* fixes output param creation bug

* fixes last index bug

* removes speckle exception from query node

* adds better error
2025-06-17 13:57:31 +01:00
Oğuzhan Koral d34d615c3b Merge pull request #928 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
Update dev into main
2025-06-17 12:25:24 +03:00
Jonathon Broughton 9be0cd8c6e feat(Navisworks): CNX-2009 - Adds saved views filter to Navisworks send operations (#927)
* Refactors hierarchical name building for saved items

Moves hierarchical name construction to a new helper class.

Modifies the selection set filtering logic to enhance clarity.
Updates the root item handling to streamline the recursive logic.

Improves code maintainability and readability.

* Adds saved views filter for object selection

Implements a new filter to manage saved views in the application.

Enables users to select and manage saved viewpoints effectively.
Implements logic to resolve saved views and collect visible object IDs based on current selections, enhancing the user experience in managing views.

Improves selection efficiency and overall usability.

* Adds new view filter for sending operations

Updates service registration to include the new filter for improved data handling.
2025-06-17 08:23:05 +01:00
Jedd Morgan a7e323b026 Add using statements (#924) 2025-06-16 12:38:57 +00:00
Dimitrie Stefanescu 42529443bd Merge pull request #921 from specklesystems/dim/gh-multisend-input-fix
Dim/gh multisend input fix
2025-06-16 12:59:46 +01:00
Dimitrie Stefanescu 16b1f8317c Merge branch 'dev' into dim/gh-multisend-input-fix 2025-06-16 12:53:58 +01:00
Jedd Morgan abe0105095 greater than 1 2025-06-16 12:48:09 +01:00
Dimitrie Stefanescu 1b2b3e6718 Merge remote-tracking branch 'origin/dim/gh-multisend-input-fix' into dim/gh-multisend-input-fix 2025-06-16 12:44:38 +01:00
Dimitrie Stefanescu cb2916ae39 feat: makes the model url component output nothing vs. nulls on incomplete resources 2025-06-16 12:44:33 +01:00
KatKatKateryna 993555b72c Merge pull request #825 from specklesystems/kateryna/cnx-1687-modifying-layer-material-properties-doesnt-trigger-object
Kateryna/cnx 1687 modifying layer material properties doesnt trigger object
2025-06-16 09:22:34 +00:00
Adam Hathcock ddac586795 add more null protection (#923)
Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-16 08:36:58 +00:00
Björn Steinhagen f92c01e34c fix (grasshopper): InheritNames to resolve and reflect on OutputParams (#922)
* fix: first pass

* refactor: simplified `null` check
2025-06-16 09:30:44 +01:00
Claire Kuang 69e63cc815 Merge branch 'dev' into dim/gh-multisend-input-fix 2025-06-15 03:05:12 +01:00
Dimitrie Stefanescu 81ad00c4d6 feat: fixes sync load component 2025-06-14 19:48:00 +01:00
Dimitrie Stefanescu ca498889dc feat: fixes load async component 2025-06-14 19:43:54 +01:00
Dimitrie Stefanescu 6ad3606091 chore: copy 2025-06-14 19:42:00 +01:00
Dimitrie Stefanescu aae52bdddd fix: sync publish component 2025-06-14 19:32:02 +01:00
Dimitrie Stefanescu 5e6d1ce5bc fix: prevents async publish node from doing multiple sends 2025-06-14 13:34:33 +01:00
Jedd Morgan 9fe28fccd2 Add boxes (#916) 2025-06-13 14:43:40 +00:00
Adam Hathcock e7e148497d Merge pull request #918 from specklesystems/main-dev
Main to dev
2025-06-13 12:16:19 +01:00
Adam Hathcock 2d2fd086d5 Merge branch 'main' into main-dev
# Conflicts:
#	DUI3/Speckle.Connectors.DUI.WebView/packages.lock.json
#	DUI3/Speckle.Connectors.DUI/packages.lock.json
#	Sdk/Speckle.Connectors.Common/packages.lock.json
#	Sdk/Speckle.Converters.Common/packages.lock.json
2025-06-13 10:27:44 +01:00
Adam Hathcock 067c1440d1 Adds Mac slnx which excludes Connectors for now (#913)
* Adds Mac slnx which excludes Connectors for now

* formatting

* change validation of solutions
2025-06-13 10:14:53 +01:00
Adam Hathcock 70e189fa1f Merge pull request #914 from specklesystems/adam/hotfix-gh-scopes
.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
(hotfix) Grasshopper scopes aren't reused and SDK 3.4.2
2025-06-12 13:19:13 +01:00
Adam Hathcock d91b24d645 Another build fix 2025-06-12 13:12:14 +01:00
Adam Hathcock 538abbcb3c Fix usage of MD5 that was introduced with 3.4.0 SDK 2025-06-12 12:44:52 +01:00
Adam Hathcock 6a99a38b2a Update to SDK 3.4.2 (#911)
* Update to SDK 3.4.1

* fix build issues

* Update to 3.4.2

---------

Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
# Conflicts:
#	Connectors/Autocad/Speckle.Connectors.Autocad2022/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Autocad2023/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Autocad2024/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Autocad2025/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Autocad2026/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Civil3d2022/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Civil3d2023/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Civil3d2024/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Civil3d2025/packages.lock.json
#	Connectors/Autocad/Speckle.Connectors.Civil3d2026/packages.lock.json
#	Connectors/CSi/Speckle.Connectors.ETABS21/packages.lock.json
#	Connectors/CSi/Speckle.Connectors.ETABS22/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2020/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2021/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2022/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2023/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2024/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2025/packages.lock.json
#	Connectors/Navisworks/Speckle.Connectors.Navisworks2026/packages.lock.json
#	Connectors/Revit/Speckle.Connectors.Revit2022/packages.lock.json
#	Connectors/Revit/Speckle.Connectors.Revit2023/packages.lock.json
#	Connectors/Revit/Speckle.Connectors.Revit2024/packages.lock.json
#	Connectors/Revit/Speckle.Connectors.Revit2025/packages.lock.json
#	Connectors/Revit/Speckle.Connectors.Revit2026/packages.lock.json
#	Connectors/Rhino/Speckle.Connectors.Grasshopper7/packages.lock.json
#	Connectors/Rhino/Speckle.Connectors.Grasshopper8/packages.lock.json
#	Connectors/Rhino/Speckle.Connectors.Rhino7/packages.lock.json
#	Connectors/Rhino/Speckle.Connectors.Rhino8/packages.lock.json
#	Connectors/Tekla/Speckle.Connector.Tekla2023/packages.lock.json
#	Connectors/Tekla/Speckle.Connector.Tekla2024/packages.lock.json
#	Connectors/Tekla/Speckle.Connector.Tekla2025/packages.lock.json
#	Converters/Autocad/Speckle.Converters.Autocad2022/packages.lock.json
#	Converters/Autocad/Speckle.Converters.Autocad2023/packages.lock.json
#	Converters/Autocad/Speckle.Converters.Autocad2024/packages.lock.json
#	Converters/Autocad/Speckle.Converters.Autocad2025/packages.lock.json
#	Converters/Autocad/Speckle.Converters.Autocad2026/packages.lock.json
#	Converters/CSi/Speckle.Converters.ETABS21/packages.lock.json
#	Converters/CSi/Speckle.Converters.ETABS22/packages.lock.json
#	Converters/Civil3d/Speckle.Converters.Civil3d2022/packages.lock.json
#	Converters/Civil3d/Speckle.Converters.Civil3d2023/packages.lock.json
#	Converters/Civil3d/Speckle.Converters.Civil3d2024/packages.lock.json
#	Converters/Civil3d/Speckle.Converters.Civil3d2025/packages.lock.json
#	Converters/Civil3d/Speckle.Converters.Civil3d2026/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2020/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2021/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2022/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2023/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2024/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2025/packages.lock.json
#	Converters/Navisworks/Speckle.Converters.Navisworks2026/packages.lock.json
#	Converters/Revit/Speckle.Converters.Revit2022/packages.lock.json
#	Converters/Revit/Speckle.Converters.Revit2023/packages.lock.json
#	Converters/Revit/Speckle.Converters.Revit2024/packages.lock.json
#	Converters/Revit/Speckle.Converters.Revit2025/packages.lock.json
#	Converters/Revit/Speckle.Converters.Revit2026/packages.lock.json
#	Converters/Rhino/Speckle.Converters.Rhino7/packages.lock.json
#	Converters/Rhino/Speckle.Converters.Rhino8/packages.lock.json
#	Converters/Tekla/Speckle.Converter.Tekla2023/packages.lock.json
#	Converters/Tekla/Speckle.Converter.Tekla2024/packages.lock.json
#	Converters/Tekla/Speckle.Converter.Tekla2025/packages.lock.json
#	DUI3/Speckle.Connectors.DUI.Tests/packages.lock.json
#	DUI3/Speckle.Connectors.DUI.WebView/packages.lock.json
#	DUI3/Speckle.Connectors.DUI/packages.lock.json
#	Directory.Packages.props
#	Importers/Ifc/Speckle.Importers.Ifc.Tester/packages.lock.json
#	Importers/Ifc/Speckle.Importers.Ifc.Tester2/packages.lock.json
#	Importers/Ifc/Speckle.Importers.Ifc/packages.lock.json
#	Sdk/Speckle.Connectors.Common.Tests/packages.lock.json
#	Sdk/Speckle.Connectors.Common/packages.lock.json
#	Sdk/Speckle.Converters.Common.Tests/packages.lock.json
#	Sdk/Speckle.Converters.Common/packages.lock.json
#	Sdk/Speckle.Testing/packages.lock.json
2025-06-12 12:29:12 +01:00
Adam Hathcock afbeeef32f Update to SDK 3.4.2 (#911)
* Update to SDK 3.4.1

* fix build issues

* Update to 3.4.2

---------

Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
2025-06-12 12:14:40 +01:00
Adam Hathcock 315db9e19c Don't use static scopes for Grasshopper. Use when necessary (#907)
* Don't use static scopes for Grasshopper.  Use when necessary

* formatting

* Scope correctly
2025-06-12 10:27:39 +01:00
Claire Kuang 183e150466 feat(grasshopper): allows nested properties (#908)
* refactors property group to support nesting

* adds support for nesting speckle props

* build fixes

* removes unused fields

* refactors for simplicity on adding props to atts

* formatting fix

* updates speckle props error message
2025-06-11 20:19:13 +02:00
kekesidavid 39735ca0cb fix (civil3d) extract property sets for solids (#896)
* get properties for ADB entities is back

* removed comment

* added comment, changed condition to filter CDB entities

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-11 18:15:15 +02:00
Adam Hathcock 9d6d56ca2a Rhino API can return null when not expected (#912) 2025-06-11 16:01:09 +01:00
Adam Hathcock 22c6b23d7a Don't use static scopes for Grasshopper. Use when necessary (#907)
* Don't use static scopes for Grasshopper.  Use when necessary

* formatting

* Scope correctly
2025-06-11 11:21:50 +01:00
Adam Hathcock 21b70ec241 fix (Rhino) Missing group from applicationIdMap fix (#903)
* fix (Rhino) Missing group from applicationIdMap fix

* Throw a better exception when an application id is missed

* back to collection and added log statement
2025-06-09 17:30:05 +01:00
Adam Hathcock 72cfc8289a adds a Revit and Local slnx (#905) 2025-06-09 14:26:09 +00:00
Adam Hathcock 75117aa8d3 fix(logs) Only log errors and observe them if they're speckle related. (#887)
* Only log errors and observe them if they're speckle related.  Others log if possible and let bomb out the app

* stacktrace is nullable

* Process the exceptions as inner exceptions

* Null handling

* Change how it's fixed

* ToString

---------

Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
2025-06-09 14:12:34 +00:00
Adam Hathcock 0361e5ea10 Introduce receive manager (#895)
* Don't log conversion errors to seq?

* add cancellation

* Make a generic handler for receive conversions

* Use for all receives?

* for cancellations, rethrow

* add vibe tests

* fix up receive cancellation

* fmt

* made ReceiveOperationManager with revit

* everything compiles

* fmt

* add tests

* This check shouldn't report to seq
2025-06-09 12:21:52 +00:00
Adam Hathcock cfac52801f React to using SDK 3.4 (#894)
* use alpha to test

* Change MD5 usage

* update alpha

* update upload progress

* update sending progress

* update to SDK 3.4.0
2025-06-09 12:12:00 +00:00
Adam Hathcock 39a6fb3c50 For Receive conversions, have common path for logging errors (#892)
* Don't log conversion errors to seq?

* add cancellation

* Make a generic handler for receive conversions

* Use for all receives?

* for cancellations, rethrow

* add vibe tests

* fix up receive cancellation

* fmt
2025-06-09 10:26:10 +00:00
Adam Hathcock 6a39635162 Merge pull request #902 from specklesystems/main-dev
Main to dev (do not squash)
2025-06-09 10:07:54 +01:00
Claire Kuang c671b151b4 updates account exception on constructor of speckle operation wizard (#904)
.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-06-06 16:20:55 +01:00
Adam Hathcock 44d2419042 Merge fixes 2025-06-06 11:21:18 +01:00
Adam Hathcock 3cb50a7187 Merge remote-tracking branch 'origin/dev' into main-dev
# Conflicts:
#	Connectors/Rhino/Speckle.Connectors.RhinoShared/HostApp/RhinoLayerBaker.cs
2025-06-06 11:18:10 +01:00
Adam Hathcock 600c361d9a Merge pull request #901 from specklesystems/dim/rhino-extra-layer-name-fix
.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
Dim/rhino extra layer name fix
2025-06-06 11:09:23 +01:00
Adam Hathcock 90d83eee41 Change exceptions for not found layers on receive, they should be conversion errors (#900)
* Change exceptions for not found layers on receive, they should be conversion errors

* fmt
2025-06-06 11:05:31 +01:00
Dimitrie Stefanescu e8cff89433 fix: handles parenthesis in layer names 2025-06-06 10:57:17 +01:00
Dimitrie Stefanescu 2a4647a1b7 Merge pull request #898 from specklesystems/dim/rhino-layer-hotifix-to-main
.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
fix: cleans up rhino layer names properly for baking
2025-06-05 14:55:51 +01:00
Dimitrie Stefanescu bf97d8c029 fix: cleans up rhino layer names properly for baking 2025-06-05 14:46:13 +01:00
Adam Hathcock 8f51f4832d (fix) Avoid CEF browser exception by checking availabity before executing command (#889)
* Avoid CEF browser exception by checking availabity before executing command

* fmt
2025-06-04 10:32:47 +00:00
Jedd Morgan c496bbe817 Small tweak to IFC tester (#890) 2025-06-04 10:23:56 +00:00
Adam Hathcock 6584163911 Introduces a Send operation manager to make Send testable (#871)
* Rhino uses SendOperationManagerFactory

* revit now uses it

* autocad and civil use it

* csi, tekla and NW

* add test

* formatting

* tested with rhino and revit

* formatting

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-06-04 13:12:24 +03:00
kekesidavid b670510da4 new paletteset guid (#886) 2025-06-03 15:33:56 +02:00
Adam Hathcock 73927de454 Remove the NET6 targets now that we don't build ArcGIS (#888) 2025-06-03 13:56:13 +01:00
kekesidavid a65cf42ccf replaced svg image for tekla (#885) 2025-06-02 13:56:39 +02:00
Oğuzhan Koral 679f5bafb7 Merge pull request #884 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
Update dev into main
2025-06-02 11:41:07 +03:00
kekesidavid 1f35ee0101 fix (rhino, autocad) updated converters after text class update (#882)
* updated converters after text class update

* fix after text class changes

* packege version bump after text calss update

---------

Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
2025-06-02 10:24:46 +02:00
Claire Kuang 63c99d3086 fix(rhino): changes rhino toolbar icon (#883)
* changes rhino toolbar icon

* updates gh docs
2025-06-02 07:13:47 +00:00
Björn Steinhagen 7a0acd6c07 chore(grasshopper): rename to view created "model" online (#878)
* chore: renamed version to model

* fix: modify url too
2025-05-30 13:55:21 +00:00
Adam Hathcock 6853fa79e8 Remove ArcGIS (#879)
* Remove ArcGIS code

* Redo solutions
2025-05-30 13:36:39 +00:00
Adam Hathcock 94c04f67b0 Use current dir for generating solutions (#880) 2025-05-30 13:31:22 +01:00
kekesidavid f15612034e Merge pull request #869 from specklesystems/david/cnx-1845-etabs-v3-rename-buttons
chore (all sharp) renamed speckle beta to speckle everywhere
2025-05-30 13:37:44 +02:00
Claire Kuang 7c5a3cba60 Merge branch 'dev' into david/cnx-1845-etabs-v3-rename-buttons 2025-05-30 11:15:44 +01:00
Claire Kuang 0cec4095e2 fixes receiving name and user strings on block instances (#877)
Co-authored-by: Björn Steinhagen <steinhagen.bjoern@gmail.com>
2025-05-30 10:46:40 +01:00
Björn Steinhagen 46ab7d6110 feat(grasshopper): add inherit names functionality to variable parameter components (#867)
* feat: inherit names for create collection and create properties poc

* feat: `KeyWatcher` class for tab key auto inheritance on connecting

* docs: bonus comments

* feat: setting to always inherit

* chore: `AlwaysInheritNames` default to `false`

* feat: `AlwaysInheritNames` status of setting banner

* refactor: consistency with "names" not "nicknames"

* feat: persist `AlwaysInheritNames` setting

persist setting when closing and reopening script

* feat: automatic name inheritance for variable parameters

- automatic parameter name updates when source component names change
- event subscription shenanigans to SpeckleVariableParam for ObjectChanged events

* fix: refresh when setting enabled and ensure behaviour after

* fix: auto update when toggled after connection and document reload fix

fixes issue where enabling "Always inherit names" after connecting components didn't work and parameter names were lost when reopening saved documents.

* refactor: get rid of code duplication

* refactor: `CreateCollection`

* feat: auto-resizing of components after name change

* feat: disable parameter renaming if automatically inheriting names

* Revert "feat: disable parameter renaming if automatically inheriting names"

This reverts commit 4b348aeba0.

* fix: grey out naming when auto inherit
2025-05-29 22:42:43 +02:00
Jonathon Broughton 169cfd6123 Differentiates legacy Navisworks connector (#873)
* Updates legacy logo files

* Replace v3 logo resources

* Differentiates legacy connector

Makes the legacy connector distinguishable in the UI.
This ensures that users can easily identify and select the correct version.
2025-05-28 09:01:18 +02:00
David Kekesi 83b7280758 new speckle icon for all sharp connectors 2025-05-27 13:25:56 +02:00
David Kekesi 30ea9858c6 renamed speckle beta to speckle everywhere 2025-05-26 12:59:27 +02:00
434 changed files with 12888 additions and 15085 deletions
-424
View File
@@ -1,424 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35027.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{85A13E25-EB29-4F31-8853-B9EE83275B3D}"
ProjectSection(SolutionItems) = preProject
.csharpierrc.yaml = .csharpierrc.yaml
.editorconfig = .editorconfig
codecov.yml = codecov.yml
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
global.json = global.json
README.md = README.md
CodeMetricsConfig.txt = CodeMetricsConfig.txt
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DUI3", "DUI3", "{FD4D6594-D81E-456F-8F2E-35B09E04A755}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Revit", "Revit", "{D92751C8-1039-4005-90B2-913E55E0B8BD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{2E00592E-558D-492D-88F9-3ECEE4C0C7DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2023", "Connectors\Revit\Speckle.Connectors.Revit2023\Speckle.Connectors.Revit2023.csproj", "{01F98733-7352-47AD-A594-537D979DE3DE}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.RevitShared", "Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.shproj", "{DC570FFF-6FE5-47BD-8BC1-B471A6067786}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared", "Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.shproj", "{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2023.DependencyInjection\Speckle.Converters.Revit2023.DependencyInjection.csproj", "{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023", "Converters\Revit\Speckle.Converters.Revit2023\Speckle.Converters.Revit2023.csproj", "{26391930-F86F-47E0-A5F6-B89919E38CE1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.DUI", "DUI3\Speckle.Connectors.DUI\Speckle.Connectors.DUI.csproj", "{D81C0B87-F0C1-4297-A147-02F001FB7E1E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Autofac", "Sdk\Speckle.Autofac\Speckle.Autofac.csproj", "{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Utils", "Sdk\Speckle.Connectors.Utils\Speckle.Connectors.Utils.csproj", "{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Common", "Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj", "{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Rhino", "Rhino", "{9584AEE5-CD59-46E6-93E6-2DC2B5285B75}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Rhino7", "Connectors\Rhino\Speckle.Connectors.Rhino7\Speckle.Connectors.Rhino7.csproj", "{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7", "Converters\Rhino\Speckle.Converters.Rhino7\Speckle.Converters.Rhino7.csproj", "{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7.DependencyInjection", "Converters\Rhino\Speckle.Converters.Rhino7.DependencyInjection\Speckle.Converters.Rhino7.DependencyInjection.csproj", "{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.ArcGIS3", "Connectors\ArcGIS\Speckle.Connectors.ArcGIS3\Speckle.Connectors.ArcGIS3.csproj", "{A97F7177-86C7-4B38-A6ED-DA51BF762471}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.ArcGIS3", "Converters\ArcGIS\Speckle.Converters.ArcGIS3\Speckle.Converters.ArcGIS3.csproj", "{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.ArcGIS3.DependencyInjection", "Converters\ArcGIS\Speckle.Converters.ArcGIS3.DependencyInjection\Speckle.Converters.ArcGIS3.DependencyInjection.csproj", "{7DFF1591-237D-499E-A767-EE37B93FB958}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ArcGIS", "ArcGIS", "{CCF48B65-33D1-4E8B-A57B-E03394730B21}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Autocad2023", "Connectors\Autocad\Speckle.Connectors.Autocad2023\Speckle.Connectors.Autocad2023.csproj", "{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.AutocadShared", "Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.shproj", "{41BC679F-887F-44CF-971D-A5502EE87DB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Common.DependencyInjection", "Sdk\Speckle.Converters.Common.DependencyInjection\Speckle.Converters.Common.DependencyInjection.csproj", "{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Autocad", "Autocad", "{804E065F-914C-414A-AF84-009312C3CFF6}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.AutocadShared", "Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.shproj", "{9ADD1B7A-6401-4202-8613-F668E2FBC0A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2023", "Converters\Autocad\Speckle.Converters.Autocad2023\Speckle.Converters.Autocad2023.csproj", "{631C295A-7CCF-4B42-8686-7034E31469E7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2023.DependencyInjection", "Converters\Autocad\Speckle.Converters.Autocad2023.DependencyInjection\Speckle.Converters.Autocad2023.DependencyInjection.csproj", "{D940853C-003A-482C-BDB0-665367F274A0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.DUI.WebView", "DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj", "{7420652C-3046-4F38-BE64-9B9E69D76FA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "Build\Build.csproj", "{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HostApps", "HostApps", "{42826721-9A18-4762-8BA9-F1429DD5C5B1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{59E8E8F3-4E42-4E92-83B3-B1C2AB901D18}"
ProjectSection(SolutionItems) = preProject
.github\workflows\ci.yml = .github\workflows\ci.yml
.github\workflows\main.yml = .github\workflows\main.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Civil3d2024", "Connectors\Autocad\Speckle.Connectors.Civil3d2024\Speckle.Connectors.Civil3d2024.csproj", "{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.Civil3dShared", "Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.shproj", "{35175682-DA83-4C0A-A49D-B191F5885D8E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Civil3d2024.DependencyInjection", "Converters\Civil3d\Speckle.Converters.Civil3d2024.DependencyInjection\Speckle.Converters.Civil3d2024.DependencyInjection.csproj", "{80F965C4-E2A8-4F54-985D-73D06E45F9CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2024", "Converters\Autocad\Speckle.Converters.Autocad2024\Speckle.Converters.Autocad2024.csproj", "{C2DE264A-AA87-4012-B954-17E3F403A237}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Autocad2024.DependencyInjection", "Converters\Autocad\Speckle.Converters.Autocad2024.DependencyInjection\Speckle.Converters.Autocad2024.DependencyInjection.csproj", "{AF507D61-6766-4C20-9F58-23DC29508219}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Civil3d2024", "Converters\Civil3d\Speckle.Converters.Civil3d2024\Speckle.Converters.Civil3d2024.csproj", "{25172C49-7AA4-4739-BB07-69785094C379}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RhinoShared", "Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.shproj", "{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Rhino7.Tests", "Converters\Rhino\Speckle.Converters.Rhino7.Tests\Speckle.Converters.Rhino7.Tests.csproj", "{AC2DB416-F05C-4296-9040-56D6AD4FCD27}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2023.Tests", "Converters\Revit\Speckle.Converters.Revit2023.Tests\Speckle.Converters.Revit2023.Tests.csproj", "{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Testing", "Sdk\Speckle.Testing\Speckle.Testing.csproj", "{A3869243-B462-4986-914B-94E407D8D20F}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared.DependencyInjection", "Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.shproj", "{6067BA60-D279-4156-8AE1-6B44E2D19187}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2024", "Connectors\Revit\Speckle.Connectors.Revit2024\Speckle.Connectors.Revit2024.csproj", "{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024", "Converters\Revit\Speckle.Converters.Revit2024\Speckle.Converters.Revit2024.csproj", "{67B888D9-C6C4-49F1-883C-5B964151D889}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2024.DependencyInjection\Speckle.Converters.Revit2024.DependencyInjection.csproj", "{7F3055BA-70AA-424C-8748-345AF35127E9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2024", "2024", "{57F59C0C-5687-4AF9-AE1C-1933B539F0E4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{FC224610-32D3-454E-9BC1-1219FE8ACD5F}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.RevitShared.Tests", "Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.shproj", "{E1C43415-3202-45F4-8BF9-A4DD7D7F2ED6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2024.Tests", "Converters\Revit\Speckle.Converters.Revit2024.Tests\Speckle.Converters.Revit2024.Tests.csproj", "{C32274D9-1B66-4D5C-82F9-EB3F10F46752}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.RevitShared.Cef", "Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.shproj", "{6A40CBE4-ECAB-4CED-9917-5C64CBF75DA6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2025", "2025", "{8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2025", "Connectors\Revit\Speckle.Connectors.Revit2025\Speckle.Connectors.Revit2025.csproj", "{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2025", "Converters\Revit\Speckle.Converters.Revit2025\Speckle.Converters.Revit2025.csproj", "{4D40A101-07E6-4FF2-8934-83434932591D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2025.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2025.DependencyInjection\Speckle.Converters.Revit2025.DependencyInjection.csproj", "{20751904-0DFC-4126-BF2A-834B53841010}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.Revit2022", "Connectors\Revit\Speckle.Connectors.Revit2022\Speckle.Connectors.Revit2022.csproj", "{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022", "Converters\Revit\Speckle.Converters.Revit2022\Speckle.Converters.Revit2022.csproj", "{19424B55-058C-4E9C-B86F-700AEF9EAEC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022.DependencyInjection", "Converters\Revit\Speckle.Converters.Revit2022.DependencyInjection\Speckle.Converters.Revit2022.DependencyInjection.csproj", "{881D71A3-D276-4108-98C6-0FFD32129B9C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2022", "2022", "{0AF38BA3-65A0-481B-8CBB-B82E406E1575}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.DUI.Tests", "DUI3\Speckle.Connectors.DUI.Tests\Speckle.Connectors.DUI.Tests.csproj", "{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converters.Revit2022.Tests", "Converters\Revit\Speckle.Converters.Revit2022.Tests\Speckle.Converters.Revit2022.Tests.csproj", "{D8069A23-AD2E-4C9E-8574-7E8C45296A46}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{2D5AE63D-85C0-43D1-84BF-04418ED93F63}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2024", "2024", "{2F45036E-D817-41E9-B82F-DBE013EC95D0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Civil3d", "Civil3d", "{91D70DE1-DC8E-4AE1-B100-0671D6263FC5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{4721AA15-AF6E-4A62-A2C3-65564DC563E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{01F98733-7352-47AD-A594-537D979DE3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01F98733-7352-47AD-A594-537D979DE3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01F98733-7352-47AD-A594-537D979DE3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01F98733-7352-47AD-A594-537D979DE3DE}.Release|Any CPU.Build.0 = Release|Any CPU
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E}.Release|Any CPU.Build.0 = Release|Any CPU
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26391930-F86F-47E0-A5F6-B89919E38CE1}.Release|Any CPU.Build.0 = Release|Any CPU
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D81C0B87-F0C1-4297-A147-02F001FB7E1E}.Release|Any CPU.Build.0 = Release|Any CPU
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6}.Release|Any CPU.Build.0 = Release|Any CPU
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC}.Release|Any CPU.Build.0 = Release|Any CPU
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434}.Release|Any CPU.Build.0 = Release|Any CPU
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21}.Release|Any CPU.Build.0 = Release|Any CPU
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5}.Release|Any CPU.Build.0 = Release|Any CPU
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D}.Release|Any CPU.Build.0 = Release|Any CPU
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A97F7177-86C7-4B38-A6ED-DA51BF762471}.Release|Any CPU.Build.0 = Release|Any CPU
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C}.Release|Any CPU.Build.0 = Release|Any CPU
{7DFF1591-237D-499E-A767-EE37B93FB958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DFF1591-237D-499E-A767-EE37B93FB958}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DFF1591-237D-499E-A767-EE37B93FB958}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DFF1591-237D-499E-A767-EE37B93FB958}.Release|Any CPU.Build.0 = Release|Any CPU
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395}.Release|Any CPU.Build.0 = Release|Any CPU
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B}.Release|Any CPU.Build.0 = Release|Any CPU
{631C295A-7CCF-4B42-8686-7034E31469E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{631C295A-7CCF-4B42-8686-7034E31469E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{631C295A-7CCF-4B42-8686-7034E31469E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{631C295A-7CCF-4B42-8686-7034E31469E7}.Release|Any CPU.Build.0 = Release|Any CPU
{D940853C-003A-482C-BDB0-665367F274A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D940853C-003A-482C-BDB0-665367F274A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D940853C-003A-482C-BDB0-665367F274A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D940853C-003A-482C-BDB0-665367F274A0}.Release|Any CPU.Build.0 = Release|Any CPU
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7420652C-3046-4F38-BE64-9B9E69D76FA2}.Release|Any CPU.Build.0 = Release|Any CPU
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}.Release|Any CPU.Build.0 = Release|Any CPU
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1}.Release|Any CPU.Build.0 = Release|Any CPU
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80F965C4-E2A8-4F54-985D-73D06E45F9CE}.Release|Any CPU.Build.0 = Release|Any CPU
{C2DE264A-AA87-4012-B954-17E3F403A237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2DE264A-AA87-4012-B954-17E3F403A237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2DE264A-AA87-4012-B954-17E3F403A237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2DE264A-AA87-4012-B954-17E3F403A237}.Release|Any CPU.Build.0 = Release|Any CPU
{AF507D61-6766-4C20-9F58-23DC29508219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF507D61-6766-4C20-9F58-23DC29508219}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF507D61-6766-4C20-9F58-23DC29508219}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF507D61-6766-4C20-9F58-23DC29508219}.Release|Any CPU.Build.0 = Release|Any CPU
{25172C49-7AA4-4739-BB07-69785094C379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25172C49-7AA4-4739-BB07-69785094C379}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25172C49-7AA4-4739-BB07-69785094C379}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25172C49-7AA4-4739-BB07-69785094C379}.Release|Any CPU.Build.0 = Release|Any CPU
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC2DB416-F05C-4296-9040-56D6AD4FCD27}.Release|Any CPU.Build.0 = Release|Any CPU
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051}.Release|Any CPU.Build.0 = Release|Any CPU
{A3869243-B462-4986-914B-94E407D8D20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A3869243-B462-4986-914B-94E407D8D20F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A3869243-B462-4986-914B-94E407D8D20F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A3869243-B462-4986-914B-94E407D8D20F}.Release|Any CPU.Build.0 = Release|Any CPU
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC}.Release|Any CPU.Build.0 = Release|Any CPU
{67B888D9-C6C4-49F1-883C-5B964151D889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67B888D9-C6C4-49F1-883C-5B964151D889}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67B888D9-C6C4-49F1-883C-5B964151D889}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67B888D9-C6C4-49F1-883C-5B964151D889}.Release|Any CPU.Build.0 = Release|Any CPU
{7F3055BA-70AA-424C-8748-345AF35127E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F3055BA-70AA-424C-8748-345AF35127E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F3055BA-70AA-424C-8748-345AF35127E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F3055BA-70AA-424C-8748-345AF35127E9}.Release|Any CPU.Build.0 = Release|Any CPU
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C32274D9-1B66-4D5C-82F9-EB3F10F46752}.Release|Any CPU.Build.0 = Release|Any CPU
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C}.Release|Any CPU.Build.0 = Release|Any CPU
{4D40A101-07E6-4FF2-8934-83434932591D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D40A101-07E6-4FF2-8934-83434932591D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D40A101-07E6-4FF2-8934-83434932591D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D40A101-07E6-4FF2-8934-83434932591D}.Release|Any CPU.Build.0 = Release|Any CPU
{20751904-0DFC-4126-BF2A-834B53841010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20751904-0DFC-4126-BF2A-834B53841010}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20751904-0DFC-4126-BF2A-834B53841010}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20751904-0DFC-4126-BF2A-834B53841010}.Release|Any CPU.Build.0 = Release|Any CPU
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Debug|Any CPU.ActiveCfg = Debug|x64
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Debug|Any CPU.Build.0 = Debug|x64
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Release|Any CPU.ActiveCfg = Debug|x64
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36}.Release|Any CPU.Build.0 = Debug|x64
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19424B55-058C-4E9C-B86F-700AEF9EAEC3}.Release|Any CPU.Build.0 = Release|Any CPU
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{881D71A3-D276-4108-98C6-0FFD32129B9C}.Release|Any CPU.Build.0 = Release|Any CPU
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885}.Release|Any CPU.Build.0 = Release|Any CPU
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8069A23-AD2E-4C9E-8574-7E8C45296A46}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D92751C8-1039-4005-90B2-913E55E0B8BD} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
{01F98733-7352-47AD-A594-537D979DE3DE} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
{DC570FFF-6FE5-47BD-8BC1-B471A6067786} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
{83EAD6F0-3CB3-456A-AD81-072127D0DE0E} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
{26391930-F86F-47E0-A5F6-B89919E38CE1} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
{D81C0B87-F0C1-4297-A147-02F001FB7E1E} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
{C9D4CA21-182B-4ED2-81BB-280A6FD713F6} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
{7291B93C-615D-42DE-B8C1-3F9DF643E0FC} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
{8AEF06C0-CA5C-4460-BC2D-ADE5F35D0434} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
{9584AEE5-CD59-46E6-93E6-2DC2B5285B75} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
{1E2644A9-6B31-4350-8772-CEAAD6EE0B21} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
{65A2F556-F14A-49F3-8A92-7F2E1E7ED3B5} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
{9C1ECA1D-DE98-4FB7-92D0-FC45BB308E5D} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
{A97F7177-86C7-4B38-A6ED-DA51BF762471} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
{139F7A79-69E4-4B8A-B2A5-6A30A66C495C} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
{7DFF1591-237D-499E-A767-EE37B93FB958} = {CCF48B65-33D1-4E8B-A57B-E03394730B21}
{CCF48B65-33D1-4E8B-A57B-E03394730B21} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
{11F7D41B-AFCA-4D29-BC08-285A14BF3A3B} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
{804E065F-914C-414A-AF84-009312C3CFF6} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
{7420652C-3046-4F38-BE64-9B9E69D76FA2} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89} = {59E8E8F3-4E42-4E92-83B3-B1C2AB901D18}
{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED9} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
{AC2DB416-F05C-4296-9040-56D6AD4FCD27} = {9584AEE5-CD59-46E6-93E6-2DC2B5285B75}
{68CF9BDF-94AC-4D2D-A7BD-D1C064F97051} = {E9DEBA00-50A4-485D-BA65-D8AB3E3467AB}
{A3869243-B462-4986-914B-94E407D8D20F} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
{6067BA60-D279-4156-8AE1-6B44E2D19187} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
{617BD3C7-87D9-4D28-8AC9-4910945BB9FC} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
{67B888D9-C6C4-49F1-883C-5B964151D889} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
{7F3055BA-70AA-424C-8748-345AF35127E9} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
{E9DEBA00-50A4-485D-BA65-D8AB3E3467AB} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{57F59C0C-5687-4AF9-AE1C-1933B539F0E4} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{FC224610-32D3-454E-9BC1-1219FE8ACD5F} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{E1C43415-3202-45F4-8BF9-A4DD7D7F2ED6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
{C32274D9-1B66-4D5C-82F9-EB3F10F46752} = {57F59C0C-5687-4AF9-AE1C-1933B539F0E4}
{6A40CBE4-ECAB-4CED-9917-5C64CBF75DA6} = {FC224610-32D3-454E-9BC1-1219FE8ACD5F}
{8AC2AD6D-6C74-4B24-8DF6-42717FC9B804} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{A6DE3DA0-B242-4F49-AEF0-4E26AF92D16C} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
{4D40A101-07E6-4FF2-8934-83434932591D} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
{20751904-0DFC-4126-BF2A-834B53841010} = {8AC2AD6D-6C74-4B24-8DF6-42717FC9B804}
{7F1FDCF2-0CE8-4119-B3C1-F2CC6D7E1C36} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
{19424B55-058C-4E9C-B86F-700AEF9EAEC3} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
{881D71A3-D276-4108-98C6-0FFD32129B9C} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
{0AF38BA3-65A0-481B-8CBB-B82E406E1575} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{EB83A3A3-F9B6-4281-8EBF-F7289FB5D885} = {FD4D6594-D81E-456F-8F2E-35B09E04A755}
{D8069A23-AD2E-4C9E-8574-7E8C45296A46} = {0AF38BA3-65A0-481B-8CBB-B82E406E1575}
{2D5AE63D-85C0-43D1-84BF-04418ED93F63} = {804E065F-914C-414A-AF84-009312C3CFF6}
{89C4CBC7-1606-40DE-B6DA-FBE3AAC98395} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
{631C295A-7CCF-4B42-8686-7034E31469E7} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
{D940853C-003A-482C-BDB0-665367F274A0} = {2D5AE63D-85C0-43D1-84BF-04418ED93F63}
{2F45036E-D817-41E9-B82F-DBE013EC95D0} = {804E065F-914C-414A-AF84-009312C3CFF6}
{C2DE264A-AA87-4012-B954-17E3F403A237} = {2F45036E-D817-41E9-B82F-DBE013EC95D0}
{AF507D61-6766-4C20-9F58-23DC29508219} = {2F45036E-D817-41E9-B82F-DBE013EC95D0}
{91D70DE1-DC8E-4AE1-B100-0671D6263FC5} = {804E065F-914C-414A-AF84-009312C3CFF6}
{CA8EAE01-AB9F-4EC1-B6F3-73721487E9E1} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
{25172C49-7AA4-4739-BB07-69785094C379} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
{80F965C4-E2A8-4F54-985D-73D06E45F9CE} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
{35175682-DA83-4C0A-A49D-B191F5885D8E} = {91D70DE1-DC8E-4AE1-B100-0671D6263FC5}
{4721AA15-AF6E-4A62-A2C3-65564DC563E6} = {804E065F-914C-414A-AF84-009312C3CFF6}
{41BC679F-887F-44CF-971D-A5502EE87DB0} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6}
{9ADD1B7A-6401-4202-8613-F668E2FBC0A4} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{01f98733-7352-47ad-a594-537d979de3de}*SharedItemsImports = 5
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{01f98733-7352-47ad-a594-537d979de3de}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{19424b55-058c-4e9c-b86f-700aef9eaec3}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{20751904-0dfc-4126-bf2a-834b53841010}*SharedItemsImports = 5
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{25172c49-7aa4-4739-bb07-69785094c379}*SharedItemsImports = 5
Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.projitems*{25172c49-7aa4-4739-bb07-69785094c379}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{26391930-f86f-47e0-a5f6-b89919e38ce1}*SharedItemsImports = 5
Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.projitems*{35175682-da83-4c0a-a49d-b191f5885d8e}*SharedItemsImports = 13
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{41bc679f-887f-44cf-971d-a5502ee87db0}*SharedItemsImports = 13
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{4d40a101-07e6-4ff2-8934-83434932591d}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{6067ba60-d279-4156-8ae1-6b44e2d19187}*SharedItemsImports = 13
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{617bd3c7-87d9-4d28-8ac9-4910945bb9fc}*SharedItemsImports = 5
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{617bd3c7-87d9-4d28-8ac9-4910945bb9fc}*SharedItemsImports = 5
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{631c295a-7ccf-4b42-8686-7034e31469e7}*SharedItemsImports = 5
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{65a2f556-f14a-49f3-8a92-7f2e1e7ed3b5}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{67b888d9-c6c4-49f1-883c-5b964151d889}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{68cf9bdf-94ac-4d2d-a7bd-d1c064f97051}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{68cf9bdf-94ac-4d2d-a7bd-d1c064f97051}*SharedItemsImports = 5
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{6a40cbe4-ecab-4ced-9917-5c64cbf75da6}*SharedItemsImports = 13
Connectors\Revit\Speckle.Connectors.RevitShared.Cef\Speckle.Connectors.RevitShared.Cef.projitems*{7f1fdcf2-0ce8-4119-b3c1-f2cc6d7e1c36}*SharedItemsImports = 5
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{7f1fdcf2-0ce8-4119-b3c1-f2cc6d7e1c36}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{7f3055ba-70aa-424c-8748-345af35127e9}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{83ead6f0-3cb3-456a-ad81-072127d0de0e}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.DependencyInjection\Speckle.Converters.RevitShared.DependencyInjection.projitems*{881d71a3-d276-4108-98c6-0ffd32129b9c}*SharedItemsImports = 5
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{89c4cbc7-1606-40de-b6da-fbe3aac98395}*SharedItemsImports = 5
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{9add1b7a-6401-4202-8613-f668e2fbc0a4}*SharedItemsImports = 13
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{a6de3da0-b242-4f49-aef0-4e26af92d16c}*SharedItemsImports = 5
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{ac2db416-f05c-4296-9040-56d6ad4fcd27}*SharedItemsImports = 5
Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{c2de264a-aa87-4012-b954-17e3f403a237}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{c32274d9-1b66-4d5c-82f9-eb3f10f46752}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{c32274d9-1b66-4d5c-82f9-eb3f10f46752}*SharedItemsImports = 5
Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{ca8eae01-ab9f-4ec1-b6f3-73721487e9e1}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{d8069a23-ad2e-4c9e-8574-7e8c45296a46}*SharedItemsImports = 5
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{d8069a23-ad2e-4c9e-8574-7e8c45296a46}*SharedItemsImports = 5
Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{dc570fff-6fe5-47bd-8bc1-b471a6067786}*SharedItemsImports = 13
Converters\Revit\Speckle.Converters.RevitShared\Speckle.Converters.RevitShared.projitems*{e1c43415-3200-45f4-8bf9-a4dd7d7f2ed6}*SharedItemsImports = 13
Converters\Rhino\Speckle.Converters.RhinoShared\Speckle.Converters.RhinoShared.projitems*{e1c43415-3200-45f4-8bf9-a4dd7d7f2ed9}*SharedItemsImports = 13
Converters\Revit\Speckle.Converters.RevitShared.Tests\Speckle.Converters.RevitShared.Tests.projitems*{e1c43415-3202-45f4-8bf9-a4dd7d7f2ed6}*SharedItemsImports = 13
EndGlobalSection
EndGlobal
-1
View File
@@ -6,7 +6,6 @@ public static class Consts
public static readonly ProjectGroup[] ProjectGroups =
{
new("arcgis", [new("Connectors/ArcGIS/Speckle.Connectors.ArcGIS3", "net6.0-windows")]),
new(
"rhino",
[
+39 -29
View File
@@ -1,48 +1,49 @@
using Microsoft.Build.Construction;
using Microsoft.VisualStudio.SolutionPersistence.Model;
using Microsoft.VisualStudio.SolutionPersistence.Model;
using Microsoft.VisualStudio.SolutionPersistence.Serializer;
namespace Build;
public static class Solutions
{
private static bool ValidProjects(KeyValuePair<string, ProjectInSolution> projectInSolution) =>
projectInSolution.Value.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat;
public static void CompareConnectorsToLocal()
#pragma warning disable CA1802
#pragma warning disable IDE1006
private static readonly string DIRECTORY = Environment.CurrentDirectory;
#pragma warning restore IDE1006
#pragma warning restore CA1802
public static async Task CompareConnectorsToLocal()
{
var localSln = SolutionFile.Parse(Path.Combine(Environment.CurrentDirectory, "Local.sln"));
var connectorsSln = SolutionFile.Parse(Path.Combine(Environment.CurrentDirectory, "Speckle.Connectors.sln"));
var localProjects = localSln.ProjectsByGuid.Where(ValidProjects).ToDictionary();
var localSln = await GetSolution("Local.sln");
var connectorsSln = await GetSolution("Speckle.Connectors.sln");
var localProjects = localSln.SolutionProjects.ToList();
foreach ((string? _, ProjectInSolution? value) in connectorsSln.ProjectsByGuid.Where(ValidProjects))
foreach (var value in connectorsSln.SolutionProjects)
{
var localProject = localProjects.Values.FirstOrDefault(x => x.ProjectName == value.ProjectName);
var localProject = localProjects.FirstOrDefault(x => x.ActualDisplayName == value.ActualDisplayName);
if (localProject is null)
{
throw new InvalidOperationException($"Could not find in LOCAL solution: {value.ProjectName}");
throw new InvalidOperationException($"Could not find in LOCAL solution: {value.ActualDisplayName}");
}
if (value.ProjectName != localProject.ProjectName)
if (value.ActualDisplayName != localProject.ActualDisplayName)
{
throw new InvalidOperationException(
"Projects with different names have same Guid in solution: "
+ value.ProjectName
+ value.ActualDisplayName
+ " and "
+ localProject.ProjectName
+ localProject.ActualDisplayName
);
}
localProjects.Remove(localProjects.Single(x => x.Value.ProjectName == value.ProjectName).Key);
localProjects.Remove(localProjects.Single(x => x.ActualDisplayName == value.ActualDisplayName));
}
void CheckAndRemoveKnown(string projectName)
{
var localProject = localProjects.Values.FirstOrDefault(x => x.ProjectName == projectName);
var localProject = localProjects.FirstOrDefault(x => x.ActualDisplayName == projectName);
if (localProject is null)
{
throw new InvalidOperationException($"Could not find in LOCAL solution: {projectName}");
}
localProjects.Remove(localProjects.Single(x => x.Value.ProjectName == projectName).Key);
localProjects.Remove(localProjects.Single(x => x.ActualDisplayName == projectName));
}
CheckAndRemoveKnown("Speckle.Objects");
@@ -51,7 +52,7 @@ public static class Solutions
if (localProjects.Count != 0)
{
throw new InvalidOperationException(
"Could not find in CONNECTOR solution: " + localProjects.First().Value.ProjectName
"Could not find in CONNECTOR solution: " + localProjects.First().ActualDisplayName
);
}
}
@@ -61,9 +62,9 @@ public static class Solutions
await GenerateLocalSlnx();
foreach (var group in Consts.ProjectGroups)
{
var path = group.Projects[0].ProjectPath.Split('/');
var folder = $"/{path[0]}/{path[1]}/";
await GenerateConnector(group.HostAppSlug, folder);
var connectors = await GetFullSlnx();
var slug = group.HostAppSlug;
await GenerateConnector(connectors, group, string.Concat(slug[0].ToString().ToUpper(), slug.AsSpan(1)));
}
}
@@ -73,16 +74,19 @@ public static class Solutions
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Objects\\Speckle.Objects.csproj");
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Sdk\\Speckle.Sdk.csproj");
connectors.AddProject("..\\speckle-sharp-sdk\\src\\Speckle.Sdk.Dependencies\\Speckle.Sdk.Dependencies.csproj");
var sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Local.slnx");
var sln = Path.Combine(DIRECTORY, "Local.slnx");
await SolutionSerializers.SlnXml.SaveAsync(sln, connectors, default);
sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Local.sln");
sln = Path.Combine(DIRECTORY, "Local.sln");
await SolutionSerializers.SlnFileV12.SaveAsync(sln, connectors, default);
var revit = Consts.ProjectGroups.Single(x => x.HostAppSlug.Equals("revit"));
await GenerateConnector(connectors, revit, "Revit.Local");
}
public static async Task GenerateConnector(string slug, string folder)
public static async Task GenerateConnector(SolutionModel connectors, ProjectGroup group, string? name)
{
slug = string.Concat(slug[0].ToString().ToUpper(), slug.AsSpan(1));
var connectors = await GetFullSlnx();
var path = group.Projects[0].ProjectPath.Split('/');
var folder = $"/{path[0]}/{path[1]}/";
var foldersToRemove = connectors
.SolutionFolders.Where(x =>
//need base folder
@@ -95,13 +99,19 @@ public static class Solutions
{
connectors.RemoveFolder(folderToRemove);
}
var sln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", $"Speckle.{slug}.slnx");
var sln = Path.Combine(DIRECTORY, $"Speckle.{name}.slnx");
await SolutionSerializers.SlnXml.SaveAsync(sln, connectors, default);
}
public static async Task<SolutionModel> GetFullSlnx()
{
var connectorsSln = Path.Combine("C:\\Users\\adam\\Git\\speckle-sharp-connectors", "Speckle.Connectors.slnx");
var connectorsSln = Path.Combine(DIRECTORY, "Speckle.Connectors.slnx");
return await SolutionSerializers.SlnXml.OpenAsync(connectorsSln, default);
}
public static async Task<SolutionModel> GetSolution(string solutionName)
{
var connectorsSln = Path.Combine(DIRECTORY, solutionName);
return await SolutionSerializers.SlnFileV12.OpenAsync(connectorsSln, default);
}
}
@@ -1,105 +0,0 @@
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Mapping;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converters.ArcGIS3;
using Speckle.Converters.ArcGIS3.Utils;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.ArcGIS.Bindings;
public sealed class ArcGISReceiveBinding : IReceiveBinding
{
public string Name { get; } = "receiveBinding";
private readonly ICancellationManager _cancellationManager;
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<ArcGISReceiveBinding> _logger;
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
private ReceiveBindingUICommands Commands { get; }
public IBrowserBridge Parent { get; }
public ArcGISReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<ArcGISReceiveBinding> logger,
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory
)
{
_store = store;
_cancellationManager = cancellationManager;
Parent = parent;
Commands = new ReceiveBindingUICommands(parent);
_serviceProvider = serviceProvider;
_operationProgressManager = operationProgressManager;
_logger = logger;
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
}
public async Task Receive(string modelCardId)
{
try
{
// Get receiver card
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No download model card was found.");
}
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
// Receive host objects
var receiveOperationResults = await scope
.ServiceProvider.GetRequiredService<ReceiveOperation>()
.Execute(
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
await Commands.SetModelReceiveResult(
modelCardId,
receiveOperationResults.BakedObjectIds,
receiveOperationResults.ConversionResults
);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
}
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
}
@@ -1,71 +0,0 @@
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
namespace Speckle.Connectors.ArcGIS.Bindings;
public class ArcGISSelectionBinding : ISelectionBinding
{
private readonly MapMembersUtils _mapMemberUtils;
public string Name => "selectionBinding";
public IBrowserBridge Parent { get; }
public ArcGISSelectionBinding(
IBrowserBridge parent,
MapMembersUtils mapMemberUtils,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_mapMemberUtils = mapMemberUtils;
Parent = parent;
// example: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Authoring/QueryBuilderControl/DefinitionQueryDockPaneViewModel.cs
// MapViewEventArgs args = new(MapView.Active);
TOCSelectionChangedEvent.Subscribe(_ => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged), true);
}
private void OnSelectionChanged()
{
SelectionInfo selInfo = GetSelection();
Parent.Send(SelectionBindingEvents.SET_SELECTION, selInfo);
}
private void GetLayersFromGroup(GroupLayer group, List<MapMember> nestedLayers)
{
nestedLayers.Add(group);
foreach (MapMember member in group.Layers)
{
if (member is GroupLayer subGroup)
{
GetLayersFromGroup(subGroup, nestedLayers);
}
else
{
nestedLayers.Add(member);
}
}
}
public SelectionInfo GetSelection()
{
MapView mapView = MapView.Active;
List<MapMember> selectedMembers = new();
selectedMembers.AddRange(mapView.GetSelectedLayers());
selectedMembers.AddRange(mapView.GetSelectedStandaloneTables());
List<MapMember> allNestedMembers = new();
var layerMapMembers = _mapMemberUtils.UnpackMapLayers(selectedMembers);
allNestedMembers.AddRange(layerMapMembers);
List<string> objectTypes = allNestedMembers
.Select(o => o.GetType().ToString().Split(".").Last())
.Distinct()
.ToList();
return new SelectionInfo(
allNestedMembers.Select(x => x.URI).ToList(),
$"{allNestedMembers.Count} layers ({string.Join(", ", objectTypes)})"
);
}
}
@@ -1,483 +0,0 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.ArcGIS.Filters;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Converters.ArcGIS3;
using Speckle.Converters.ArcGIS3.Utils;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Common;
namespace Speckle.Connectors.ArcGIS.Bindings;
public sealed class ArcGISSendBinding : ISendBinding
{
public string Name => "sendBinding";
public SendBindingUICommands Commands { get; }
public IBrowserBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly ICancellationManager _cancellationManager;
private readonly ISendConversionCache _sendConversionCache;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<ArcGISSendBinding> _logger;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
private readonly IThreadContext _threadContext;
private readonly ISpeckleApplication _speckleApplication;
/// <summary>
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
/// [CNX-202: Unhandled Exception Occurred when receiving in Rhino](https://linear.app/speckle/issue/CNX-202/unhandled-exception-occurred-when-receiving-in-rhino)
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
/// </summary>
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
private List<FeatureLayer> SubscribedLayers { get; set; } = new();
private List<StandaloneTable> SubscribedTables { get; set; } = new();
private readonly MapMembersUtils _mapMemberUtils;
public ArcGISSendBinding(
DocumentModelStore store,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
ICancellationManager cancellationManager,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<ArcGISSendBinding> logger,
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
MapMembersUtils mapMemberUtils,
IThreadContext threadContext,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_store = store;
_serviceProvider = serviceProvider;
_sendFilters = sendFilters.ToList();
_cancellationManager = cancellationManager;
_sendConversionCache = sendConversionCache;
_operationProgressManager = operationProgressManager;
_logger = logger;
_topLevelExceptionHandler = topLevelExceptionHandler;
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
_mapMemberUtils = mapMemberUtils;
_threadContext = threadContext;
_speckleApplication = speckleApplication;
Parent = parent;
Commands = new SendBindingUICommands(parent);
SubscribeToArcGISEvents();
_store.DocumentChanged += (_, _) =>
{
_sendConversionCache.ClearCache();
};
}
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
private void SubscribeToArcGISEvents()
{
LayersRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
),
true
);
StandaloneTablesRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
),
true
);
MapPropertyChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
),
true
); // Map units, CRS etc.
MapMemberPropertiesChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
),
true
); // e.g. Layer name
ActiveMapViewChangedEvent.Subscribe(
_ =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
}),
true
);
/*
LayersAddedEvent.Subscribe(a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForLayersAddedEvent(a)), true);
StandaloneTablesAddedEvent.Subscribe(
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForStandaloneTablesAddedEvent(a)),
true
);
*/
}
private void SubscribeToMapMembersDataSourceChange()
{
if (MapView.Active == null)
{
return;
}
// subscribe to layers
foreach (Layer layer in MapView.Active.Map.Layers)
{
if (layer is FeatureLayer featureLayer)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
}
}
// subscribe to tables
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
{
SubscribeToTableDataSourceChange(table);
}
}
private void SubscribeToFeatureLayerDataSourceChange(FeatureLayer layer)
{
if (SubscribedLayers.Contains(layer))
{
return;
}
Table layerTable = layer.GetTable();
if (layerTable != null)
{
SubscribeToAnyDataSourceChange(layerTable);
SubscribedLayers.Add(layer);
}
}
private void SubscribeToTableDataSourceChange(StandaloneTable table)
{
if (SubscribedTables.Contains(table))
{
return;
}
Table layerTable = table.GetTable();
if (layerTable != null)
{
SubscribeToAnyDataSourceChange(layerTable);
SubscribedTables.Add(table);
}
}
private void SubscribeToAnyDataSourceChange(Table layerTable)
{
RowCreatedEvent.Subscribe(
(args) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
layerTable
);
RowChangedEvent.Subscribe(
(args) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
layerTable
);
RowDeletedEvent.Subscribe(
(args) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
layerTable
);
}
private async Task OnRowChanged(RowChangedEventArgs args)
{
if (args == null || MapView.Active == null)
{
return;
}
// get the path of the edited dataset
Uri datasetPath = args.Row.GetTable().GetPath();
foreach (Layer layer in MapView.Active.Map.Layers)
{
try
{
if (layer.GetPath() == datasetPath)
{
ChangedObjectIds[layer.URI] = 1;
}
}
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
{
// ignore layers with invalid source URI
}
}
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
{
try
{
if (table.GetPath() == datasetPath)
{
ChangedObjectIds[table.URI] = 1;
}
}
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
{
// ignore layers with invalid source URI
}
}
await RunExpirationChecks(false);
}
private async Task GetIdsForLayersRemovedEvent(LayerEventsArgs args)
{
foreach (Layer layer in args.Layers)
{
ChangedObjectIds[layer.URI] = 1;
}
await RunExpirationChecks(true);
}
private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
{
foreach (StandaloneTable table in args.Tables)
{
ChangedObjectIds[table.URI] = 1;
}
await RunExpirationChecks(true);
}
private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
{
foreach (Map map in args.Maps)
{
List<MapMember> allMapMembers = _mapMemberUtils.GetAllMapMembers(map);
foreach (MapMember member in allMapMembers)
{
ChangedObjectIds[member.URI] = 1;
}
}
await RunExpirationChecks(false);
}
private void GetIdsForLayersAddedEvent(LayerEventsArgs args)
{
foreach (Layer layer in args.Layers)
{
if (layer is FeatureLayer featureLayer)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
}
}
}
private void GetIdsForStandaloneTablesAddedEvent(StandaloneTableEventArgs args)
{
foreach (StandaloneTable table in args.Tables)
{
SubscribeToTableDataSourceChange(table);
}
}
private async Task GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
{
// don't subscribe to all events (e.g. expanding group, changing visibility etc.)
bool validEvent = false;
foreach (var hint in args.EventHints)
{
if (
hint == MapMemberEventHint.DataSource
|| hint == MapMemberEventHint.DefinitionQuery
|| hint == MapMemberEventHint.LabelClasses
|| hint == MapMemberEventHint.LabelVisibility
|| hint == MapMemberEventHint.Name
|| hint == MapMemberEventHint.Renderer
|| hint == MapMemberEventHint.SceneLayerType
|| hint == MapMemberEventHint.URL
)
{
validEvent = true;
break;
}
}
if (validEvent)
{
foreach (MapMember member in args.MapMembers)
{
ChangedObjectIds[member.URI] = 1;
}
await RunExpirationChecks(false);
}
}
public List<ISendFilter> GetSendFilters() => _sendFilters;
public List<ICardSetting> GetSendSettings() => [];
[SuppressMessage(
"Maintainability",
"CA1506:Avoid excessive class coupling",
Justification = "Being refactored on in parallel, muting this issue so CI can pass initially."
)]
public async Task Send(string modelCardId)
{
//poc: dupe code between connectors
try
{
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No publish model card was found.");
}
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var scope = _serviceProvider.CreateScope();
List<MapMember> mapMembers = await QueuedTask.Run(() =>
{
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
return modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
.Where(obj => obj != null)
.ToList();
});
if (mapMembers.Count == 0)
{
// Handle as CARD ERROR in this function
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
await QueuedTask.Run(() =>
{
// subscribe to the selected layer events
foreach (MapMember mapMember in mapMembers)
{
if (mapMember is FeatureLayer featureLayer)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
}
else if (mapMember is StandaloneTable table)
{
SubscribeToTableDataSourceChange(table);
}
}
});
var sendResult = await scope
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
.Execute(
mapMembers,
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
}
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
/// <summary>
/// Checks if any sender model cards contain any of the changed objects. If so, also updates the changed objects hashset for each model card - this last part is important for on send change detection.
/// </summary>
private async Task RunExpirationChecks(bool idsDeleted)
{
var senders = _store.GetSenders();
List<string> expiredSenderIds = new();
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
_sendConversionCache.EvictObjects(objectIdsList);
foreach (SenderModelCard sender in senders)
{
var objIds = sender.SendFilter.NotNull().RefreshObjectIds();
var intersection = objIds.Intersect(objectIdsList).ToList();
bool isExpired = intersection.Count != 0;
if (isExpired)
{
expiredSenderIds.Add(sender.ModelCardId.NotNull());
// Update the model card object Ids
if (idsDeleted && sender.SendFilter is ArcGISSelectionFilter filter)
{
List<string> remainingObjIds = objIds.SkipWhile(x => intersection.Contains(x)).ToList();
filter.SelectedObjectIds = remainingObjIds;
}
}
}
await Commands.SetModelsExpired(expiredSenderIds);
ChangedObjectIds = new();
}
}
@@ -1,216 +0,0 @@
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using ArcProject = ArcGIS.Desktop.Core.Project;
namespace Speckle.Connectors.ArcGIS.Bindings;
//poc: dupe code between connectors
public class BasicConnectorBinding : IBasicConnectorBinding
{
public string Name => "baseBinding";
public IBrowserBridge Parent { get; }
public BasicConnectorBindingCommands Commands { get; }
private readonly DocumentModelStore _store;
private readonly ISpeckleApplication _speckleApplication;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public BasicConnectorBinding(
DocumentModelStore store,
IBrowserBridge parent,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_store = store;
_speckleApplication = speckleApplication;
_topLevelExceptionHandler = topLevelExceptionHandler;
Parent = parent;
Commands = new BasicConnectorBindingCommands(parent);
_store.DocumentChanged += (_, _) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await Commands.NotifyDocumentChanged();
});
}
public string GetSourceApplicationName() => _speckleApplication.Slug;
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
public DocumentInfo? GetDocumentInfo()
{
if (MapView.Active is null)
{
return null;
}
return new DocumentInfo(ArcProject.Current.URI, MapView.Active.Map.Name, MapView.Active.Map.URI);
}
public DocumentModelStore GetDocumentState() => _store;
public void AddModel(ModelCard model) => _store.AddModel(model);
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
{
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
}
public async Task HighlightModel(string modelCardId)
{
var model = _store.GetModelById(modelCardId);
if (model is null)
{
return;
}
var objectIds = new List<ObjectID>();
if (model is SenderModelCard senderModelCard)
{
objectIds = senderModelCard.SendFilter.NotNull().RefreshObjectIds().Select(x => new ObjectID(x)).ToList();
}
if (model is ReceiverModelCard receiverModelCard)
{
objectIds = receiverModelCard.BakedObjectIds.NotNull().Select(x => new ObjectID(x)).ToList();
}
if (objectIds is null)
{
return;
}
await HighlightObjectsOnView(objectIds);
}
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
{
await QueuedTask.Run(() =>
{
MapView mapView = MapView.Active;
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
ClearSelectionInTOC();
ClearSelection();
SelectMapMembersInTOC(mapMembersFeatures);
SelectMapMembersAndFeatures(mapMembersFeatures);
mapView.ZoomToSelected();
});
}
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
{
// find the layer on the map (from the objectID) and add the featureID is available
List<MapMemberFeature> mapMembersFeatures = new();
foreach (ObjectID objectId in objectIds)
{
MapMember mapMember = mapView.Map.FindLayer(objectId.MappedLayerURI, true);
if (mapMember is null)
{
mapMember = mapView.Map.FindStandaloneTable(objectId.MappedLayerURI);
}
if (mapMember is not null)
{
MapMemberFeature mapMembersFeat = new(mapMember, objectId.FeatureId);
mapMembersFeatures.Add(mapMembersFeat);
}
}
return mapMembersFeatures;
}
private void ClearSelection()
{
List<Layer> mapMembers = MapView.Active.Map.GetLayersAsFlattenedList().ToList();
foreach (var member in mapMembers)
{
if (member is FeatureLayer featureLayer)
{
featureLayer.ClearSelection();
}
}
}
private void ClearSelectionInTOC()
{
MapView.Active.ClearTOCSelection();
}
private void SelectMapMembersAndFeatures(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
{
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
{
MapMember member = mapMemberFeat.MapMember;
if (member is FeatureLayer layer)
{
if (mapMemberFeat.FeatureId == null)
{
// select full layer if featureID not specified
layer.Select();
}
else
{
// query features by ID
var objectIDfield = layer.GetFeatureClass().GetDefinition().GetObjectIDField();
// FeatureID range starts from 0, but auto-assigned IDs in the layer start from 1
QueryFilter anotherQueryFilter = new() { WhereClause = $"{objectIDfield} = {mapMemberFeat.FeatureId + 1}" };
using (Selection onlyOneSelection = layer.Select(anotherQueryFilter, SelectionCombinationMethod.New)) { }
}
}
}
}
private void SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
{
List<Layer> layers = new();
List<StandaloneTable> tables = new();
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
{
MapMember member = mapMemberFeat.MapMember;
if (member is Layer layer)
{
if (member is not GroupLayer) // group layer selection clears other layers selection
{
layers.Add(layer);
}
else
{
layer.SetExpanded(true);
}
}
else if (member is StandaloneTable table)
{
tables.Add(table);
}
}
MapView.Active.SelectLayers(layers);
// this step clears previous selection, not clear how to ADD selection instead
// this is why, activating it only if no layers are selected
if (layers.Count == 0)
{
MapView.Active.SelectStandaloneTables(tables);
}
}
}
@@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2022 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ArcGIS defaultAssembly="Speckle.Connectors.ArcGIS3.dll" defaultNamespace="Speckle.Connectors.ArcGIS" xmlns="http://schemas.esri.com/DADF/Registry" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.esri.com/DADF/Registry file:///C:/Program%20Files/ArcGIS/Pro/bin/ArcGIS.Desktop.Framework.xsd">
<AddInInfo id="{6CB1D25C-B8BF-4A33-9099-C1F8D1B32EFC}" version="1.0" desktopVersion="3.0.34047">
<Name>Speckle</Name>
<Description>Next Gen Speckle Connector (Beta) for ArcGIS</Description>
<Image>Images\AddinDesktop32.png</Image>
<Author>Speckle Systems</Author>
<Company>Speckle Systems</Company>
<Date>8/5/2021 12:24:21 PM</Date>
<Subject>Framework</Subject>
<!-- Note subject can be one or more of these topics:
Content, Framework, Editing, Geodatabase, Geometry, Geoprocessing, Layouts, Map Authoring, Map Exploration -->
</AddInInfo>
<modules>
<insertModule id="ConnectorArcGIS_Module" className="SpeckleModule" autoLoad="false" caption="SpeckleModule">
<!-- uncomment to have the control hosted on a separate tab-->
<tabs>
<tab id="Speckle_Tab1" caption="Speckle">
<group refID="Speckle_Group1"/>
</tab>
</tabs>
<groups>
<!-- comment this out if you have no controls on the Addin tab to avoid
an empty group. change appearsOnAddinTab to "True" if control is to be in the addin tab-->
<group id="Speckle_Group1" caption="Speckle" appearsOnAddInTab="false" keytip="G1">
<!-- host controls within groups -->
<button refID="SpeckleDUI3_SpeckleDUI3OpenButton" size="large" />
</group>
</groups>
<controls>
<!-- add your controls here -->
<button id="SpeckleDUI3_SpeckleDUI3OpenButton" caption="Speckle (Beta)"
className="SpeckleDUI3OpenButton" loadOnClick="true"
keytip="B1"
smallImage="Images/s2logo_16.png"
largeImage="Images/s2logo_32.png">
<tooltip heading="Speckle Connector for ArcGIS">
<disabledText />
</tooltip>
</button>
</controls>
<dockPanes>
<dockPane id="SpeckleDUI3_SpeckleDUI3" caption="Speckle (Beta)" className="SpeckleDUI3ViewModel" keytip="DockPane" initiallyVisible="true" dock="group" dockWith="esri_core_projectDockPane">
<content className="SpeckleDUI3Wrapper" />
</dockPane>
</dockPanes>
</insertModule>
</modules>
</ArcGIS>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

@@ -1,66 +0,0 @@
using ArcGIS.Desktop.Mapping;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.ArcGIS.Bindings;
using Speckle.Connectors.ArcGIS.Filters;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.Operations.Receive;
using Speckle.Connectors.ArcGis.Operations.Send;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.WebView;
using Speckle.Converters.Common;
using Speckle.Sdk.Models.GraphTraversal;
// POC: This is a temp reference to root object senders to tweak CI failing after having generic interfaces into common project.
// This should go whenever it is aligned.
namespace Speckle.Connectors.ArcGIS.DependencyInjection;
public static class ArcGISConnectorModule
{
public static void AddArcGIS(this IServiceCollection serviceCollection)
{
serviceCollection.AddConnectors();
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
serviceCollection.AddDUIView();
// Register bindings
serviceCollection.AddSingleton<IBinding, TestBinding>();
serviceCollection.AddSingleton<IBinding, ConfigBinding>();
serviceCollection.AddSingleton<IBinding, AccountBinding>();
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBinding>();
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());
// register send operation and dependencies
serviceCollection.AddSingleton<IBinding, ArcGISSendBinding>();
serviceCollection.AddScoped<SendOperation<MapMember>>();
serviceCollection.AddSingleton<IBinding, ArcGISSelectionBinding>();
serviceCollection.AddTransient<ISendFilter, ArcGISSelectionFilter>();
serviceCollection.AddScoped<ArcGISRootObjectBuilder>();
serviceCollection.AddScoped<IRootObjectBuilder<MapMember>, ArcGISRootObjectBuilder>();
serviceCollection.AddScoped<ArcGISLayerUnpacker>();
serviceCollection.AddScoped<ArcGISColorUnpacker>();
// register send conversion cache
serviceCollection.AddSingleton<ISendConversionCache, SendConversionCache>();
// register receive operation and dependencies
// serviceCollection.AddSingleton<IBinding, ArcGISReceiveBinding>(); // POC: disabled until receive code is refactored
serviceCollection.AddScoped<LocalToGlobalConverterUtils>();
serviceCollection.AddScoped<ArcGISColorManager>();
serviceCollection.AddScoped<IHostObjectBuilder, ArcGISHostObjectBuilder>();
serviceCollection.AddScoped<MapMembersUtils>();
// operation progress manager
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
}
}
@@ -1,356 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project>
<!-- Code to zip up the files-->
<UsingTask TaskName="PackageAddIn" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<ZipIntermediatePath ParameterType="System.String" Required="true" />
<PackageType ParameterType="System.String" Required="true" />
<TargetFolder ParameterType="System.String" Required="true" />
<TargetFileName ParameterType="System.String" Required="true" />
<RootNamespace ParameterType="System.String" Required="true" />
<PackageOutputPath ParameterType="System.String" Output="true"/>
</ParameterGroup>
<Task>
<!-- <Reference Include="System.IO.Compression.FileSystem"/>-->
<!-- <Reference Include="System.Xml.Linq"/>-->
<!-- <Reference Include="System.Xml"/>-->
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Xml.Linq"/>
<Using Namespace="System.Linq"/>
<Using Namespace="System.IO.Compression"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
Success = false;
string ConfigNotFound = "{0} was not found. File must be present in the root of the project and its build action set to AddInContent.";
string ZipIntermediatePathNotFound = "{0} was not found.";
string DefaultAssemblyDoesNotMatch = "Your value of '{0}' for the '{1}' attribute in the {2} does not match the assembly name '{3}' set for your project.";
string DefaultNSDoesNotMatch = "Your value of '{0}' for the '{1}' attribute in the {2} does not match the default namespace '{3}' set for your project.";
//Create the name of the Config File and extension
string extension = "";
string config = "";
string attrib_asm = "";
string attrib_ns = "";
var assemblyValMissing = "";
var nsValMissing = "";
if (PackageType.ToLower() == "plugin")
{
Log.LogMessage(MessageImportance.Low, "This is an plugin");
config = "Config.xml";
extension = ".esriPlugin";
attrib_asm = "library";
attrib_ns = "namespace";
assemblyValMissing = "AddIn element 'library' attribute not found";
nsValMissing = "AddIn element 'namespace' attribute not found";
}
else if (PackageType.ToLower() == "configuration")
{
Log.LogMessage(MessageImportance.Low, "This is an configuration");
config = "Config.daml";
extension = ".proConfigX";
attrib_asm = "defaultAssembly";
attrib_ns = "defaultNamespace";
assemblyValMissing = "ArcGIS element 'defaultAssembly' attribute not found";
nsValMissing = "ArcGIS element 'defaultNamespace' attribute not found";
}
else
{
Log.LogMessage(MessageImportance.Low, "This is an addin");
config = "Config.daml";
bool proSDKProject = File.Exists(Path.Combine(ZipIntermediatePath, config));
if (!proSDKProject) //This might be a class library that uses the Pro references only
return true;
extension = ".esriAddinX";
attrib_asm = "defaultAssembly";
attrib_ns = "defaultNamespace";
assemblyValMissing = "ArcGIS element 'defaultAssembly' attribute not found";
nsValMissing = "ArcGIS element 'defaultNamespace' attribute not found";
}
// Check if Config.daml exists in ZipFolder
ZipIntermediatePath = Path.GetFullPath(ZipIntermediatePath);
if (!Directory.Exists(ZipIntermediatePath))
{
Log.LogError(ZipIntermediatePathNotFound, ZipIntermediatePath);
return false;
}
var addInXML = Path.Combine(ZipIntermediatePath, config);
Log.LogMessage(MessageImportance.Low, "addInXML: " + addInXML);
Log.LogMessage(MessageImportance.High, "PackageType: " + PackageType);
if (!File.Exists(addInXML))
{
Log.LogError(ConfigNotFound, config);
return false;
}
//Verfiy that an assembly with the name defined in the Config.daml
//matches the default assembly set in the project. Ditto for the
//namespace
string DefaultAssembly = "";
string DefaultNamespace = "";
XDocument xdoc = XDocument.Load(addInXML);
XNamespace DefaultNS = "http://schemas.esri.com/DADF/Registry";
if (PackageType.ToLower() == "plugin")
{
var addin = xdoc.Root.Element(DefaultNS + "AddIn");
if (addin != null)
{
var val = addin.Attribute("library");
if (val != null)
DefaultAssembly = val.Value;
val = addin.Attribute("namespace");
if (val != null)
DefaultNamespace = val.Value;
}
}
else
{
var val = xdoc.Root.Attribute("defaultAssembly");
if (val != null)
DefaultAssembly = val.Value;
val = xdoc.Root.Attribute("defaultNamespace");
if (val != null)
DefaultNamespace = val.Value;
}
if (string.IsNullOrEmpty(DefaultAssembly))
{
Log.LogError(assemblyValMissing);
return false;
}
if (string.IsNullOrEmpty(DefaultNamespace))
{
Log.LogError(nsValMissing);
return false;
}
//check that the addin assembly and default assembly names match
if (DefaultAssembly.ToLower() != TargetFileName.ToLower())
{
Log.LogWarning(DefaultAssemblyDoesNotMatch, DefaultAssembly, attrib_asm, config, TargetFileName);
}
//Ditto for namespace
if (DefaultNamespace.ToLower() != RootNamespace.ToLower())
{
Log.LogWarning(DefaultNSDoesNotMatch, DefaultNamespace, attrib_ns, config, RootNamespace);
}
if (!Directory.Exists(TargetFolder))
{
Directory.CreateDirectory(TargetFolder);
}
string addInAssembly = System.IO.Path.GetFileNameWithoutExtension(DefaultAssembly);
string archiveName = addInAssembly + extension;
try
{
string file = Path.Combine(TargetFolder, archiveName);
if (File.Exists(file))
File.Delete(file);
System.IO.Compression.ZipFile.CreateFromDirectory(ZipIntermediatePath, file);
PackageOutputPath = Path.GetFullPath(file);
Success = true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
<!-- Code to find relative path-->
<UsingTask TaskName="ConvertToRelativePath" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<RelativeTo ParameterType="System.String" Required="true"/>
<Paths ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<RelativePaths ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true"/>
</ParameterGroup>
<Task>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Linq"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
var result = new List<ITaskItem>();
System.Uri relativeTo = new Uri(this.RelativeTo);
foreach (var i in Paths) {
try {
System.Uri itemFullPath = new Uri(i.GetMetadata("FullPath"));
var relativeUri = relativeTo.MakeRelativeUri(itemFullPath);
result.Add(new TaskItem(Uri.UnescapeDataString(relativeUri.ToString())));
}
catch {
return false;
}
}
RelativePaths = result.ToArray();
foreach (var i in RelativePaths)
{
Log.LogMessage(MessageImportance.Low, "RelativePaths: " + i.ToString());
}
Success = true;
]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="CleanAddIn" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<ProjectDir ParameterType="System.String" Required="true"/>
<AssemblyName ParameterType="System.String" Required="true"/>
<PackageType ParameterType="System.String" Required="true"/>
<!--<ArcGISFolder ParameterType="System.String" Output="true" /> -->
<CleanInfo ParameterType="System.String" Output="true"/>
</ParameterGroup>
<Task>
<!-- <Reference Include="System.Xml.Linq"/>-->
<!-- <Reference Include="System.Xml"/>-->
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Xml.Linq"/>
<Using Namespace="System.Linq"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
Success = false;
string ConfigNotFound = "{0} was not found. File must be present in the root of the project and its build action set to AddInContent.";
//Create the name of the Config File and extension
string extension = "";
string config = "";
if (PackageType.ToLower() == "plugin")
{
config = "Config.xml";
extension = ".esriPlugin";
}
else if (PackageType.ToLower() == "configuration")
{
config = "Config.daml";
extension = ".proConfigX";
}
else
{
config = "Config.daml";
bool proSDKProject = File.Exists(Path.Combine(ProjectDir, config));
if (!proSDKProject) //This might be a class library that uses the Pro references only
return true;
extension = ".esriAddinX";
}
var addInXML = Path.Combine(ProjectDir, config);
if (!File.Exists(addInXML))
{
Log.LogError(ConfigNotFound, config);
return false;
}
//Get the add-in id
XDocument xdoc = XDocument.Load(addInXML);
XNamespace DefaultNS = "http://schemas.esri.com/DADF/Registry";
if (PackageType.ToLower() == "plugin")
{
Log.LogMessage("process plugin");
var addInID = xdoc.Root.Element(DefaultNS + "AddInID");
CleanInfo = addInID.Value;//let it error if it's missing
}
else if (PackageType.ToLower() == "addin")
{
Log.LogMessage("process addin");
var addinInfo = xdoc.Root.Element(DefaultNS + "AddInInfo");
CleanInfo = addinInfo.Attribute("id").Value;//let it error if it's missing
}
else
{
Log.LogMessage("process configuration");
CleanInfo = AssemblyName + extension;
}
Success = true;
]]>
</Code>
</Task>
</UsingTask>
<!-- Define additional BuildAction option -->
<!-- Set up default zip properties -->
<PropertyGroup>
<PackageType Condition="'$(PackageType)' == ''">Addin</PackageType>
</PropertyGroup>
<PropertyGroup>
<ArcGISFolder>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\ESRI\ArcGISPro', 'InstallDir', null, RegistryView.Registry64))\bin</ArcGISFolder>
<ArcGISFolder Condition="'$(ArcGISFolder)' == ''">$(registry:HKEY_CURRENT_USER\SOFTWARE\ESRI\ArcGISPro@InstallDir)\bin</ArcGISFolder>
<ArcGISFolder Condition="'$(ArcGISFolder)' == '' Or !Exists('$(ArcGISFolder)\RegisterAddIn.exe')">$(ProgramData)\EsriProCommon\</ArcGISFolder>
</PropertyGroup>
<Target Name="ArcGISInstallOutput" AfterTargets="Build">
<Message Text="IntermediateOutputPath Name: $(IntermediateOutputPath)..." Importance="High"/>
<Message Text="CleanFile Name: $(CleanFile)..." Importance="High"/>
<Message Text="ProjectDir Name: $(ProjectDir)..." Importance="High"/>
<Message Text="AssemblyName Name: $(AssemblyName)..." Importance="High"/>
<Message Text="TargetFileName Name: $(TargetFileName)..." Importance="High"/>
<Message Text="RootNamespace: $(RootNamespace)..." Importance="High"/>
<Message Text="TargetFolder Name: $(OutDir)..." Importance="High"/>
<Message Text="PackageType Name: $(PackageType)..." Importance="High"/>
<Message Text="Install dir: $(ArcGISFolder)" Importance="High"/>
<!-- Get a list of project outputs from the cache file and FileWritesXXX item,
excluding those in intermediate output directory -->
<!-- Note clean file may miss listing CopyLocal reference -->
<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
<Output TaskParameter="Lines" ItemName="CacheOutputFiles" />
</ReadLinesFromFile>
<FindUnderPath Files="@(CacheOutputFiles)" Path="$(OutDir)">
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
</FindUnderPath>
<FindUnderPath Files="@(FileWrites->'%(FullPath)')" Path="$(OutDir)">
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
</FindUnderPath>
<FindUnderPath Files="@(FileWritesShareable->'%(FullPath)')" Path="$(OutDir)">
<Output TaskParameter="InPath" ItemName="PackageOutputFiles" />
</FindUnderPath>
<RemoveDuplicates Inputs="@(PackageOutputFiles)">
<Output TaskParameter="Filtered" ItemName="FilteredPackageOutputFiles" />
</RemoveDuplicates>
<ConvertToRelativePath Paths="@(FilteredPackageOutputFiles)" RelativeTo="$(TargetDir)">
<Output TaskParameter="RelativePaths" ItemName="ConfigBinaries" />
</ConvertToRelativePath>
<Message Text="ConvertToRelativePath Task, TargetDir: $(TargetDir) " Importance="High"/>
</Target>
<Target Name="PackageArcGISContents" AfterTargets="ArcGISInstallOutput">
<Message Text="Running PackageArcGISContents..." Importance="High"/>
<RemoveDir Condition="Exists('$(ZipIntermediatePath)')" Directories="$(ZipIntermediatePath)" />
<Message Text="ZipIntermediatePath: $(ZipIntermediatePath)Install..." Importance="High"/>
<!-- Copy project output files, preserving folder structure -->
<Copy SourceFiles="@(ConfigBinaries->'$(OutDir)%(Identity)')" ContinueOnError="true" DestinationFolder="$(IntermediateOutputPath)temp_archive\Install\%(RelativeDir)" />
<!-- Copy items marked with Content as BuildAction, preserving folder structure & handling linked items -->
<!-- Only include items that have CopyToOutputDirectory as Never -->
<Copy SourceFiles="@(Content)" Condition="'%(Content.Link)' == '' And ('%(Content.CopyToOutputDirectory)' == 'Never' Or '%(Content.CopyToOutputDirectory)' == '')" DestinationFolder="$(IntermediateOutputPath)temp_archive\%(RelativeDir)" ContinueOnError="true" />
<Copy SourceFiles="@(Content)" Condition="'%(Content.Link)' != '' And ('%(Content.CopyToOutputDirectory)' == 'Never' Or '%(Content.CopyToOutputDirectory)' == '')" DestinationFiles="$(IntermediateOutputPath)temp_archive\%(Content.Link)" ContinueOnError="true"/>
<!-- Zipping up add-in resources -->
<PackageAddIn ZipIntermediatePath="$(IntermediateOutputPath)temp_archive\"
PackageType="$(PackageType)"
TargetFolder="$(OutDir)"
TargetFileName="$(TargetFileName)"
RootNamespace="$(RootNamespace)">
<Output TaskParameter="PackageOutputPath" PropertyName="PackageFile" />
</PackageAddIn>
<!-- Shell out to RegisterAddIn.exe to install the package -->
<Message Text="Deploying $(PackageType)..." Importance="High"/>
<Message Text="ArcGISFolder Name: $(ArcGISFolder)..." Importance="High"/>
<Message Text="Unable to execute RegisterAddIn.exe. ArcGIS Pro is not installed." Importance="High" Condition="!Exists('$(ArcGISFolder)')"/>
<Message Text="Execute RegisterAddIn.exe &quot;$(PackageFile)&quot; /s..." Importance="High" Condition="Exists('$(ArcGISFolder)')"/>
<Exec IgnoreExitCode="true" WorkingDirectory="$(ArcGISFolder)" Command="RegisterAddIn.exe &quot;$(PackageFile)&quot; /s" Condition="Exists('$(ArcGISFolder)') AND $(PackageFile) != '' ">
<Output TaskParameter="ExitCode" PropertyName="ESRIRegAddinExitCode" />
</Exec>
<RemoveDir Condition="Exists('$(ZipIntermediatePath)')" Directories="$(ZipIntermediatePath)" />
</Target>
<Target Name="CleanArcGISContents" AfterTargets="Clean">
<CleanAddIn ProjectDir="$(ProjectDir)"
AssemblyName="$(AssemblyName)"
PackageType="$(PackageType)">
<Output TaskParameter="CleanInfo" PropertyName="CleanInfo" />
</CleanAddIn>
<Message Text="Clean $(PackageType).$(ArcGISFolder).." Importance="High"/>
<Message Text="Execute RegisterAddIn.exe &quot;$(CleanInfo)&quot; /u..." Importance="High" Condition="Exists('$(ArcGISFolder)')"/>
<Message Text="Unable to execute RegisterAddIn.exe. ArcGIS Pro is not installed." Importance="High" Condition="!Exists('$(ArcGISFolder)')"/>
<Exec IgnoreExitCode="true" WorkingDirectory="$(ArcGISFolder)" Command="RegisterAddIn.exe &quot;$(CleanInfo)&quot; /u /s" Condition="Exists('$(ArcGISFolder)') AND $(CleanInfo) != ''">
<Output TaskParameter="ExitCode" PropertyName="ESRIRegAddinExitCode" />
</Exec>
</Target>
</Project>
@@ -1,13 +0,0 @@
using Speckle.Connectors.DUI.Models.Card.SendFilter;
namespace Speckle.Connectors.ArcGIS.Filters;
public class ArcGISSelectionFilter : DirectSelectionSendFilter
{
public ArcGISSelectionFilter()
{
IsDefault = true;
}
public override List<string> RefreshObjectIds() => SelectedObjectIds;
}
@@ -1,3 +0,0 @@
global using AC = ArcGIS.Core;
global using ACD = ArcGIS.Core.Data;
global using ADM = ArcGIS.Desktop.Mapping;
@@ -1,265 +0,0 @@
using System.Drawing;
using ArcGIS.Core.CIM;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.ArcGIS3.Utils;
using Speckle.Objects;
using Speckle.Objects.Other;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Extensions;
using Speckle.Sdk.Models.GraphTraversal;
using Speckle.Sdk.Models.Proxies;
namespace Speckle.Connectors.ArcGIS.HostApp;
/// <summary>
/// TODO: definitely need to refactor this, probably will collect colors during layer iteration in the root object builder.
/// </summary>
public class ArcGISColorManager
{
public Dictionary<string, Color> ObjectColorsIdMap { get; set; } = new();
public Dictionary<string, Color> ObjectMaterialsIdMap { get; set; } = new();
/// <summary>
/// Parse Color Proxies and stores in ObjectColorsIdMap the relationship between object ids and colors
/// </summary>
/// <param name="colorProxies"></param>
/// <param name="onOperationProgressed"></param>
public void ParseColors(List<ColorProxy> colorProxies, IProgress<CardProgress> onOperationProgressed)
{
// injected as Singleton, so we need to clean existing proxies first
ObjectColorsIdMap = new();
var count = 0;
foreach (ColorProxy colorProxy in colorProxies)
{
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
foreach (string objectId in colorProxy.objects)
{
Color convertedColor = Color.FromArgb(colorProxy.value);
ObjectColorsIdMap.TryAdd(objectId, convertedColor);
}
}
}
/// <summary>
/// Parse Color renderMaterials and stores in ObjectMaterialsIdMap the relationship between object ids and colors
/// </summary>
/// <param name="materialProxies"></param>
/// <param name="onOperationProgressed"></param>
public void ParseMaterials(List<RenderMaterialProxy> materialProxies, IProgress<CardProgress> onOperationProgressed)
{
// injected as Singleton, so we need to clean existing proxies first
ObjectMaterialsIdMap = new();
var count = 0;
foreach (RenderMaterialProxy colorProxy in materialProxies)
{
onOperationProgressed.Report(new("Converting materials", (double)++count / materialProxies.Count));
foreach (string objectId in colorProxy.objects)
{
Color convertedColor = Color.FromArgb(colorProxy.value.diffuse);
ObjectMaterialsIdMap.TryAdd(objectId, convertedColor);
}
}
}
public int CIMColorToInt(CIMColor color)
{
return (255 << 24)
| ((int)Math.Round(color.Values[0]) << 16)
| ((int)Math.Round(color.Values[1]) << 8)
| (int)Math.Round(color.Values[2]);
}
/// <summary>
/// Create a new CIMUniqueValueClass for UniqueRenderer per each object ID
/// </summary>
/// <param name="tc"></param>
/// <param name="speckleGeometryType"></param>
private CIMUniqueValueClass CreateColorCategory(
TraversalContext tc,
esriGeometryType speckleGeometryType,
string uniqueLabel
)
{
// declare default white color
Color color = Color.FromArgb(255, 255, 255, 255);
bool colorFound = false;
// get color moving upwards from the object
foreach (var parent in tc.GetAscendants())
{
if (parent.applicationId is string appId)
{
if (ObjectMaterialsIdMap.TryGetValue(appId, out Color objColorMaterial))
{
color = objColorMaterial;
colorFound = true;
break;
}
if (ObjectColorsIdMap.TryGetValue(appId, out Color objColor))
{
color = objColor;
colorFound = true;
break;
}
}
}
// handling Revit case, where child objects have separate colors/materials
if (!colorFound && tc.Current is IDataObject)
{
var displayable = tc.Current.TryGetDisplayValue();
if (displayable != null)
{
foreach (var childObj in displayable)
{
if (childObj.applicationId is string appId)
{
if (ObjectMaterialsIdMap.TryGetValue(appId, out Color objColorMaterial))
{
color = objColorMaterial;
break;
}
if (ObjectColorsIdMap.TryGetValue(appId, out Color objColor))
{
color = objColor;
break;
}
}
}
}
}
CIMSymbolReference symbol = CreateSymbol(speckleGeometryType, color);
// First create a "CIMUniqueValueClass"
List<CIMUniqueValue> listUniqueValues = new() { new CIMUniqueValue { FieldValues = new string[] { uniqueLabel } } };
CIMUniqueValueClass newUniqueValueClass =
new()
{
Editable = true,
Label = uniqueLabel,
Patch = PatchShape.Default,
Symbol = symbol,
Visible = true,
Values = listUniqueValues.ToArray()
};
return newUniqueValueClass;
}
/// <summary>
/// Create a Symbol from GeometryType and Color
/// </summary>
/// <param name="speckleGeometryType"></param>
/// <param name="color"></param>
private CIMSymbolReference CreateSymbol(esriGeometryType speckleGeometryType, Color color)
{
var symbol = SymbolFactory
.Instance.ConstructPointSymbol(ColorFactory.Instance.CreateColor(color))
.MakeSymbolReference();
switch (speckleGeometryType)
{
case esriGeometryType.esriGeometryLine:
case esriGeometryType.esriGeometryPolyline:
symbol = SymbolFactory
.Instance.ConstructLineSymbol(ColorFactory.Instance.CreateColor(color))
.MakeSymbolReference();
break;
case esriGeometryType.esriGeometryPolygon:
case esriGeometryType.esriGeometryMultiPatch:
symbol = SymbolFactory
.Instance.ConstructPolygonSymbol(ColorFactory.Instance.CreateColor(color))
.MakeSymbolReference();
break;
}
return symbol;
}
/// <summary>
/// Add CIMUniqueValueClass to Layer Renderer (if exists); apply Renderer to Layer (again)
/// </summary>
/// <param name="tc"></param>
/// <param name="trackerItem"></param>
public CIMUniqueValueRenderer? CreateOrEditLayerRenderer(
TraversalContext tc,
ObjectConversionTracker trackerItem,
CIMRenderer? existingRenderer
)
{
if (trackerItem.HostAppMapMember is not FeatureLayer fLayer)
{
// do nothing with non-feature layers
return null;
}
// declare default grey color, create default symbol for the given layer geometry type
var color = Color.FromArgb(CIMColorToInt(ColorFactory.Instance.GreyRGB));
CIMSymbolReference defaultSymbol = CreateSymbol(fLayer.ShapeType, color);
// get existing renderer classes
List<CIMUniqueValueClass> listUniqueValueClasses = new() { };
if (existingRenderer is CIMUniqueValueRenderer uniqueRenderer)
{
if (uniqueRenderer.Groups[0].Classes != null)
{
listUniqueValueClasses.AddRange(uniqueRenderer.Groups[0].Classes.ToList());
}
}
// Add new CIMUniqueValueClass (or multiple, if it's a Collection with elements, e.g. VectorLayer)
List<TraversalContext> traversalContexts = new();
if (tc.Current is Collection collection)
{
foreach (var element in collection.elements)
{
TraversalContext newTc = new(element, "elements", tc);
traversalContexts.Add(newTc);
}
}
else
{
traversalContexts.Add(tc);
}
foreach (var tContext in traversalContexts)
{
// get unique label
string? uniqueLabel = tContext.Current?.id;
// remove any GIS-specific classes for now
/*
if (tContext.Current is IGisFeature gisFeat)
{
var existingLabel = gisFeat.attributes["Speckle_ID"];
if (existingLabel is string stringLabel)
{
uniqueLabel = stringLabel;
}
}*/
if (uniqueLabel is not null && !listUniqueValueClasses.Select(x => x.Label).Contains(uniqueLabel))
{
CIMUniqueValueClass newUniqueValueClass = CreateColorCategory(tContext, fLayer.ShapeType, uniqueLabel);
listUniqueValueClasses.Add(newUniqueValueClass);
}
}
// Create a list of CIMUniqueValueGroup
CIMUniqueValueGroup uvg = new() { Classes = listUniqueValueClasses.ToArray(), Heading = "Speckle_ID" };
List<CIMUniqueValueGroup> listUniqueValueGroups = new() { uvg };
// Create the CIMUniqueValueRenderer
CIMUniqueValueRenderer uvr =
new()
{
UseDefaultSymbol = true,
DefaultLabel = "all other values",
DefaultSymbol = defaultSymbol,
Groups = listUniqueValueGroups.ToArray(),
Fields = new string[] { "Speckle_ID" }
};
return uvr;
}
}
@@ -1,461 +0,0 @@
using ArcGIS.Desktop.Mapping;
using Speckle.Sdk.Models.Proxies;
namespace Speckle.Connectors.ArcGIS.HostApp;
public class ArcGISColorUnpacker
{
/// <summary>
/// Cache of all color proxies for converted features. Key is the Color proxy argb value.
/// </summary>
public Dictionary<int, ColorProxy> ColorProxyCache { get; } = new();
/// <summary>
/// Stores the current renderer (determined by mapMember)
/// </summary>
private AC.CIM.CIMRenderer? StoredRenderer { get; set; }
/// <summary>
/// Stores the current renderer (determined by tin mapmember)
/// </summary>
private AC.CIM.CIMTinRenderer? StoredTinRenderer { get; set; }
/// <summary>
/// Stores the used renderer fields from the layer
/// </summary>
private List<string> StoredRendererFields { get; set; }
/// <summary>
/// Stores an already processed color for current mapMember, to dbe used by all mapMember objects. Only applies to simple type renderers
/// </summary>
private int? StoredColor { get; set; }
/// <summary>
/// Stores a feature layer renderer to be used by <see cref="ProcessFeatureLayerColor"/> in <see cref="StoredRenderer"/>, any fields used by the renderer from the layer, and resets the <see cref="StoredColor"/> and <see cref="StoredRendererFields"/>
/// </summary>
/// <param name="featureLayer"></param>
/// <exception cref="AC.CalledOnWrongThreadException">Must be called on MCT.</exception>
public void StoreRendererAndFields(ADM.FeatureLayer featureLayer)
{
// field names are unique, but often their alias is used instead by renderer headings
// so we are storing both names and alias in this dictionary for fast lookup
// POC: adding aliases are not optimal, because they do not need to be unique && they can be the same as the name of another field
Dictionary<string, string> layerFieldDictionary = new();
foreach (ADM.FieldDescription field in featureLayer.GetFieldDescriptions())
{
layerFieldDictionary.TryAdd(field.Name, field.Name);
layerFieldDictionary.TryAdd(field.Alias, field.Name);
}
// clear stored values
StoredRendererFields = new();
StoredColor = null;
StoredRenderer = null;
AC.CIM.CIMRenderer layerRenderer = featureLayer.GetRenderer();
List<string> fields = new();
bool isSupported = false;
switch (layerRenderer)
{
case AC.CIM.CIMSimpleRenderer:
isSupported = true;
break;
case AC.CIM.CIMUniqueValueRenderer uniqueValueRenderer:
isSupported = true;
fields = uniqueValueRenderer.Fields.ToList();
break;
case AC.CIM.CIMClassBreaksRenderer classBreaksRenderer:
isSupported = true;
fields.Add(classBreaksRenderer.Field);
break;
default:
// TODO: log error here that a renderer is unsupported
break;
}
if (isSupported)
{
StoredRenderer = layerRenderer;
foreach (string field in fields)
{
if (layerFieldDictionary.TryGetValue(field, out string? fieldName))
{
StoredRendererFields.Add(fieldName);
}
}
}
}
/// <summary>
/// Stores a las layer renderer to be used by <see cref="ProcessLasLayerColor"/> in <see cref="StoredTinRenderer"/>
/// </summary>
/// <param name="lasLayer"></param>
/// <exception cref="AC.CalledOnWrongThreadException">Must be called on MCT.</exception>
public void StoreRenderer(ADM.LasDatasetLayer lasLayer)
{
// clear stored values
StoredTinRenderer = null;
// POC: not sure why we are only using the first renderer here
AC.CIM.CIMTinRenderer layerRenderer = lasLayer.GetRenderers()[0];
bool isSupported = false;
switch (layerRenderer)
{
case AC.CIM.CIMTinUniqueValueRenderer:
isSupported = true;
break;
default:
// TODO: log error here that a renderer is unsupported
break;
}
if (isSupported)
{
StoredTinRenderer = layerRenderer;
}
}
/// <summary>
/// Processes a las layer's point color by the stored <see cref="StoredRenderer"/>, and stores the point's id and color proxy to the <see cref="ColorProxyCache"/>.
/// POC: logic probably can be combined with ProcessFeatureLayerColor.
/// </summary>
/// <param name="point"></param>
public void ProcessLasLayerColor(ACD.Analyst3D.LasPoint point, string pointApplicationId)
{
// get the color from the renderer and point
AC.CIM.CIMColor? color;
switch (StoredTinRenderer)
{
case AC.CIM.CIMTinUniqueValueRenderer uniqueValueRenderer:
color = GetPointColorByUniqueValueRenderer(uniqueValueRenderer, point);
break;
default:
return;
}
// get or create the color proxy for the point
int argb = CIMColorToInt(color ?? point.RGBColor);
AddObjectIdToColorProxyCache(pointApplicationId, argb);
}
// Retrieves the las point color from a unique value renderer
// unique renderers have groups of conditions that may affect the color of a feature
// resulting in a different color than the default renderer symbol color
private AC.CIM.CIMColor? GetPointColorByUniqueValueRenderer(
AC.CIM.CIMTinUniqueValueRenderer renderer,
ACD.Analyst3D.LasPoint point
)
{
foreach (AC.CIM.CIMUniqueValueGroup group in renderer.Groups)
{
foreach (AC.CIM.CIMUniqueValueClass groupClass in group.Classes)
{
foreach (AC.CIM.CIMUniqueValue value in groupClass.Values)
{
// all field values have to match the row values
for (int i = 0; i < value.FieldValues.Length; i++)
{
string groupValue = value.FieldValues[i].Replace("<Null>", "");
object? pointValue = point.ClassCode;
if (ValuesAreEqual(groupValue, pointValue))
{
return groupClass.Symbol.Symbol.GetColor();
}
}
}
}
}
return null;
}
/// <summary>
/// Processes a feature layer's row color by the stored <see cref="StoredRenderer"/>, and stores the row's id and color proxy to the <see cref="ColorProxyCache"/>.
/// </summary>
/// <param name="row"></param>
/// <returns></returns>
/// <exception cref="ACD.Exceptions.GeodatabaseException"></exception>
public void ProcessFeatureLayerColor(ACD.Row row, string rowApplicationId)
{
// if stored color is not null, this means the renderer was a simple renderer that applies to the entire layer, and was already created.
// just add the row application id to the color proxy.
if (StoredColor is int existingColorProxyId)
{
AddObjectIdToColorProxyCache(rowApplicationId, existingColorProxyId);
return;
}
// get the color from the renderer and row
AC.CIM.CIMColor? color = null;
switch (StoredRenderer)
{
// simple renderers do not rely on fields, so the color can be retrieved from the renderer directly
case AC.CIM.CIMSimpleRenderer simpleRenderer:
color = simpleRenderer.Symbol.Symbol.GetColor();
break;
case AC.CIM.CIMUniqueValueRenderer uniqueValueRenderer:
color = GetRowColorByUniqueValueRenderer(uniqueValueRenderer, row);
break;
case AC.CIM.CIMClassBreaksRenderer classBreaksRenderer:
color = GetRowColorByClassBreaksRenderer(classBreaksRenderer, row);
break;
}
if (color is null)
{
// TODO: log error or throw exception that color could not be retrieved
return;
}
// get or create the color proxy for the row
int argb = CIMColorToInt(color);
AddObjectIdToColorProxyCache(rowApplicationId, argb);
// store color if from simple renderer
if (StoredRenderer is AC.CIM.CIMSimpleRenderer)
{
StoredColor = argb;
}
}
// Retrieves the row color from a class breaks renderer
// unique renderers have groups of conditions that may affect the color of a feature
// resulting in a different color than the default renderer symbol color
private AC.CIM.CIMColor? GetRowColorByClassBreaksRenderer(AC.CIM.CIMClassBreaksRenderer renderer, ACD.Row row)
{
AC.CIM.CIMColor? color = null;
// get the default symbol color
if (renderer.DefaultSymbol?.Symbol.GetColor() is AC.CIM.CIMColor defaultColor)
{
color = defaultColor;
}
// get the first stored field, since this renderer should only have 1 field
double storedFieldValue = Convert.ToDouble(row[StoredRendererFields.First()]);
List<AC.CIM.CIMClassBreak> reversedBreaks = new(renderer.Breaks);
reversedBreaks.Reverse();
foreach (var rBreak in reversedBreaks)
{
// keep looping until the last matching condition
if (storedFieldValue <= rBreak.UpperBound)
{
if (rBreak.Symbol.Symbol.GetColor() is AC.CIM.CIMColor breakColor)
{
color = breakColor;
}
else
{
// TODO: log error here, could not retrieve break color from symbol
}
}
}
return color;
}
// Retrieves the row color from a unique value renderer
// unique renderers have groups of conditions that may affect the color of a feature
// resulting in a different color than the default renderer symbol color
private AC.CIM.CIMColor? GetRowColorByUniqueValueRenderer(AC.CIM.CIMUniqueValueRenderer renderer, ACD.Row row)
{
AC.CIM.CIMColor? color = null;
// get the default symbol color
if (renderer.DefaultSymbol?.Symbol.GetColor() is AC.CIM.CIMColor defaultColor)
{
color = defaultColor;
}
// note: usually there is only 1 group
foreach (AC.CIM.CIMUniqueValueGroup group in renderer.Groups)
{
// loop through all values in groups to see if any have met conditions that result in a different color
foreach (AC.CIM.CIMUniqueValueClass groupClass in group.Classes)
{
bool groupConditionsMet = true;
foreach (AC.CIM.CIMUniqueValue value in groupClass.Values)
{
// all field values have to match the row values
for (int i = 0; i < StoredRendererFields.Count; i++)
{
string groupValue = value.FieldValues[i];
object? rowValue = row[StoredRendererFields[i]];
if (!ValuesAreEqual(groupValue, rowValue))
{
groupConditionsMet = false;
break;
}
}
}
// set the group color to class symbol color if conditions are met
if (groupConditionsMet)
{
if (groupClass.Symbol.Symbol.GetColor() is AC.CIM.CIMColor groupColor)
{
color = groupColor;
}
else
{
// TODO: log error here, could not retrieve group color from symbol
}
}
}
}
return color;
}
/// <summary>
/// Compares the label string of a UniqueValueRenderer (groupValue), and an object value (row, las point), to determine if they are equal
/// </summary>
/// <param name="objectValue"></param>
/// <param name="groupValue"></param>
private bool ValuesAreEqual(string groupValue, object? objectValue)
{
switch (objectValue)
{
case int:
case short:
case long:
case byte:
string objectValueString = Convert.ToString(objectValue) ?? "";
return groupValue.Equals(objectValueString);
case string:
return groupValue.Equals(objectValue);
// POC: these are tricky to compare with the label strings accurately, so will trim both values to 5 decimal places.
case double d:
return double.TryParse(groupValue, out double groupDouble) && groupDouble - d < 0.000001;
case float f:
return float.TryParse(groupValue, out float groupFloat) && groupFloat - f < 0.000001;
default:
return false;
}
}
private void AddObjectIdToColorProxyCache(string objectId, int argb)
{
if (ColorProxyCache.TryGetValue(argb, out ColorProxy? colorProxy))
{
colorProxy.objects.Add(objectId);
}
else
{
ColorProxy newColorProxy =
new()
{
name = argb.ToString(),
objects = new() { objectId },
value = argb,
applicationId = argb.ToString()
};
ColorProxyCache.Add(argb, newColorProxy);
}
}
private int ArgbToInt(int a, int r, int g, int b)
{
return (a << 24) | (r << 16) | (g << 8) | b;
}
// Gets the argb int from a CIMColor
// Defaults to assuming CIMColor.Values represent the red, green, and blue channels.
private int CIMColorToInt(AC.CIM.CIMColor color)
{
switch (color)
{
case AC.CIM.CIMHSVColor hsv:
(float hsvR, float hsvG, float hsvB) = RgbFromHsv(hsv.H, hsv.S, hsv.V);
return ArgbToInt(
(int)Math.Round(hsv.Alpha),
(int)Math.Round(hsvR * 255),
(int)Math.Round(hsvG * 255),
(int)Math.Round(hsvB * 255)
);
case AC.CIM.CIMCMYKColor cmyk:
float k = cmyk.K;
int cmykR = Convert.ToInt32(255 * (1 - cmyk.C) * (1 - k));
int cmykG = Convert.ToInt32(255 * (1 - cmyk.M) * (1 - k));
int cmykB = Convert.ToInt32(255 * (1 - cmyk.Y) * (1 - k));
return ArgbToInt((int)Math.Round(cmyk.Alpha), cmykR, cmykG, cmykB);
default:
return ArgbToInt(
(int)Math.Round(color.Alpha),
(int)Math.Round(color.Values[0]),
(int)Math.Round(color.Values[1]),
(int)Math.Round(color.Values[2])
);
}
}
private (float, float, float) RgbFromHsv(float hue, float saturation, float value)
{
// Translates HSV color to RGB color
// H: 0.0 - 360.0, S: 0.0 - 100.0, V: 0.0 - 100.0
// R, G, B: 0.0 - 1.0
float c = (value / 100) * (saturation / 100);
float x = c * (1 - Math.Abs(((hue / 60) % 2) - 1));
float m = (value / 100) - c;
float r = 0;
float g = 0;
float b = 0;
if (hue >= 0 && hue < 60)
{
r = c;
g = x;
b = 0;
}
else if (hue >= 60 && hue < 120)
{
r = x;
g = c;
b = 0;
}
else if (hue >= 120 && hue < 180)
{
r = 0;
g = c;
b = x;
}
else if (hue >= 180 && hue < 240)
{
r = 0;
g = x;
b = c;
}
else if (hue >= 240 && hue < 300)
{
r = x;
g = 0;
b = c;
}
else if (hue >= 300 && hue < 360)
{
r = c;
g = 0;
b = x;
}
r += m;
g += m;
b += m;
return (r, g, b);
}
}
@@ -1,97 +0,0 @@
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.ArcGIS.HostApp;
public class ArcGISLayerUnpacker
{
/// <summary>
/// Cache of all collections created by unpacked Layer MapMembers. Key is the Speckle applicationId (Layer URI).
/// </summary>
public Dictionary<string, Collection> CollectionCache { get; } = new();
/// <summary>
/// Mapmembers can be layers containing objects, or LayerContainers containing other layers.
/// Unpacks selected mapMembers and creates their corresponding collection on the root collection.
/// </summary>
/// <param name="mapMembers"></param>
/// <param name="parentCollection"></param>
/// <returns>List of layers containing objects.</returns>
/// <exception cref="AC.CalledOnWrongThreadException">Thrown when this method is *not* called on the MCT, because this method accesses mapmember fields</exception>
public List<ADM.MapMember> UnpackSelection(
IEnumerable<ADM.MapMember> mapMembers,
Collection parentCollection,
List<ADM.MapMember>? objects = null
)
{
if (objects is null)
{
objects = new();
}
foreach (ADM.MapMember mapMember in mapMembers)
{
switch (mapMember)
{
case ADM.ILayerContainer container:
Collection containerCollection = CreateAndCacheMapMemberCollection(mapMember, true);
parentCollection.elements.Add(containerCollection);
UnpackSelection(container.Layers, containerCollection, objects);
break;
default:
if (!(objects.Contains(mapMember)))
{
Collection collection = CreateAndCacheMapMemberCollection(mapMember);
parentCollection.elements.Add(collection);
objects.Add(mapMember);
}
break;
}
}
return objects;
}
private Collection CreateAndCacheMapMemberCollection(ADM.MapMember mapMember, bool isLayerContainer = false)
{
string mapMemberApplicationId = mapMember.GetSpeckleApplicationId();
Collection collection =
new()
{
name = mapMember.Name,
applicationId = mapMemberApplicationId,
["type"] = mapMember.GetType().Name
};
switch (mapMember)
{
case ADM.IDisplayTable displayTable: // get fields from layers that implement IDisplayTable, eg FeatureLayer or StandaloneTable
Dictionary<string, string>? fields = displayTable
.GetFieldDescriptions()
.ToDictionary(field => field.Name, field => field.Type.ToString());
collection["fields"] = fields;
if (mapMember is ADM.BasicFeatureLayer basicFeatureLayer)
{
collection["shapeType"] = basicFeatureLayer.ShapeType.ToString();
}
break;
case ADM.Layer layer:
collection["mapLayerType"] = layer.MapLayerType.ToString();
break;
case ADM.ILayerContainer:
default:
break;
}
if (!isLayerContainer) // do not cache layer containers, since these won't contain any objects
{
CollectionCache.Add(mapMemberApplicationId, collection);
}
return collection;
}
}
@@ -1,31 +0,0 @@
using ArcGIS.Core.Data.Raster;
namespace Speckle.Connectors.ArcGIS.HostApp.Extensions;
public static class SpeckleApplicationIdExtensions
{
/// <summary>
/// Retrieves the Speckle application id for map members
/// </summary>
public static string GetSpeckleApplicationId(this ADM.MapMember mapMember) => mapMember.URI;
/// <summary>
/// Constructs the Speckle application id for Features as a concatenation of the layer URI (applicationId)
/// and the row OID (index of row in layer).
/// </summary>
/// <exception cref="ACD.Exceptions.GeodatabaseException">Throws when this is *not* called on MCT. Use QueuedTask.Run.</exception>
public static string GetSpeckleApplicationId(this ACD.Row row, string layerApplicationId) =>
$"{layerApplicationId}_{row.GetObjectID()}";
/// <summary>
/// Constructs the Speckle application id for Raster as a concatenation of the layer URI (applicationId) and 0-index
/// </summary>
public static string GetSpeckleApplicationId(this Raster _, string layerApplicationId) => $"{layerApplicationId}_0";
/// <summary>
/// Constructs the Speckle application id for LasDatasets as a concatenation of the layer URI (applicationId)
/// and point OID.
/// </summary>
public static string GetSpeckleApplicationId(this ACD.Analyst3D.LasPoint point, string layerApplicationId) =>
$"{layerApplicationId}_{point.PointID}";
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

@@ -1,411 +0,0 @@
using System.Diagnostics.Contracts;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Instances;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.ArcGIS3;
using Speckle.Converters.ArcGIS3.Utils;
using Speckle.Converters.Common;
using Speckle.Objects.Data;
using Speckle.Objects.Other;
using Speckle.Sdk;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.GraphTraversal;
using Speckle.Sdk.Models.Instances;
using Speckle.Sdk.Models.Proxies;
namespace Speckle.Connectors.ArcGIS.Operations.Receive;
public class ArcGISHostObjectBuilder : IHostObjectBuilder
{
private readonly IRootToHostConverter _converter;
private readonly IFeatureClassUtils _featureClassUtils;
private readonly ILocalToGlobalUnpacker _localToGlobalUnpacker;
private readonly LocalToGlobalConverterUtils _localToGlobalConverterUtils;
// POC: figure out the correct scope to only initialize on Receive
private readonly IConverterSettingsStore<ArcGISConversionSettings> _settingsStore;
private readonly GraphTraversal _traverseFunction;
private readonly ArcGISColorManager _colorManager;
public ArcGISHostObjectBuilder(
IRootToHostConverter converter,
IConverterSettingsStore<ArcGISConversionSettings> settingsStore,
IFeatureClassUtils featureClassUtils,
ILocalToGlobalUnpacker localToGlobalUnpacker,
LocalToGlobalConverterUtils localToGlobalConverterUtils,
GraphTraversal traverseFunction,
ArcGISColorManager colorManager
)
{
_converter = converter;
_settingsStore = settingsStore;
_featureClassUtils = featureClassUtils;
_localToGlobalUnpacker = localToGlobalUnpacker;
_localToGlobalConverterUtils = localToGlobalConverterUtils;
_traverseFunction = traverseFunction;
_colorManager = colorManager;
}
public Task<HostObjectBuilderResult> Build(
Base rootObject,
string projectName,
string modelName,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
return QueuedTask.Run(
() => BuildInternal(rootObject, projectName, modelName, onOperationProgressed, cancellationToken)
);
}
private HostObjectBuilderResult BuildInternal(
Base rootObject,
string projectName,
string modelName,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
// TODO get spatialRef and offsets & rotation from ProjectInfo in CommitObject
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
// Prompt the UI conversion started. Progress bar will swoosh.
onOperationProgressed.Report(new("Converting", null));
// get materials
List<RenderMaterialProxy>? materials = (rootObject[ProxyKeys.RENDER_MATERIAL] as List<object>)
?.Cast<RenderMaterialProxy>()
.ToList();
if (materials != null)
{
_colorManager.ParseMaterials(materials, onOperationProgressed);
}
// get colors
List<ColorProxy>? colors = (rootObject[ProxyKeys.COLOR] as List<object>)?.Cast<ColorProxy>().ToList();
if (colors != null)
{
_colorManager.ParseColors(colors, onOperationProgressed);
}
int count = 0;
IReadOnlyCollection<LocalToGlobalMap> objectsToConvert = GetObjectsToConvert(rootObject);
Dictionary<TraversalContext, ObjectConversionTracker> conversionTracker = new();
// 1. convert everything
List<ReceiveConversionResult> results = new(objectsToConvert.Count);
List<string> bakedObjectIds = new();
foreach (LocalToGlobalMap objectToConvert in objectsToConvert)
{
string[] path = GetLayerPath(objectToConvert.TraversalContext);
Base obj = objectToConvert.AtomicObject;
cancellationToken.ThrowIfCancellationRequested();
try
{
obj = _localToGlobalConverterUtils.TransformObjects(objectToConvert.AtomicObject, objectToConvert.Matrix);
object conversionResult = _converter.Convert(obj);
string nestedLayerPath = $"{string.Join("\\", path)}";
if (obj is ArcgisObject gisObj)
{
nestedLayerPath += $"\\{gisObj.name}";
}
else
{
nestedLayerPath += $"\\{obj.speckle_type.Split(".")[^1]}"; // add sub-layer by speckleType, for non-GIS objects
}
conversionTracker[objectToConvert.TraversalContext] = new ObjectConversionTracker(
obj,
(Geometry?)conversionResult,
nestedLayerPath
);
}
catch (Exception ex) when (!ex.IsFatal()) // DO NOT CATCH SPECIFIC STUFF, conversion errors should be recoverable
{
results.Add(new(Status.ERROR, obj, null, null, ex));
}
onOperationProgressed.Report(new("Converting", (double)++count / objectsToConvert.Count));
}
// 2.1. Group conversionTrackers (to write into datasets)
onOperationProgressed.Report(new("Grouping features into layers", null));
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups =
_featureClassUtils.GroupConversionTrackers(
conversionTracker,
(s, progres) => onOperationProgressed.Report(new(s, progres))
);
// 2.2. Write groups of objects to Datasets
onOperationProgressed.Report(new("Writing to Database", null));
_featureClassUtils.CreateDatasets(
conversionTracker,
convertedGroups,
(s, progres) => onOperationProgressed.Report(new(s, progres))
);
// 3. add layer and tables to the Map and Table Of Content
// Create placeholder for GroupLayers
Dictionary<string, GroupLayer> createdLayerGroups = new();
int bakeCount = 0;
Dictionary<string, (MapMember, CIMUniqueValueRenderer?)> bakedMapMembers = new();
onOperationProgressed.Report(new("Adding to Map", bakeCount));
foreach (var item in conversionTracker)
{
cancellationToken.ThrowIfCancellationRequested();
var trackerItem = conversionTracker[item.Key]; // updated tracker object
// BAKE OBJECTS HERE
if (trackerItem.Exception != null)
{
results.Add(new(Status.ERROR, trackerItem.Base, null, null, trackerItem.Exception));
}
else if (trackerItem.DatasetId == null)
{
results.Add(
new(
Status.ERROR,
trackerItem.Base,
null,
null,
new ArgumentException($"Unknown error: Dataset not created for {trackerItem.Base.speckle_type}")
)
);
}
else if (bakedMapMembers.TryGetValue(trackerItem.DatasetId, out var value))
{
// if the layer already created, just add more features to report, and more color categories
// add layer and layer URI to tracker
trackerItem.AddConvertedMapMember(value.Item1);
trackerItem.AddLayerURI(value.Item1.URI);
conversionTracker[item.Key] = trackerItem; // not necessary atm, but needed if we use conversionTracker further
// add color category
CIMUniqueValueRenderer? uvr = _colorManager.CreateOrEditLayerRenderer(item.Key, trackerItem, value.Item2);
// replace renderer
bakedMapMembers[trackerItem.DatasetId] = (value.Item1, uvr);
// only add a report item
AddResultsFromTracker(trackerItem, results);
}
else
{
// no layer yet, create and add layer to Map
MapMember mapMember = AddDatasetsToMap(trackerItem, createdLayerGroups, projectName, modelName);
// add layer and layer URI to tracker
trackerItem.AddConvertedMapMember(mapMember);
trackerItem.AddLayerURI(mapMember.URI);
conversionTracker[item.Key] = trackerItem; // not necessary atm, but needed if we use conversionTracker further
// add layer URI to bakedIds
bakedObjectIds.Add(trackerItem.MappedLayerURI == null ? "" : trackerItem.MappedLayerURI);
// add color category
CIMUniqueValueRenderer? uvr = _colorManager.CreateOrEditLayerRenderer(item.Key, trackerItem, null);
// mark dataset as already created
bakedMapMembers[trackerItem.DatasetId] = (mapMember, uvr);
// add report item
AddResultsFromTracker(trackerItem, results);
}
onOperationProgressed.Report(new("Adding to Map", (double)++bakeCount / conversionTracker.Count));
}
// apply renderers to baked layers
foreach (var bakedMember in bakedMapMembers)
{
if (bakedMember.Value.Item1 is FeatureLayer fLayer)
{
// Set the feature layer's renderer.
fLayer.SetRenderer(bakedMember.Value.Item2);
}
}
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
// TODO: validated a correct set regarding bakedobject ids
return new HostObjectBuilderResult(bakedObjectIds, results);
}
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
{
// keep GISlayers in the list, because they are still needed to extract CRS of the commit (code below)
List<TraversalContext> objectsToConvertTc = _traverseFunction.Traverse(rootObject).ToList();
// now filter the objects
objectsToConvertTc = objectsToConvertTc.Where(ctx => ctx.Current is not Collection).ToList();
var instanceDefinitionProxies = (rootObject[ProxyKeys.INSTANCE_DEFINITION] as List<object>)
?.Cast<InstanceDefinitionProxy>()
.ToList();
return _localToGlobalUnpacker.Unpack(instanceDefinitionProxies, objectsToConvertTc);
}
private void AddResultsFromTracker(ObjectConversionTracker trackerItem, List<ReceiveConversionResult> results)
{
if (trackerItem.MappedLayerURI == null) // should not happen
{
results.Add(
new(
Status.ERROR,
trackerItem.Base,
null,
null,
new ArgumentException($"Created Layer URI not found for {trackerItem.Base.speckle_type}")
)
);
}
else
{
// encode layer ID and ID of its feature in 1 object represented as string
ObjectID objectId = new(trackerItem.MappedLayerURI, trackerItem.DatasetRow);
if (trackerItem.HostAppGeom != null) // individual hostAppGeometry
{
results.Add(
new(
Status.SUCCESS,
trackerItem.Base,
objectId.ObjectIdToString(),
trackerItem.HostAppGeom.GetType().ToString()
)
);
}
else // hostApp Layers
{
results.Add(
new(
Status.SUCCESS,
trackerItem.Base,
objectId.ObjectIdToString(),
trackerItem.HostAppMapMember?.GetType().ToString()
)
);
}
}
}
private MapMember AddDatasetsToMap(
ObjectConversionTracker trackerItem,
Dictionary<string, GroupLayer> createdLayerGroups,
string projectName,
string modelName
)
{
// get layer details
string? datasetId = trackerItem.DatasetId; // should not be null here
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
string nestedLayerName = trackerItem.NestedLayerName;
// add group for the current layer
string shortName = nestedLayerName.Split("\\")[^1];
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
// if no general group layer found
if (createdLayerGroups.Count == 0)
{
Map map = _settingsStore.Current.Map;
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
mainGroupLayer.SetExpanded(true);
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
}
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
// Most of the Speckle-written datasets will be containing geometry and added as Layers
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
// We can create a connection to the dataset in advance and determine its type, but this will be more
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
try
{
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
if (layer == null)
{
throw new SpeckleException($"Layer '{shortName}' was not created");
}
layer.SetExpanded(false);
// if Scene
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
if (_settingsStore.Current.Map.IsScene)
{
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
var layerElevationSurface = new CIMLayerElevationSurface { ElevationSurfaceLayerURI = groundSurfaceLayer.URI, };
// for Feature Layers
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
{
cimLyr.LayerElevation = layerElevationSurface;
layer.SetDefinition(cimLyr);
}
}
return layer;
}
catch (ArgumentException)
{
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
uri,
groupLayer,
tableName: shortName
);
return table;
}
}
private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary<string, GroupLayer> createdLayerGroups)
{
GroupLayer lastGroup = createdLayerGroups.FirstOrDefault().Value;
if (lastGroup == null) // if layer not found
{
throw new InvalidOperationException("Speckle Layer Group not found");
}
// iterate through each nested level
string createdGroupPath = "";
var allPathElements = nestedLayerPath.Split("\\").Where(x => !string.IsNullOrEmpty(x));
foreach (string pathElement in allPathElements)
{
createdGroupPath += "\\" + pathElement;
if (createdLayerGroups.TryGetValue(createdGroupPath, out var existingGroupLayer))
{
lastGroup = existingGroupLayer;
}
else
{
// create new GroupLayer under last found Group, named with last pathElement
lastGroup = LayerFactory.Instance.CreateGroupLayer(lastGroup, 0, pathElement);
lastGroup.SetExpanded(true);
}
createdLayerGroups[createdGroupPath] = lastGroup;
}
return lastGroup;
}
[Pure]
private static string[] GetLayerPath(TraversalContext context)
{
string[] collectionBasedPath = context.GetAscendantOfType<Collection>().Select(c => c.name).ToArray();
string[] reverseOrderPath =
collectionBasedPath.Length != 0 ? collectionBasedPath : context.GetPropertyPath().ToArray();
var originalPath = reverseOrderPath.Reverse().ToArray();
return originalPath.Where(x => !string.IsNullOrEmpty(x)).ToArray();
}
}
@@ -1,362 +0,0 @@
using ArcGIS.Core.Data.Raster;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Extensions;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.ArcGIS3;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.ArcGis.Operations.Send;
/// <summary>
/// Stateless builder object to turn an ISendFilter into a <see cref="Base"/> object
/// </summary>
public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
{
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
private readonly ArcGISLayerUnpacker _layerUnpacker;
private readonly ArcGISColorUnpacker _colorUnpacker;
private readonly IConverterSettingsStore<ArcGISConversionSettings> _converterSettings;
private readonly ILogger<ArcGISRootObjectBuilder> _logger;
private readonly ISdkActivityFactory _activityFactory;
private readonly MapMembersUtils _mapMemberUtils;
public ArcGISRootObjectBuilder(
ArcGISLayerUnpacker layerUnpacker,
ArcGISColorUnpacker colorUnpacker,
IConverterSettingsStore<ArcGISConversionSettings> converterSettings,
IRootToSpeckleConverter rootToSpeckleConverter,
ILogger<ArcGISRootObjectBuilder> logger,
ISdkActivityFactory activityFactory,
MapMembersUtils mapMemberUtils
)
{
_layerUnpacker = layerUnpacker;
_colorUnpacker = colorUnpacker;
_converterSettings = converterSettings;
_rootToSpeckleConverter = rootToSpeckleConverter;
_logger = logger;
_activityFactory = activityFactory;
_mapMemberUtils = mapMemberUtils;
}
public Task<RootObjectBuilderResult> Build(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
private async Task<RootObjectBuilderResult> BuildInternal(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
// TODO: add a warning if Geographic CRS is set
// "Data has been sent in the units 'degrees'. It is advisable to set the project CRS to Projected type (e.g. EPSG:32631) to be able to receive geometry correctly in CAD/BIM software"
// 0 - Create Root collection and attach CRS properties
// CRS properties are useful for data based workflows coming out of gis applications
SpatialReference sr = _converterSettings.Current.ActiveCRSoffsetRotation.SpatialReference;
Dictionary<string, object?> spatialReference =
new()
{
["name"] = sr.Name,
["unit"] = sr.Unit.Name,
["wkid"] = sr.Wkid,
["wkt"] = sr.Wkt,
};
Dictionary<string, object?> crs =
new()
{
["trueNorthRadians"] = _converterSettings.Current.ActiveCRSoffsetRotation.TrueNorthRadians,
["latOffset"] = _converterSettings.Current.ActiveCRSoffsetRotation.LatOffset,
["lonOffset"] = _converterSettings.Current.ActiveCRSoffsetRotation.LonOffset,
["spatialReference"] = spatialReference
};
Collection rootCollection =
new()
{
name = ADM.MapView.Active.Map.Name,
["units"] = _converterSettings.Current.SpeckleUnits,
["crs"] = crs
};
// 1 - Unpack the selected mapmembers
// In Arcgis, mapmembers are collections of other mapmember or objects.
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
// Mapmember dynamically attached properties are also added at this step.
List<ADM.MapMember> unpackedLayers;
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
long allFeaturesCount;
ADM.Map map = ADM.MapView.Active.Map;
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
using (var _ = _activityFactory.Start("Unpacking selection"))
{
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
allFeaturesCount = layersWithFeatureCount.Values.Sum();
}
List<SendConversionResult> results = new(unpackedLayers.Count);
onOperationProgressed.Report(new("Converting", null));
using (var convertingActivity = _activityFactory.Start("Converting objects"))
{
long count = 0;
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
{
cancellationToken.ThrowIfCancellationRequested();
string layerApplicationId = layer.GetSpeckleApplicationId();
try
{
// get the corresponding collection for this layer - we'll add all converted objects to the collection
if (_layerUnpacker.CollectionCache.TryGetValue(layerApplicationId, out Collection? layerCollection))
{
var status = Status.SUCCESS;
var sdkStatus = SdkActivityStatusCode.Ok;
// TODO: check cache first to see if this layer was previously converted
/*
if (_sendConversionCache.TryGetValue(
sendInfo.ProjectId,
layerApplicationId,
out ObjectReference? value
))
{
}
*/
switch (layer)
{
case ADM.FeatureLayer featureLayer:
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
featureLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
break;
case ADM.RasterLayer rasterLayer:
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
rasterLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedRasterLayerObjects);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
lasDatasetLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedLasDatasetObjects);
break;
default:
status = Status.ERROR;
sdkStatus = SdkActivityStatusCode.Error;
break;
}
count += layerFeatureCount;
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
convertingActivity?.SetStatus(sdkStatus);
}
else
{
throw new SpeckleException($"No converted Collection found for layer {layerApplicationId}.");
}
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogSendConversionError(ex, layer.GetType().Name);
results.Add(new(Status.ERROR, layerApplicationId, layer.GetType().Name, null, ex));
convertingActivity?.SetStatus(SdkActivityStatusCode.Error);
convertingActivity?.RecordException(ex);
}
await Task.Yield();
}
}
if (results.All(x => x.Status == Status.ERROR))
{
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
}
// 3 - Add Color Proxies
rootCollection[ProxyKeys.COLOR] = _colorUnpacker.ColorProxyCache.Values.ToList();
return new RootObjectBuilderResult(rootCollection, results);
}
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
{
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
foreach (ADM.MapMember layer in unpackedLayers)
{
switch (layer)
{
case ADM.FeatureLayer featureLayer:
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
break;
case ADM.RasterLayer rasterLayer:
// count Raster layer as 1 feature: not optimal but this is the approach for now
layersFeatureCount.Add(rasterLayer, 1);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
var dataset = lasDatasetLayer.GetLasDataset();
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
layersFeatureCount.Add(
lasDatasetLayer,
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
);
break;
}
}
return layersFeatureCount;
}
private List<Base> ConvertFeatureLayerObjects(
ADM.FeatureLayer featureLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
// store the layer renderer for color unpacking
_colorUnpacker.StoreRendererAndFields(featureLayer);
// search the rows of the layer, where each row is treated like an object
// RowCursor is IDisposable but is not being correctly picked up by IDE warnings.
// This means we need to be carefully adding using statements based on the API documentation coming from each method/class
using (ACD.RowCursor rowCursor = featureLayer.Search())
{
while (rowCursor.MoveNext())
{
// allow cancellation before every feature
cancellationToken.ThrowIfCancellationRequested();
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
using (ACD.Row row = rowCursor.Current)
{
// get application id. test for subtypes before defaulting to base type.
Base converted = _rootToSpeckleConverter.Convert(row);
string applicationId = row.GetSpeckleApplicationId(layerApplicationId);
converted.applicationId = applicationId;
convertedObjects.Add(converted);
// process the object color
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
return convertedObjects;
}
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
private List<Base> ConvertRasterLayerObjects(
ADM.RasterLayer rasterLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
Raster raster = rasterLayer.GetRaster();
// check cancellation token before conversion
cancellationToken.ThrowIfCancellationRequested();
Base converted = _rootToSpeckleConverter.Convert(raster);
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
converted.applicationId = applicationId;
convertedObjects.Add(converted);
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
return convertedObjects;
}
private List<Base> ConvertLasDatasetLayerObjects(
ADM.LasDatasetLayer lasDatasetLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
try
{
// store the layer renderer for color unpacking
_colorUnpacker.StoreRenderer(lasDatasetLayer);
using (ACD.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.SearchPoints(new ACD.Analyst3D.LasPointFilter()))
{
while (ptCursor.MoveNext())
{
// allow cancellation before every point
cancellationToken.ThrowIfCancellationRequested();
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
{
Base converted = _rootToSpeckleConverter.Convert(pt);
string applicationId = pt.GetSpeckleApplicationId(layerApplicationId);
converted.applicationId = applicationId;
convertedObjects.Add(converted);
// process the object color
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
}
catch (ACD.Exceptions.TinException ex)
{
throw new SpeckleException("3D analyst extension is not enabled for .las layer operations", ex);
}
return convertedObjects;
}
}
@@ -1,14 +0,0 @@
{
"profiles": {
"Speckle.Connectors.ArcGIS3_all_users": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
"commandLineArgs": ""
},
"Speckle.Connectors.ArcGIS3_user": {
"commandName": "Executable",
"executablePath": "C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
"commandLineArgs": ""
}
}
}
@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<PlatformTarget>x64</PlatformTarget>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<RootNameSpace>Speckle.Connectors.ArcGIS</RootNameSpace>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<DefineConstants>$(DefineConstants);ARCGIS3</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<ItemGroup>
<Content Include="Config.daml" />
<Content Include="Images\s2logo_16.png" />
<Content Include="Images\s2logo_32.png" />
<Content Include="DarkImages\s2logo_16.png" />
<Content Include="DarkImages\s2logo_32.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Esri.ArcGISPro.Extensions30" IncludeAssets="compile" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Converters\ArcGIS\Speckle.Converters.ArcGIS3\Speckle.Converters.ArcGIS3.csproj" />
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj" />
</ItemGroup>
<Import Project="Esri.ArcGISPro.Extensions30.Speckle.targets" />
</Project>
@@ -1,42 +0,0 @@
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
namespace Speckle.Connectors.ArcGIS;
internal sealed class SpeckleDUI3ViewModel : DockPane
{
private const string DOCKPANE_ID = "SpeckleDUI3_SpeckleDUI3";
internal static void Create()
{
var pane = FrameworkApplication.DockPaneManager.Find(DOCKPANE_ID);
pane?.Activate();
}
/// <summary>
/// Called when the pane is initialized.
/// </summary>
protected override async Task InitializeAsync()
{
await base.InitializeAsync();
}
/// <summary>
/// Called when the pane is uninitialized.
/// </summary>
protected override async Task UninitializeAsync()
{
await base.UninitializeAsync();
}
}
/// <summary>
/// Button implementation to create a new instance of the pane and activate it.
/// </summary>
internal sealed class SpeckleDUI3OpenButton : Button
{
protected override void OnClick()
{
SpeckleDUI3ViewModel.Create();
}
}
@@ -1,18 +0,0 @@
using System.Windows.Controls;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.DUI.WebView;
namespace Speckle.Connectors.ArcGIS;
public class SpeckleDUI3Wrapper : UserControl
{
public SpeckleDUI3Wrapper()
{
Initialize();
}
private void Initialize()
{
Content = SpeckleModule.Current.Container.GetRequiredService<DUI3ControlWebView>();
}
}
@@ -1,61 +0,0 @@
using ArcGIS.Desktop.Framework;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.ArcGIS.DependencyInjection;
using Speckle.Connectors.Common;
using Speckle.Connectors.DUI;
using Speckle.Converters.ArcGIS3;
using Module = ArcGIS.Desktop.Framework.Contracts.Module;
namespace Speckle.Connectors.ArcGIS;
/// <summary>
/// This sample shows how to implement pane that contains an Edge WebView2 control using the built-in ArcGIS Pro SDK's WebBrowser control. For details on how to utilize the WebBrowser control in an add-in see here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#webbrowser For details on how to utilize the Microsoft Edge web browser control in an add-in see here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Framework#webbrowser-control
/// </summary>
internal sealed class SpeckleModule : Module
{
private static SpeckleModule? s_this;
private readonly IDisposable? _disposableLogger;
/// <summary>
/// Retrieve the singleton instance to this module here
/// </summary>
public static SpeckleModule Current =>
s_this ??= (SpeckleModule)FrameworkApplication.FindModule("ConnectorArcGIS_Module");
public ServiceProvider Container { get; }
public SpeckleModule()
{
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver.OnAssemblyResolve<SpeckleModule>;
var services = new ServiceCollection();
// init DI
_disposableLogger = services.Initialize(HostApplications.ArcGIS, GetVersion());
services.AddArcGIS();
services.AddArcGISConverters();
Container = services.BuildServiceProvider();
Container.UseDUI();
}
private HostAppVersion GetVersion()
{
#if ARCGIS3
return HostAppVersion.v3;
#else
throw new NotImplementedException();
#endif
}
/// <summary>
/// Called by Framework when ArcGIS Pro is closing
/// </summary>
/// <returns>False to prevent Pro from closing, otherwise True</returns>
protected override bool CanUnload()
{
//TODO - add your business logic
//return false to ~cancel~ Application close
_disposableLogger?.Dispose();
Container.Dispose();
return true;
}
}
@@ -1,131 +0,0 @@
using System.Xml.Linq;
using ArcGIS.Desktop.Core.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
namespace Speckle.Connectors.ArcGIS.Utils;
public class ArcGISDocumentStore : DocumentModelStore
{
public ArcGISDocumentStore(
ILogger<DocumentModelStore> logger,
IJsonSerializer jsonSerializer,
ITopLevelExceptionHandler topLevelExceptionHandler
)
: base(logger, jsonSerializer)
{
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
ProjectSavingEvent.Subscribe(
_ =>
{
topLevelExceptionHandler.CatchUnhandled(OnProjectSaving);
return Task.CompletedTask;
},
true
);
ProjectClosingEvent.Subscribe(
_ =>
{
topLevelExceptionHandler.CatchUnhandled(OnProjectClosing);
return Task.CompletedTask;
},
true
);
// in case plugin was loaded into already opened Map, read metadata from the current Map
if (!IsDocumentInit && MapView.Active != null)
{
IsDocumentInit = true;
LoadState();
OnDocumentChanged();
}
}
private void OnProjectClosing()
{
if (MapView.Active is null)
{
return;
}
SaveState();
}
private void OnProjectSaving()
{
if (MapView.Active is not null)
{
SaveState();
}
}
/// <summary>
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
/// </summary>
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
{
if (args.IncomingView is null)
{
return;
}
IsDocumentInit = true;
LoadState();
OnDocumentChanged();
}
protected override void HostAppSaveState(string modelCardState) =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
var existingMetadata = map.GetMetadata();
// Parse existing metadata
XDocument existingXmlDocument = !string.IsNullOrEmpty(existingMetadata)
? XDocument.Parse(existingMetadata)
: new XDocument(new XElement("metadata"));
XElement xmlModelCards = new("SpeckleModelCards", modelCardState);
// Check if SpeckleModelCards element already exists at root and update it
var speckleModelCardsElement = existingXmlDocument.Root?.Element("SpeckleModelCards");
if (speckleModelCardsElement != null)
{
speckleModelCardsElement.ReplaceWith(xmlModelCards);
}
else
{
existingXmlDocument.Root?.Add(xmlModelCards);
}
map.SetMetadata(existingXmlDocument.ToString());
})
.FireAndForget();
protected override void LoadState() =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
var metadata = map.GetMetadata();
var root = XDocument.Parse(metadata).Root;
var element = root?.Element("SpeckleModelCards");
if (element is null)
{
ClearAndSave();
return;
}
string modelsString = element.Value;
LoadFromString(modelsString);
})
.FireAndForget();
}
@@ -1,16 +0,0 @@
using ArcGIS.Desktop.Mapping;
namespace Speckle.Connectors.ArcGIS.Utils;
// bind together a layer object on the map, and auto-assigned ID if the specific feature
public readonly struct MapMemberFeature
{
public int? FeatureId { get; } // unique feature id (start from 0) of a feature in the layer
public MapMember MapMember { get; } // layer object on the Map
public MapMemberFeature(MapMember mapMember, int? featureId)
{
MapMember = mapMember;
FeatureId = featureId;
}
}
@@ -1,61 +0,0 @@
using ArcGIS.Desktop.Mapping;
namespace Speckle.Connectors.ArcGIS.Utils;
public class MapMembersUtils
{
/// <summary>
/// Returns all Layers and Standalone Tables present on the Map
/// </summary>
/// <param name="map"></param>
/// <returns></returns>
public List<MapMember> GetAllMapMembers(Map map)
{
// first get all map layers
List<MapMember> mapMembers = new();
var layerMapMembers = UnpackMapLayers(map.Layers);
mapMembers.AddRange(layerMapMembers);
// add tables
var standaloneTableMapMembers = UnpackMapLayers(map.StandaloneTables);
mapMembers.AddRange(standaloneTableMapMembers);
return mapMembers;
}
public List<MapMember> UnpackMapLayers(IEnumerable<MapMember> mapMembersToUnpack)
{
List<MapMember> mapMembers = new();
foreach (var layer in mapMembersToUnpack)
{
mapMembers.Add(layer);
switch (layer)
{
case ILayerContainer subGroup:
var subLayerMapMembers = UnpackMapLayers(subGroup.Layers);
mapMembers.AddRange(subLayerMapMembers);
break;
}
}
return mapMembers;
}
/// <summary>
/// Sorts the selected mapmembers into the same order as they appear in the Table of Contents (TOC) bar in the file.
/// This is a required step before unpacking layers, because depending on the user selection order, some children layers may appear before their container layer if both the container and children layers are selected.
/// </summary>
public IEnumerable<MapMember> GetMapMembersInOrder(Map map, IReadOnlyList<MapMember> selectedMapMembers)
{
// first get all map layers
List<MapMember> allMapMembers = GetAllMapMembers(map);
// recalculate selected layer priority from all map layers
foreach (MapMember mapMember in allMapMembers)
{
if (selectedMapMembers.Contains(mapMember))
{
yield return mapMember;
}
}
}
}
@@ -1,38 +0,0 @@
namespace Speckle.Connectors.ArcGIS.Utils;
// this struct is needed to be able to parse single-string value into IDs of both a layer, and it's individual feature
public struct ObjectID
{
private const string FEATURE_ID_SEPARATOR = "__speckleFeatureId__";
public string MappedLayerURI { get; } // unique ID of the layer on the map
public int? FeatureId { get; } // unique feature id (start from 0) of a feature in the layer
public ObjectID(string encodedId)
{
List<string> stringParts = encodedId.Split(FEATURE_ID_SEPARATOR).ToList();
MappedLayerURI = stringParts[0];
FeatureId = null;
if (stringParts.Count > 1)
{
FeatureId = Convert.ToInt32(stringParts[1]);
}
}
public ObjectID(string layerId, int? featureId)
{
MappedLayerURI = layerId;
FeatureId = featureId;
}
public readonly string ObjectIdToString()
{
if (FeatureId == null)
{
return $"{MappedLayerURI}";
}
else
{
return $"{MappedLayerURI}{FEATURE_ID_SEPARATOR}{FeatureId}";
}
}
}
@@ -1,359 +0,0 @@
{
"version": 2,
"dependencies": {
"net6.0-windows7.0": {
"Esri.ArcGISPro.Extensions30": {
"type": "Direct",
"requested": "[3.2.0.49743, )",
"resolved": "3.2.0.49743",
"contentHash": "fmnYm+mD14Cz0Uqh1ij37SfLJerkyFHK5581y5tXT/l3H2ZvUmVuuxjYquXzyzj9p7IexQzMW4xCpxe+mD922g=="
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Direct",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
"resolved": "1.0.3",
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
"dependencies": {
"Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3"
}
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"PolySharp": {
"type": "Direct",
"requested": "[1.14.1, )",
"resolved": "1.14.1",
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
},
"Speckle.InterfaceGenerator": {
"type": "Direct",
"requested": "[0.9.6, )",
"resolved": "0.9.6",
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0",
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
"System.Reactive": "5.0.0"
}
},
"GraphQL.Client.Abstractions": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
"dependencies": {
"GraphQL.Primitives": "6.0.0"
}
},
"GraphQL.Client.Abstractions.Websocket": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0"
}
},
"GraphQL.Primitives": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
"dependencies": {
"Microsoft.Data.Sqlite.Core": "7.0.5",
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
}
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"Microsoft.Extensions.Configuration": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
"dependencies": {
"Microsoft.Extensions.Primitives": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Primitives": "2.2.0",
"System.ComponentModel.Annotations": "4.5.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
"dependencies": {
"System.Memory": "4.5.1",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
"type": "Transitive",
"resolved": "1.0.3",
"contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
"dependencies": {
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
"dependencies": {
"System.Memory": "4.5.3"
}
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
},
"SQLitePCLRaw.provider.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
"resolved": "4.5.0",
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
},
"System.Reactive": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "4.5.1",
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
},
"speckle.common.meshtriangulation": {
"type": "Project",
"dependencies": {
"LibTessDotNet": "[1.1.15, )",
"Speckle.DoubleNumerics": "[4.1.0, )"
}
},
"speckle.connectors.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )"
}
},
"speckle.connectors.dui.webview": {
"type": "Project",
"dependencies": {
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
"Speckle.Connectors.DUI": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
"type": "Project"
},
"speckle.converters.arcgis3": {
"type": "Project",
"dependencies": {
"Esri.ArcGISPro.Extensions30": "[3.2.0.49743, )",
"Speckle.Common.MeshTriangulation": "[1.0.0, )",
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.converters.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
}
},
"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, )",
"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.Web.WebView2": {
"type": "CentralTransitive",
"requested": "[1.0.1938.49, )",
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
}
},
"net6.0-windows7.0/win-x64": {
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
},
"Microsoft.Web.WebView2": {
"type": "CentralTransitive",
"requested": "[1.0.1938.49, )",
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
}
}
}
}
+6 -6
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Target AfterTargets="Clean" Name="CleanAddinAutocad" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Clean" Name="CleanAddinAutocad" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion);" />
</Target>
<Target AfterTargets="Build" Name="AfterBuildAutoCAD" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Build" Name="AfterBuildAutoCAD" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<ItemGroup>
<AutoCADDLLs Include="$(TargetDir)\**\*.*" />
</ItemGroup>
@@ -12,11 +12,11 @@
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion)\%(RecursiveDir)" SourceFiles="@(AutoCADDLLs)" />
</Target>
<Target AfterTargets="Clean" Name="CleanAddinCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Clean" Name="CleanAddinCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion);" />
</Target>
<Target AfterTargets="Build" Name="AfterBuildCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Build" Name="AfterBuildCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<ItemGroup>
<Civil3DDLLs Include="$(TargetDir)\**\*.*" />
</ItemGroup>
@@ -24,11 +24,11 @@
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion)\%(RecursiveDir)" SourceFiles="@(Civil3DDLLs)" />
</Target>
<PropertyGroup Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<PropertyGroup Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<StartAction>Program</StartAction>
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(AutoCADVersion)\acad.exe</StartProgram>
</PropertyGroup>
<PropertyGroup Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<PropertyGroup Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<StartAction>Program</StartAction>
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
<StartArguments>/product C3D</StartArguments>
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -292,7 +292,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,18 +336,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -357,14 +357,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -292,7 +292,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -336,18 +336,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -357,14 +357,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -293,7 +293,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -75,11 +75,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -215,9 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -249,7 +244,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -293,34 +288,33 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -75,11 +75,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -215,9 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -249,7 +244,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -293,34 +288,33 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -1,119 +1,59 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
namespace Speckle.Connectors.Autocad.Bindings;
public abstract class AutocadReceiveBaseBinding : IReceiveBinding
public abstract class AutocadReceiveBaseBinding(
IBrowserBridge parent,
ICancellationManager cancellationManager,
IThreadContext threadContext,
IReceiveOperationManagerFactory receiveOperationManagerFactory
) : IReceiveBinding
{
public string Name => "receiveBinding";
public IBrowserBridge Parent { get; }
public IBrowserBridge Parent { get; } = parent;
private readonly DocumentModelStore _store;
private readonly ICancellationManager _cancellationManager;
private readonly IServiceProvider _serviceProvider;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<AutocadReceiveBinding> _logger;
private readonly ISpeckleApplication _speckleApplication;
private readonly IThreadContext _threadContext;
private ReceiveBindingUICommands Commands { get; } = new(parent);
private ReceiveBindingUICommands Commands { get; }
protected abstract void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc);
protected AutocadReceiveBaseBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
)
{
_store = store;
_cancellationManager = cancellationManager;
_serviceProvider = serviceProvider;
_operationProgressManager = operationProgressManager;
_logger = logger;
_speckleApplication = speckleApplication;
_threadContext = threadContext;
Parent = parent;
Commands = new ReceiveBindingUICommands(parent);
}
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
public void CancelReceive(string modelCardId) => cancellationManager.CancelOperation(modelCardId);
public async Task Receive(string modelCardId) =>
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
await threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
private async Task ReceiveInternal(string modelCardId)
{
using var scope = _serviceProvider.CreateScope();
InitializeSettings(scope.ServiceProvider);
try
{
// Get receiver card
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
using var manager = receiveOperationManagerFactory.Create();
await manager.Process(
Commands,
modelCardId,
InitializeSettings,
async (_, processor) =>
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No download model card was found.");
try
{
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
Application.DocumentManager.DocumentActivationEnabled = false;
return await processor();
}
finally
{
// reenable document activation
Application.DocumentManager.DocumentActivationEnabled = true;
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
Application.DocumentManager.CurrentDocument.Editor.Regen();
}
}
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
Application.DocumentManager.DocumentActivationEnabled = false;
// Receive host objects
var operationResults = await scope
.ServiceProvider.GetRequiredService<ReceiveOperation>()
.Execute(
modelCard.GetReceiveInfo(_speckleApplication.Slug),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelReceiveResult(
modelCardId,
operationResults.BakedObjectIds,
operationResults.ConversionResults
);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
finally
{
// reenable document activation
Application.DocumentManager.DocumentActivationEnabled = true;
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
Application.DocumentManager.CurrentDocument.Editor.Regen();
}
);
}
}
@@ -1,13 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converters.Autocad;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Autocad.Bindings;
@@ -16,31 +14,18 @@ public sealed class AutocadReceiveBinding : AutocadReceiveBaseBinding
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
public AutocadReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
IThreadContext threadContext,
IReceiveOperationManagerFactory receiveOperationManagerFactory
)
: base(
store,
parent,
cancellationManager,
serviceProvider,
operationProgressManager,
logger,
speckleApplication,
threadContext
)
: base(parent, cancellationManager, threadContext, receiveOperationManagerFactory)
{
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
}
protected override void InitializeSettings(IServiceProvider serviceProvider)
protected override void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc)
{
serviceProvider
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
@@ -1,23 +1,16 @@
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.Extensions;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Sdk;
using Speckle.Sdk.Common;
namespace Speckle.Connectors.Autocad.Bindings;
@@ -33,14 +26,11 @@ public abstract class AutocadSendBaseBinding : ISendBinding
private readonly DocumentModelStore _store;
private readonly List<ISendFilter> _sendFilters;
private readonly ICancellationManager _cancellationManager;
private readonly IServiceProvider _serviceProvider;
private readonly ISendConversionCache _sendConversionCache;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<AutocadSendBinding> _logger;
private readonly ISpeckleApplication _speckleApplication;
private readonly IThreadContext _threadContext;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IAppIdleManager _idleManager;
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
/// <summary>
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
@@ -55,27 +45,21 @@ public abstract class AutocadSendBaseBinding : ISendBinding
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
ISpeckleApplication speckleApplication,
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager idleManager
IAppIdleManager idleManager,
ISendOperationManagerFactory sendOperationManagerFactory
)
{
_store = store;
_serviceProvider = serviceProvider;
_cancellationManager = cancellationManager;
_sendFilters = sendFilters.ToList();
_sendConversionCache = sendConversionCache;
_operationProgressManager = operationProgressManager;
_logger = logger;
_speckleApplication = speckleApplication;
_threadContext = threadContext;
_topLevelExceptionHandler = topLevelExceptionHandler;
_idleManager = idleManager;
_sendOperationManagerFactory = sendOperationManagerFactory;
Parent = parent;
Commands = new SendBindingUICommands(parent);
@@ -152,55 +136,17 @@ public abstract class AutocadSendBaseBinding : ISendBinding
{
try
{
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
{
// Handle as GLOBAL ERROR at BrowserBridge
throw new InvalidOperationException("No publish model card was found.");
}
using var scope = _serviceProvider.CreateScope();
InitializeSettings(scope.ServiceProvider);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var manager = _sendOperationManagerFactory.Create();
// Disable document activation (document creation and document switch)
// Not disabling results in DUI model card being out of sync with the active document
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
Application.DocumentManager.DocumentActivationEnabled = false;
// Get elements to convert
List<AutocadRootObject> autocadObjects = Application.DocumentManager.CurrentDocument.GetObjects(
modelCard.SendFilter.NotNull().RefreshObjectIds()
await manager.Process(
Commands,
modelCardId,
(sp, card) => InitializeSettings(sp),
card => Application.DocumentManager.CurrentDocument.GetObjects(card.SendFilter.NotNull().RefreshObjectIds())
);
if (autocadObjects.Count == 0)
{
// Handle as CARD ERROR in this function
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
var sendResult = await scope
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
.Execute(
autocadObjects,
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.VersionId, sendResult.ConversionResults);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
return;
}
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
finally
{
@@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
@@ -9,7 +8,6 @@ using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Converters.Autocad;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Autocad.Bindings;
@@ -22,29 +20,23 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager appIdleManager
IAppIdleManager appIdleManager,
ISendOperationManagerFactory sendOperationManagerFactory
)
: base(
store,
parent,
sendFilters,
cancellationManager,
serviceProvider,
sendConversionCache,
operationProgressManager,
logger,
speckleApplication,
threadContext,
topLevelExceptionHandler,
appIdleManager
appIdleManager,
sendOperationManagerFactory
)
{
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp.Extensions;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Instances;
using Speckle.Converters.AutocadShared.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.DoubleNumerics;
using Speckle.Sdk;
@@ -17,16 +18,19 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
{
private readonly IHostToSpeckleUnitConverter<UnitsValue> _unitsConverter;
private readonly IInstanceObjectsManager<AutocadRootObject, List<Entity>> _instanceObjectsManager;
private readonly IPropertiesExtractor _propertiesExtractor;
private readonly ILogger<AutocadInstanceUnpacker> _logger;
public AutocadInstanceUnpacker(
IHostToSpeckleUnitConverter<UnitsValue> unitsConverter,
IInstanceObjectsManager<AutocadRootObject, List<Entity>> instanceObjectsManager,
IPropertiesExtractor propertiesExtractor,
ILogger<AutocadInstanceUnpacker> logger
)
{
_unitsConverter = unitsConverter;
_instanceObjectsManager = instanceObjectsManager;
_propertiesExtractor = propertiesExtractor;
_logger = logger;
}
@@ -71,6 +75,13 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker<AutocadRootObject>
transform = GetMatrix(instance.BlockTransform.ToArray()),
units = _unitsConverter.ConvertOrThrow(Application.DocumentManager.CurrentDocument.Database.Insunits)
};
var properties = _propertiesExtractor.GetProperties(instance);
if (properties?.Count > 0)
{
instanceProxy["properties"] = properties;
}
_instanceObjectsManager.AddInstanceProxy(instanceId, instanceProxy);
// For each block instance that has the same definition, we need to keep track of the "maximum depth" at which is found.
@@ -7,7 +7,6 @@ using Speckle.Connectors.Common.Extensions;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Dependencies;
using Speckle.Sdk.Models;
@@ -28,7 +27,8 @@ public class AutocadHostObjectBuilder(
IAutocadMaterialBaker materialBaker,
IAutocadColorBaker colorBaker,
AutocadContext autocadContext,
RootObjectUnpacker rootObjectUnpacker
RootObjectUnpacker rootObjectUnpacker,
IReceiveConversionHandler conversionHandler
) : IHostObjectBuilder
{
public Task<HostObjectBuilderResult> Build(
@@ -90,11 +90,11 @@ public class AutocadHostObjectBuilder(
var count = 0;
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
{
string objectId = atomicObject.applicationId ?? atomicObject.id.NotNull();
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
cancellationToken.ThrowIfCancellationRequested();
try
var ex = conversionHandler.TryConvert(() =>
{
cancellationToken.ThrowIfCancellationRequested();
string objectId = atomicObject.applicationId ?? atomicObject.id.NotNull();
IReadOnlyCollection<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix);
applicationIdMap[objectId] = convertedObjects;
@@ -109,8 +109,8 @@ public class AutocadHostObjectBuilder(
);
bakedObjectIds.UnionWith(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
}
catch (Exception ex) when (!ex.IsFatal())
});
if (ex != null)
{
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
}
@@ -60,7 +60,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
)]
public Task<RootObjectBuilderResult> Build(
IReadOnlyList<AutocadRootObject> objects,
SendInfo sendInfo,
string projectId,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
@@ -106,13 +106,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
root.elements.Add(objectCollection);
}
var result = ConvertAutocadEntity(
entity,
applicationId,
objectCollection,
instanceProxies,
sendInfo.ProjectId
);
var result = ConvertAutocadEntity(entity, applicationId, objectCollection, instanceProxies, projectId);
results.Add(result);
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
@@ -17,10 +17,10 @@ namespace Speckle.Connectors.Autocad.Plugin;
public class AutocadCommand
{
private static PaletteSet? PaletteSet { get; set; }
private static readonly Guid s_id = new("3223E594-1B09-4E54-B3DD-8EA0BECE7BA5");
private static readonly Guid s_id = new("7C27DD2B-86E8-4D31-B3DE-B34B267B1DC8");
public ServiceProvider? Container { get; private set; }
private IDisposable? _disposableLogger;
public const string COMMAND_STRING = "SpeckleBeta";
public const string COMMAND_STRING = "Speckle";
[CommandMethod(COMMAND_STRING)]
public void Command()
@@ -31,7 +31,7 @@ public class AutocadCommand
return;
}
PaletteSet = new PaletteSet($"Speckle (Beta)", s_id)
PaletteSet = new PaletteSet($"Speckle", s_id)
{
Size = new Size(400, 500),
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right)
@@ -52,7 +52,7 @@ public class AutocadCommand
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
PaletteSet.AddVisual("Speckle (Beta)", panelWebView);
PaletteSet.AddVisual("Speckle", panelWebView);
FocusPalette();
}
@@ -49,19 +49,19 @@ public class AutocadRibbon
private void Create()
{
RibbonTab tab = FindOrMakeTab("Speckle");
RibbonPanelSource source = new() { Title = "Speckle (Beta)" };
RibbonPanelSource source = new() { Title = "Speckle" };
RibbonPanel panel = new() { Source = source };
tab.Panels.Add(panel);
RibbonToolTip speckleToolTip =
new()
{
Title = "Speckle (Beta)",
Content = $"Next Gen Speckle Connector (Beta) for {AppUtils.App.Name}",
Title = "Speckle",
Content = $"Next Gen Speckle Connector for {AppUtils.App.Name}",
IsHelpEnabled = true // Without this "Press F1 for help" does not appear in the tooltip
};
_ = CreateSpeckleButton("Speckle (Beta)", source, null, speckleToolTip, "logo");
_ = CreateSpeckleButton("Speckle", source, null, speckleToolTip, "logo");
}
private void ComponentManager_ItemInitialized(object? sender, RibbonItemEventArgs e)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 430 B

@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -302,7 +302,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -346,18 +346,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -367,14 +367,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -302,7 +302,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -346,18 +346,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -367,14 +367,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -302,7 +302,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -346,18 +346,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -367,14 +367,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -84,11 +84,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -224,9 +219,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -259,7 +254,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -303,34 +298,33 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -84,11 +84,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -224,9 +219,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -259,7 +254,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -303,34 +298,33 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -1,15 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.Bindings;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converters.Autocad;
using Speckle.Converters.Civil3dShared;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Civil3dShared.Bindings;
@@ -19,27 +17,14 @@ public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
public Civil3dReceiveBinding(
DocumentModelStore store,
IBrowserBridge parent,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
IOperationProgressManager operationProgressManager,
ILogger<AutocadReceiveBinding> logger,
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
IThreadContext threadContext,
IReceiveOperationManagerFactory receiveOperationManagerFactory
)
: base(
store,
parent,
cancellationManager,
serviceProvider,
operationProgressManager,
logger,
speckleApplication,
threadContext
)
: base(parent, cancellationManager, threadContext, receiveOperationManagerFactory)
{
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
@@ -47,7 +32,7 @@ public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
// POC: we're registering the conversion settings for autocad here because we need the autocad conversion settings to be able to use the autocad typed converters.
// POC: We need a separate receive binding for civil3d due to using a different unit converter (needed for conversion settings construction)
protected override void InitializeSettings(IServiceProvider serviceProvider)
protected override void InitializeSettings(IServiceProvider serviceProvider, ModelCard mc)
{
serviceProvider
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
@@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.Bindings;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
@@ -11,7 +10,6 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Converters.Autocad;
using Speckle.Converters.Civil3dShared;
using Speckle.Converters.Common;
using Speckle.Sdk;
namespace Speckle.Connectors.Civil3dShared.Bindings;
@@ -25,30 +23,24 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
ICancellationManager cancellationManager,
IServiceProvider serviceProvider,
ISendConversionCache sendConversionCache,
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler,
IAppIdleManager appIdleManager
IAppIdleManager appIdleManager,
ISendOperationManagerFactory sendOperationManagerFactory
)
: base(
store,
parent,
sendFilters,
cancellationManager,
serviceProvider,
sendConversionCache,
operationProgressManager,
logger,
speckleApplication,
threadContext,
topLevelExceptionHandler,
appIdleManager
appIdleManager,
sendOperationManagerFactory
)
{
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
@@ -1,22 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.CSiShared.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Logging;
namespace Speckle.Connectors.CSiShared.Bindings;
@@ -26,43 +18,28 @@ public sealed class CsiSharedSendBinding : ISendBinding
public SendBindingUICommands Commands { get; }
public IBrowserBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly ICancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<CsiSharedSendBinding> _logger;
private readonly ICsiApplicationService _csiApplicationService;
private readonly ICsiConversionSettingsFactory _csiConversionSettingsFactory;
private readonly ISpeckleApplication _speckleApplication;
private readonly ISdkActivityFactory _activityFactory;
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
public CsiSharedSendBinding(
DocumentModelStore store,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
ICancellationManager cancellationManager,
IOperationProgressManager operationProgressManager,
ILogger<CsiSharedSendBinding> logger,
ICsiConversionSettingsFactory csiConversionSettingsFactory,
ISpeckleApplication speckleApplication,
ISdkActivityFactory activityFactory,
ICsiApplicationService csiApplicationService
ICsiApplicationService csiApplicationService,
ISendOperationManagerFactory sendOperationManagerFactory
)
{
_store = store;
_serviceProvider = serviceProvider;
_sendFilters = sendFilters.ToList();
_cancellationManager = cancellationManager;
_operationProgressManager = operationProgressManager;
_logger = logger;
Parent = parent;
Commands = new SendBindingUICommands(parent);
_csiConversionSettingsFactory = csiConversionSettingsFactory;
_speckleApplication = speckleApplication;
_activityFactory = activityFactory;
_csiApplicationService = csiApplicationService;
_sendOperationManagerFactory = sendOperationManagerFactory;
}
public List<ISendFilter> GetSendFilters() => _sendFilters;
@@ -71,52 +48,15 @@ public sealed class CsiSharedSendBinding : ISendBinding
public async Task Send(string modelCardId)
{
using var activity = _activityFactory.Start();
try
{
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
{
throw new InvalidOperationException("No publish model card was found.");
}
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
.Initialize(_csiConversionSettingsFactory.Create(_csiApplicationService.SapModel));
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
List<ICsiWrapper> wrappers = modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(DecodeObjectIdentifier)
.ToList();
if (wrappers.Count == 0)
{
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
var sendResult = await scope
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
.Execute(
wrappers,
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.VersionId, sendResult.ConversionResults);
}
catch (OperationCanceledException)
{
return;
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogModelCardHandledError(ex);
await Commands.SetModelError(modelCardId, ex);
}
using var manager = _sendOperationManagerFactory.Create();
await manager.Process(
Commands,
modelCardId,
(sp, _) =>
sp.GetRequiredService<IConverterSettingsStore<CsiConversionSettings>>()
.Initialize(_csiConversionSettingsFactory.Create(_csiApplicationService.SapModel)),
card => card.SendFilter.NotNull().RefreshObjectIds().Select(DecodeObjectIdentifier).ToList()
);
}
private ICsiWrapper DecodeObjectIdentifier(string encodedId)
@@ -5,7 +5,7 @@ using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
using Speckle.Sdk;
using Speckle.Sdk.Helpers;
using Speckle.Sdk.Common;
using Speckle.Sdk.Logging;
using Timer = System.Timers.Timer;
@@ -82,7 +82,7 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
{
try
{
ModelPathHash = Crypt.Md5(_csiApplicationService.SapModel.GetModelFilename(), length: 32);
ModelPathHash = Md5.GetString(_csiApplicationService.SapModel.GetModelFilename());
HostAppUserDataPath = Path.Combine(
SpecklePathProvider.UserSpeckleFolderPath,
"ConnectorsFileData",
@@ -70,7 +70,7 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
/// </remarks>
public async Task<RootObjectBuilderResult> Build(
IReadOnlyList<ICsiWrapper> csiObjects,
SendInfo sendInfo,
string projectId,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
@@ -22,7 +22,7 @@ public abstract class SpeckleFormBase : Form, ICsiApplicationService
protected SpeckleFormBase()
{
Text = "Speckle (Beta)";
Text = "Speckle";
Size = new System.Drawing.Size(400, 600);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 KiB

After

Width:  |  Height:  |  Size: 352 KiB

@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.etabs21": {
@@ -335,18 +335,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -356,14 +356,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -75,11 +75,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -215,9 +210,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -241,7 +236,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.etabs22": {
@@ -291,34 +286,33 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -21,7 +21,7 @@
</ItemGroup>
<Target Name="PostBuild" AfterTargets="Build">
<Target Name="PostBuild" AfterTargets="Build" Condition="'$(NavisworksVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<Message Text="Navisworks Version $(NavisworksVersion)" Importance="high"/>
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2020": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2021": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2022": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2023": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -285,7 +285,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2024": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -265,9 +265,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -291,7 +291,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2025": {
@@ -337,18 +337,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -358,14 +358,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -266,9 +266,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -292,7 +292,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.navisworks2026": {
@@ -339,18 +339,18 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -360,14 +360,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -1,5 +1,4 @@
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;
@@ -9,16 +8,13 @@ using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Logging;
namespace Speckle.Connector.Navisworks.Bindings;
@@ -30,45 +26,33 @@ public class NavisworksSendBinding : ISendBinding
public SendBindingUICommands Commands { get; }
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly ICancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<NavisworksSendBinding> _logger;
private readonly ISpeckleApplication _speckleApplication;
private readonly ISdkActivityFactory _activityFactory;
private readonly INavisworksConversionSettingsFactory _conversionSettingsFactory;
private readonly ToSpeckleSettingsManagerNavisworks _toSpeckleSettingsManagerNavisworks;
private readonly IElementSelectionService _selectionService;
private readonly IThreadContext _threadContext;
private readonly ISendOperationManagerFactory _sendOperationManagerFactory;
public NavisworksSendBinding(
DocumentModelStore store,
IBrowserBridge parent,
IServiceProvider serviceProvider,
ICancellationManager cancellationManager,
IOperationProgressManager operationProgressManager,
ILogger<NavisworksSendBinding> logger,
ISpeckleApplication speckleApplication,
ISdkActivityFactory activityFactory,
INavisworksConversionSettingsFactory conversionSettingsFactory,
ToSpeckleSettingsManagerNavisworks toSpeckleSettingsManagerNavisworks,
IElementSelectionService selectionService,
IThreadContext threadContext
IThreadContext threadContext,
ISendOperationManagerFactory sendOperationManagerFactory
)
{
Parent = parent;
Commands = new SendBindingUICommands(parent);
_store = store;
_serviceProvider = serviceProvider;
_cancellationManager = cancellationManager;
_operationProgressManager = operationProgressManager;
_logger = logger;
_speckleApplication = speckleApplication;
_activityFactory = activityFactory;
_conversionSettingsFactory = conversionSettingsFactory;
_toSpeckleSettingsManagerNavisworks = toSpeckleSettingsManagerNavisworks;
_selectionService = selectionService;
_threadContext = threadContext;
_sendOperationManagerFactory = sendOperationManagerFactory;
SubscribeToNavisworksEvents();
}
@@ -78,7 +62,8 @@ public class NavisworksSendBinding : ISendBinding
public List<ISendFilter> GetSendFilters() =>
[
new NavisworksSelectionFilter() { IsDefault = true },
new NavisworksSavedSetsFilter(new ElementSelectionService())
new NavisworksSavedSetsFilter(new ElementSelectionService()),
new NavisworksSavedViewsFilter(new ElementSelectionService())
];
public List<ICardSetting> GetSendSettings() =>
@@ -95,60 +80,13 @@ public class NavisworksSendBinding : ISendBinding
private async Task SendInternal(string modelCardId)
{
using var activity = _activityFactory.Start();
try
{
var modelCard = GetModelCard(modelCardId);
using var scope = _serviceProvider.CreateScope();
InitializeConverterSettings(scope, modelCard);
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
var progress = _operationProgressManager.CreateOperationProgressEventHandler(
Parent,
modelCard.ModelCardId.NotNull(),
cancellationItem.Token
);
var navisworksModelItems = await GetNavisworksModelItems(modelCard, progress);
var sendResult = await ExecuteSendOperation(
scope,
modelCard,
navisworksModelItems,
progress,
cancellationItem.Token
);
await Commands.SetModelSendResult(modelCardId, sendResult.VersionId, sendResult.ConversionResults);
}
catch (OperationCanceledException)
{
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
}
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
{
// 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);
}
using var manager = _sendOperationManagerFactory.Create();
await manager.Process(Commands, modelCardId, InitializeConverterSettings, GetNavisworksModelItems);
}
private SenderModelCard GetModelCard(string modelCardId) =>
_store.GetModelById(modelCardId) as SenderModelCard
?? throw new InvalidOperationException("No publish model card was found.");
private void InitializeConverterSettings(IServiceScope scope, SenderModelCard modelCard) =>
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<NavisworksConversionSettings>>()
private void InitializeConverterSettings(IServiceProvider serviceProvider, SenderModelCard modelCard) =>
serviceProvider
.GetRequiredService<IConverterSettingsStore<NavisworksConversionSettings>>()
.Initialize(
_conversionSettingsFactory.Create(
originMode: _toSpeckleSettingsManagerNavisworks.GetOriginMode(modelCard),
@@ -159,7 +97,7 @@ public class NavisworksSendBinding : ISendBinding
)
);
private async Task<List<NAV.ModelItem>> GetNavisworksModelItems(
private async Task<IReadOnlyList<NAV.ModelItem>> GetNavisworksModelItems(
SenderModelCard modelCard,
IProgress<CardProgress> onOperationProgressed
)
@@ -191,22 +129,6 @@ public class NavisworksSendBinding : ISendBinding
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.ApplicationAndVersion),
onOperationProgressed,
token
);
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
/// <summary>
@@ -68,6 +68,7 @@ public static class NavisworksConnectorServiceRegistration
// register filters
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedViewsFilter>();
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
}
}
@@ -2,7 +2,6 @@
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Utils;
using Speckle.Converter.Navisworks.Constants;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
@@ -85,12 +84,14 @@ public class NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
{
List<NAV.SelectionSet> savedSetRecords = [];
CollectSavedSets(NavisworksApp.ActiveDocument.SelectionSets.RootItem, savedSetRecords);
var root = NavisworksApp.ActiveDocument.SelectionSets.RootItem;
CollectSavedSets(root, savedSetRecords);
Items = savedSetRecords
.Select(setRecord =>
{
string hierarchicalName = BuildHierarchicalName(setRecord);
string hierarchicalName = SavedItemHelpers.BuildHierarchicalName(setRecord, root);
return new SendFilterSelectItem(setRecord.Guid.ToString(), hierarchicalName);
})
.ToList();
@@ -103,7 +104,7 @@ public class NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
return;
}
foreach (NAV.SavedItem item in ((NAV.FolderItem)parentItem).Children)
foreach (NAV.SavedItem item in ((NAV.GroupItem)parentItem).Children)
{
if (item.IsGroup)
{
@@ -115,18 +116,4 @@ public class NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
}
}
}
private static string BuildHierarchicalName(NAV.SavedItem item)
{
var pathParts = new List<string> { item.DisplayName };
var current = item.Parent;
while (current != null && current != NavisworksApp.ActiveDocument.SelectionSets.RootItem)
{
pathParts.Insert(0, current.DisplayName);
current = current.Parent;
}
return string.Join(PathConstants.SET_SEPARATOR, pathParts);
}
}
@@ -0,0 +1,173 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Utils;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
public class NavisworksSavedViewsFilter : DiscriminatedObject, ISendFilterSelect
{
private readonly IElementSelectionService _selectionService;
public NavisworksSavedViewsFilter(IElementSelectionService selectionService)
{
_selectionService = selectionService;
Items = [];
SelectedItems = [];
GetSavedViews();
}
public string Id { get; set; } = "navisworksSavedViews";
public string Name { get; set; } = "Saved Views";
public string Type { get; set; } = "Select";
public string? Summary { get; set; }
public bool IsDefault { get; set; }
public List<string> SelectedObjectIds { get; set; } = [];
public Dictionary<string, string>? IdMap { get; set; }
public bool IsMultiSelectable { get; set; }
public List<SendFilterSelectItem> SelectedItems { get; set; }
public List<SendFilterSelectItem> Items { get; set; }
public List<string> RefreshObjectIds()
{
List<string> objectIds = [];
if (SelectedItems.Count == 0)
{
return objectIds;
}
var savedViews = NavisworksApp.ActiveDocument.SavedViewpoints;
foreach (var savedViewItem in SelectedItems.Select(item => ResolveSavedView(item.Id)))
{
// Get the visible elements in the saved view.
objectIds.AddRange(ResolvedSavedViewObjects(savedViewItem));
}
return objectIds;
}
private static NAV.SavedViewpoint ResolveSavedView(string savedViewReference)
{
if (Guid.TryParse(savedViewReference, out var guid))
{
// Even though we may have already got a match, that could be to a generic Guid from earlier versions of Navisworks
if (savedViewReference != Guid.Empty.ToString())
{
return (NAV.SavedViewpoint)NavisworksApp.ActiveDocument.SavedViewpoints.ResolveGuid(guid);
}
}
var savedRef = new NAV.SavedItemReference("LcOpSavedViewsElement", savedViewReference);
var resolvedReference = NavisworksApp.ActiveDocument.ResolveReference(savedRef) as NAV.SavedViewpoint;
return resolvedReference
?? throw new SpeckleSendFilterException($"Saved view with reference {savedViewReference} not found.");
}
private IEnumerable<string> ResolvedSavedViewObjects(NAV.SavedViewpoint savedView)
{
var objectIds = new List<string>();
// THIS IS COMMENTED OUT AS IT IS LEGACY DEFENSIVE BEHAVIOUR - DISCUSSION REQUIRED
// if (!savedView.ContainsVisibilityOverrides)
// {
// // We check this again as the view settings may have changed in the saved card.
// // If the saved view does not contain visibility overrides, this is effectively everything in the model.
// // This will need to be the documented behaviour.
// throw new SpeckleSendFilterException(
// "Saved view does not contain visibility overrides. This would effectively publish everything in the model."
// );
// }
NavisworksApp.ActiveDocument.SavedViewpoints.CurrentSavedViewpoint = savedView;
var models = NavisworksApp.ActiveDocument.Models;
NavisworksApp.ActiveDocument.CurrentSelection.Clear();
foreach (var model in models)
{
var rootItem = model.RootItem;
if (!_selectionService.IsVisible(rootItem))
{
// If the root item is hidden, we skip it and its descendants.
continue;
}
objectIds.AddRange(
rootItem.Descendants.Where(_selectionService.IsVisible).Select(_selectionService.GetModelItemPath).ToList()
);
}
return objectIds;
}
/// <summary>
/// Since it is called from constructor, it is re-called whenever UI calls SendBinding.GetSendFilters() on SendFilter dialog.
/// 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.
/// </summary>
private void GetSavedViews()
{
List<NAV.SavedViewpoint> savedViewRecords = [];
var root = NavisworksApp.ActiveDocument.SavedViewpoints.RootItem;
CollectSavedViews(root, savedViewRecords);
Items = savedViewRecords
.Select(viewRecord =>
{
var reference = NavisworksApp.ActiveDocument.SavedViewpoints.CreateReference(viewRecord);
// If the guid is effectively empty, we can use the saved view's name as a fallback
var selectItemId =
viewRecord.Guid.ToString() == Guid.Empty.ToString() ? reference.SavedItemId : viewRecord.Guid.ToString();
string hierarchicalName = SavedItemHelpers.BuildHierarchicalName(viewRecord, root);
return new SendFilterSelectItem(selectItemId, hierarchicalName);
})
.ToList();
}
private static void CollectSavedViews(NAV.SavedItem parentItem, List<NAV.SavedViewpoint> collectedSets)
{
if (!parentItem.IsGroup)
{
return;
}
foreach (NAV.SavedItem item in ((NAV.GroupItem)parentItem).Children)
{
switch (item)
{
// case NAV.SavedViewpoint { ContainsVisibilityOverrides: false }:
// Legacy defensive behaviour: skip viewpoints without visibility overrides.
// Essentially, send everything, or whatever the current view state for hidden elements is.
// break;
case NAV.SavedViewpointAnimationCut:
// Skip animation cuts.
break;
case NAV.SavedViewpoint savedViewpoint:
collectedSets.Add(savedViewpoint);
break;
case NAV.GroupItem groupItem when groupItem.Children.Count > 0:
CollectSavedViews(groupItem, collectedSets);
break;
// No action for empty groups or unknown types.
}
}
}
}
@@ -0,0 +1,20 @@
using Speckle.Converter.Navisworks.Constants;
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
public static class SavedItemHelpers
{
internal static string BuildHierarchicalName(NAV.SavedItem item, NAV.FolderItem? root)
{
var pathParts = new List<string> { item.DisplayName };
var current = item.Parent;
while (current != null && current != root)
{
pathParts.Insert(0, current.DisplayName);
current = current.Parent;
}
return string.Join(PathConstants.SET_SEPARATOR, pathParts);
}
}
@@ -32,18 +32,9 @@ public class NavisworksRootObjectBuilder(
internal NavisworksConversionSettings GetCurrentSettings() => converterSettings.Current;
/// <summary>
/// Asynchronously builds a Speckle object hierarchy from Navisworks model items.
/// </summary>
/// <param name="navisworksModelItems">The list of Navisworks items to convert.</param>
/// <param name="sendInfo">Information about the send operation.</param>
/// <param name="onOperationProgressed">Progress reporting callback.</param>
/// <param name="cancellationToken">Token to cancel the operation.</param>
/// <returns>A result containing the root collection and conversion results.</returns>
/// <exception cref="SpeckleException">Thrown when no objects can be converted.</exception>
public async Task<RootObjectBuilderResult> Build(
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
SendInfo sendInfo,
string projectId,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
@@ -54,7 +45,7 @@ public class NavisworksRootObjectBuilder(
#endif
using var activity = activityFactory.Start("Build");
ValidateInputs(navisworksModelItems, sendInfo, onOperationProgressed);
ValidateInputs(navisworksModelItems, projectId, onOperationProgressed);
// 2. Initialize root collection
var rootCollection = InitializeRootCollection();
@@ -62,7 +53,7 @@ public class NavisworksRootObjectBuilder(
// 3. Convert all model items and store results
var (convertedElements, conversionResults) = await ConvertModelItemsAsync(
navisworksModelItems,
sendInfo,
projectId,
onOperationProgressed,
cancellationToken
);
@@ -80,7 +71,7 @@ public class NavisworksRootObjectBuilder(
private static void ValidateInputs(
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
SendInfo sendInfo,
string projectId,
IProgress<CardProgress> onOperationProgressed
)
{
@@ -94,9 +85,11 @@ public class NavisworksRootObjectBuilder(
throw new ArgumentNullException(nameof(navisworksModelItems));
}
if (onOperationProgressed == null || sendInfo == null)
if (onOperationProgressed == null || projectId == null)
{
throw new ArgumentNullException(onOperationProgressed == null ? nameof(onOperationProgressed) : nameof(sendInfo));
throw new ArgumentNullException(
onOperationProgressed == null ? nameof(onOperationProgressed) : nameof(projectId)
);
}
}
@@ -109,7 +102,7 @@ public class NavisworksRootObjectBuilder(
private Task<(Dictionary<string, Base?> converted, List<SendConversionResult> results)> ConvertModelItemsAsync(
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
SendInfo sendInfo,
string projectId,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
@@ -122,7 +115,7 @@ public class NavisworksRootObjectBuilder(
foreach (var item in navisworksModelItems)
{
cancellationToken.ThrowIfCancellationRequested();
var converted = ConvertNavisworksItem(item, convertedBases, sendInfo);
var converted = ConvertNavisworksItem(item, convertedBases, projectId);
results.Add(converted);
processedCount++;
onOperationProgressed.Report(new CardProgress("Converting", (double)processedCount / totalCount));
@@ -310,7 +303,7 @@ public class NavisworksRootObjectBuilder(
private SendConversionResult ConvertNavisworksItem(
NAV.ModelItem navisworksItem,
Dictionary<string, Base?> convertedBases,
SendInfo sendInfo
string projectId
)
{
string applicationId = elementSelectionService.GetModelItemPath(navisworksItem);
@@ -318,7 +311,7 @@ public class NavisworksRootObjectBuilder(
try
{
Base converted = sendConversionCache.TryGetValue(applicationId, sendInfo.ProjectId, out ObjectReference? cached)
Base converted = sendConversionCache.TryGetValue(applicationId, projectId, out ObjectReference? cached)
? cached
: rootToSpeckleConverter.Convert(navisworksItem);
@@ -63,23 +63,19 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
throw new ArgumentNullException(nameof(modelCard));
}
var originString = modelCard.Settings?.First(s => s.Id == "originMode").Value as string;
if (originString is not null && OriginModeSetting.OriginModeMap.TryGetValue(originString, out OriginMode origin))
var originString = modelCard.Settings?.FirstOrDefault(s => s.Id == "originMode")?.Value as string;
if (!OriginModeSetting.OriginModeMap.TryGetValue(originString ?? string.Empty, out var origin))
{
if (_originModeCache.TryGetValue(modelCard.ModelCardId.NotNull(), out OriginMode previousType))
{
if (previousType != origin)
{
EvictCacheForModelCard(modelCard);
}
}
_originModeCache[modelCard.ModelCardId.NotNull()] = origin;
return origin;
return OriginMode.ModelOrigin; // Default to ModelOrigin if not specified or invalid
}
throw new ArgumentException($"Invalid origin mode value: {originString}");
if (_originModeCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousType) && previousType != origin)
{
EvictCacheForModelCard(modelCard);
}
_originModeCache[modelCard.ModelCardId.NotNull()] = origin;
return origin;
}
public bool GetConvertHiddenElements(SenderModelCard modelCard)
@@ -20,7 +20,7 @@ namespace Speckle.Connector.Navisworks.Plugin;
DisplayName = SpeckleV3Tool.DISPLAY_NAME,
Options = NAV.Plugins.PluginOptions.None,
ToolTip = "Speckle Connector for Navisworks",
ExtendedToolTip = "Next Gen Speckle Connector (Beta) for Navisworks"
ExtendedToolTip = "Next Gen Speckle Connector for Navisworks"
)
]
[SuppressMessage(
@@ -4,7 +4,7 @@ $utf8
DisplayName=Speckle
Speckle.DisplayName=Speckle
SpeckleV3.Title=Speckle (Beta)
SpeckleV2.Title=Speckle
Speckle_Launch.DisplayName=Speckle (Beta)
Speckle_Launch_V2.DisplayName=Speckle
SpeckleV3.Title=Speckle
SpeckleV2.Title=Speckle (Legacy)
Speckle_Launch.DisplayName=Speckle
Speckle_Launch_V2.DisplayName=Speckle (Legacy)
@@ -8,7 +8,7 @@ public static class SpeckleV3Tool
public const string COMMAND = "Speckle_Launch";
public const string PLUGIN = "SpeckleUI3";
public const string PLUGIN_ID = "SpeckleNavisworksNextGen";
public const string DISPLAY_NAME = "Speckle (Beta)";
public const string DISPLAY_NAME = "Speckle";
public const string RIBBON_TAB_ID = "Speckle";
public const string RIBBON_TAB_DISPLAY_NAME = "Speckle";
public const string RIBBON_STRINGS = "NavisworksRibbon.name";
Binary file not shown.

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 864 B

@@ -20,6 +20,8 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksDocumentModelStore.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksMaterialUnpacker.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSavedViewsFilter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\SavedItemHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\GeometryNodeMerger.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksHierarchyBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksRootObjectBuilder.cs"/>
+2 -2
View File
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Target AfterTargets="Clean" Name="CleanAddinsRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Clean" Name="CleanAddinsRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<RemoveDir Directories="$(TargetDir);$(ProjectDir)\..\Release\Release$(RevitVersion);$(AppData)\Autodesk\Revit\Addins\$(RevitVersion)\Speckle.Connectors.Revit$(RevitVersion);" />
<Delete Files="$(AppData)\Autodesk\Revit\Addins\$(RevitVersion)\Speckle.Connectors.Revit$(RevitVersion).addin" />
</Target>
<Target AfterTargets="Build" Name="AfterBuildRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Build" Name="AfterBuildRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<ItemGroup>
<RevitDLLs Include="$(TargetDir)\**\*.*" Exclude="$(TargetDir)*.addin" />
<SourceManifest Include="$(TargetDir)\Plugin\Speckle.Connectors.Revit$(RevitVersion).addin" />
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Application">
<Name>Speckle (Beta) for Revit</Name>
<Description>Speckle (Beta) for Revit</Description>
<Name>Speckle for Revit</Name>
<Description>Speckle for Revit</Description>
<Assembly>Speckle.Connectors.Revit2022\Speckle.Connectors.Revit2022.dll</Assembly>
<FullClassName>Speckle.Connectors.Revit.Plugin.RevitExternalApplication</FullClassName>
<ClientId>27ccff2c-011c-4374-bb79-b93990d0c86a</ClientId>
@@ -281,9 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -306,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.revit2022": {
@@ -351,11 +351,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Revit.API": {
@@ -366,9 +366,9 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -378,14 +378,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Application">
<Name>Speckle (Beta) for Revit</Name>
<Description>Speckle (Beta) for Revit</Description>
<Name>Speckle for Revit</Name>
<Description>Speckle for Revit</Description>
<Assembly>Speckle.Connectors.Revit2023\Speckle.Connectors.Revit2023.dll</Assembly>
<FullClassName>Speckle.Connectors.Revit.Plugin.RevitExternalApplication</FullClassName>
<ClientId>27ccff2c-011c-4374-bb79-b93990d0c86a</ClientId>
@@ -281,9 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -306,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.revit2023": {
@@ -351,11 +351,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Revit.API": {
@@ -366,9 +366,9 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -378,14 +378,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Application">
<Name>Speckle (Beta) for Revit</Name>
<Description>Speckle (Beta) for Revit</Description>
<Name>Speckle for Revit</Name>
<Description>Speckle for Revit</Description>
<Assembly>Speckle.Connectors.Revit2024\Speckle.Connectors.Revit2024.dll</Assembly>
<FullClassName>Speckle.Connectors.Revit.Plugin.RevitExternalApplication</FullClassName>
<ClientId>27ccff2c-011c-4374-bb79-b93990d0c86a</ClientId>
@@ -281,9 +281,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -306,7 +306,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.revit2024": {
@@ -351,11 +351,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Revit.API": {
@@ -366,9 +366,9 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
@@ -378,14 +378,14 @@
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
}
}
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Application">
<Name>Speckle (Beta) for Revit</Name>
<Description>Speckle (Beta) for Revit</Description>
<Name>Speckle for Revit</Name>
<Description>Speckle for Revit</Description>
<Assembly>Speckle.Connectors.Revit2025\Speckle.Connectors.Revit2025.dll</Assembly>
<FullClassName>Speckle.Connectors.Revit.Plugin.RevitExternalApplication</FullClassName>
<ClientId>27ccff2c-011c-4374-bb79-b93990d0c86a</ClientId>
@@ -91,11 +91,6 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
@@ -231,9 +226,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.3.5, )",
"Speckle.Sdk": "[3.3.5, )",
"Speckle.Sdk.Dependencies": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )",
"Speckle.Sdk": "[3.4.5, )",
"Speckle.Sdk.Dependencies": "[3.4.5, )"
}
},
"speckle.connectors.dui": {
@@ -256,7 +251,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.3.5, )"
"Speckle.Objects": "[3.4.5, )"
}
},
"speckle.converters.revit2025": {
@@ -301,11 +296,11 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "VPbYI8TyPDlKlNUHPLPAL1HveN9649LKVxw8opgGypoqq0MC5I7WxQjDcuB8xKnQ1PCSO8suu4hEJgdyPcEvWg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "WMDYkTxoSbzh2WzuubMUKx37M6f7D/k/xOOV50oB9bQA0TiUAVcCFKAW0VHZZF4OhjBBxV8N2FM2yr2oaNc/Ww==",
"dependencies": {
"Speckle.Sdk": "3.3.5"
"Speckle.Sdk": "3.4.5"
}
},
"Speckle.Revit.API": {
@@ -316,25 +311,24 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "7r8CmugwinniEF6v0N0bWuC+xpJaRfa/EnEjzj8NLpFG1b3uAjOxteGlQgR+evVacxTCEsuNkio7Mdv97odgpg==",
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "w6vfOyckHVWqOqDjBO+PmVT5LeYu8voMMypOpa+w/2LrgMH6CxkCMYYjyOK8/rb3Ss989f2EjkpksQ3lcHPN/Q==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.3.5"
"Speckle.Sdk.Dependencies": "3.4.5"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.3.5, )",
"resolved": "3.3.5",
"contentHash": "RukqLb0lVNgtmhKPeZJCncibnyutQ6Dr6+UQCa4PjWinIXpSm3A3ywK9ISkU+5StW1QoejiR7kc9a6qmiLys6w=="
"requested": "[3.4.5, )",
"resolved": "3.4.5",
"contentHash": "8X9Qpksyp2MDb/G2Du7OFehdCtt0A0AclMKUFNsDSot5h8fTrvT620kW64ycm4l+PKXsPvCKDspOiGi4+9HrMQ=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -50,7 +50,7 @@ internal sealed class RevitWebViewPlugin(
var dui3Button = (PushButton)
specklePanel.AddItem(
new PushButtonData(
"Speckle (Beta) for Revit",
"Speckle for Revit",
Connector.TabTitle,
typeof(RevitExternalApplication).Assembly.Location,
typeof(SpeckleRevitCommand).FullName
@@ -70,7 +70,7 @@ internal sealed class RevitWebViewPlugin(
$"Speckle.Connectors.Revit{speckleApplication.HostApplicationVersion}.Assets.logo32.png",
path
);
dui3Button.ToolTip = "Speckle (Beta) for Revit";
dui3Button.ToolTip = "Speckle for Revit";
//dui3Button.AvailabilityClassName = typeof(CmdAvailabilityViews).FullName;
dui3Button.SetContextualHelp(new ContextualHelp(ContextualHelpType.Url, "https://speckle.systems"));
}

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