Compare commits

...

53 Commits

Author SHA1 Message Date
Oğuzhan Koral deb2d7fd37 Merge pull request #633 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 to release
2025-02-27 14:10:33 +03:00
Jedd Morgan 3ff40757e0 Corrected tekla structures slug (#632) 2025-02-27 10:52:55 +00:00
Claire Kuang a8571fdd61 detaches featurelines so they are queryable (#627) 2025-02-27 13:41:59 +03:00
Jedd Morgan 345a555eba Merge pull request #630 from specklesystems/dev
Release to test Tekla
2025-02-26 18:30:57 +00:00
Oğuzhan Koral f8a6d27c6d revert revit task back for highlight view (#629) 2025-02-26 18:29:56 +00:00
Dogukan Karatas 4e1604f77e updates after build (#628) 2025-02-26 18:17:44 +00:00
Adam Hathcock 00af4ad338 fix: Use a concurrent dictionary to cache types since the converter is effectively a singleton (#624)
* Use a concurrent dictionary to cache types since the converter is effectively a singleton

* Don't modify the collection in the getter

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-26 20:34:06 +03:00
Jedd Morgan 85b6468939 Merge pull request #626 from specklesystems/dev
Retrigger test release
2025-02-26 15:28:43 +00:00
Jonathon Broughton 7fed9e03e9 enhancement(Navisworks): CNX-972 - less aggressive object merging (#622)
* Remove unused path constants and update namespace

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

* Remove unused send filters

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

* Update Navisworks object creation logic

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

* Add path cleaning method and simplify geometry resolution

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

* Improve geometry node grouping logic

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

* Added an extendable signature generation pattern

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

* Update material separator in path constants

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

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

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

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

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

* Add missing import for Navisworks constants

Included the Navisworks constants import to ensure proper functionality.

* Replaced custom hash function with MD5, suppressing related warnings.
2025-02-26 14:25:09 +00:00
Jedd Morgan c55db8e275 Merge pull request #625 from specklesystems/dev
Test release to test new installers
2025-02-26 11:51:29 +00:00
KatKatKateryna e9c2c85a7f Arcgis detailed progress and cancellation (#614)
* pass cancellation token to individual features

* move count to a separate function

* remove per-layer progress report

* fix count

* reorder

* count layers only once

* move count to "unpacking selection" activityFactory

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

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

* Add Navisworks hierarchy builder class

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

* Refactor hierarchy handling in object builder

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

* Refactor model item conversion logic

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

* Refactor hierarchy builder for cleaner conversion

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

* Remove unnecessary comment in hierarchy builder

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

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

* add comments

* Add fatch when

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-25 16:54:10 +03:00
Jedd Morgan 641c36e9a8 Merge pull request #620 from specklesystems/dev
Test release again
2025-02-25 13:34:39 +00:00
Oğuzhan Koral a3f7069c37 Feat(navis): send filter dropdown navis poc (#619)
* Add Saved Sets Filter

* formatting

* !!!

* fml

* Unclear why formatting rules are not being applied

* !!!

* !

* fixed?

* Add new filter for saved sets in Navisworks

- Included a new file for NavisworksSavedSetsFilter.

* POC ISendFilterSelect

* Align saved sets filtler with ISendFilterSelect

* No DI for send filters

* reverse condition

* Remove ISendFilterSelect from revit views

* Add notes

* Improve object selection error handling

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

---------

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

* updates speckle.svg

* updates logo

---------

Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-02-25 08:14:17 +01:00
Jedd Morgan c859a0c44d Merge pull request #618 from specklesystems/dev
Test release of desktop services and installers
2025-02-24 17:43:26 +00:00
Claire Kuang 4ae2106608 fixes pointcloud plane bug (#615) 2025-02-21 17:30:25 +00:00
Claire Kuang 3656587081 fix(autocad/Rhino): add support for receiving any convertible geometry in dataobject display values (#599)
* adds additional geometry conversions to autocad and rhino

* removes unused converters

* fixes zip bug

---------

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

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

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

* Update Speckle.Converters.RevitShared.projitems

* removes top level pointcloud converter

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

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

* Add property retrieval method to handler

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

* Fix namespace formatting and improve property handling

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

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

* Refactor property handling in base class

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

* Add hierarchical property retrieval method

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

* Fix namespace formatting issues

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

* Refactor model item conversion logic

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

* Refactor model item conversion logic

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

* Refactor geometry property handling

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

* Refactor conversion method for brevity

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

* Fix import statement formatting

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

* Add class properties handling to property dictionaries

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

* Refactor property handling methods

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

* Add ClassPropertiesExtractor to service registration

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

* Refactor HierarchicalPropertyHandler for clarity

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

* Refactor property assignment methods

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

* Refactor ClassPropertiesExtractor to instance method

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

* updates csproj

---------

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

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

* Update ClassPropertiesExtractor.cs

* some bug fixes

* Update PartDataExtractor.cs

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

* update to SDK 267

* adjust ifc tester

* Update to SDK 268

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

* reverted LibraryImport as it would need more testing

* IFC app ids
2025-02-17 16:35:26 +00:00
Björn Steinhagen 6d4e12dfae Merge pull request #591 from specklesystems/dev
test(etabs): bundled installer with ini file magic
2025-02-17 13:52:57 +01:00
Björn Steinhagen f882b0f5bd fix(etabs): ensure csi operations run on main thread to prevent etabs exceptions (#589)
* fix: ensure operations run on main thread to prevent etabsexceptions

* pr comments

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

* refactor: mixed concerns

Some structural asset stuff was in the MaterialQuantitiesToSpeckle.cs

---------

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

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

* removes number from room since this is included in params

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

* stupid typos

---------

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

* more QueuedTask usage and format

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

* fix: applies the minimal fix

* chore: adds comment for future

---------

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

* feature: frame length extraction

* feat: shell area extraction

* feat: frame length extraction

* feat: shell area extraction

* docs: cleaned up object extractors

* refactor: extensible database table extraction

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

* refactor: using DatabaseTableExtractor for material name lookup

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

* fix: openings shouldn't look for material assignments

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

* refactor: database table extractor handles dictionary lookups
2025-02-12 18:43:44 +00:00
Dimitrie Stefanescu 5c2c0ff303 Merge pull request #582 from specklesystems/dimitrie/cnx-1239-rhino-fix-the-documentisinit-post-copy-paste
Rhino: fixes change detection post copy paste events
2025-02-12 15:00:32 +00:00
Dimitrie Stefanescu a6fd4547ea feat: adds previous dix 2025-02-12 14:38:47 +00:00
Adam Hathcock 0d27eadfeb add deep clean local docs (#579) 2025-02-11 14:06:12 +00:00
207 changed files with 4995 additions and 3401 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ public static class Consts
]
),
new(
"tekla-structures",
"teklastructures",
[
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
@@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Microsoft.Extensions.DependencyInjection;
@@ -45,6 +46,7 @@ public sealed class ArcGISSendBinding : ISendBinding
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:
@@ -70,6 +72,7 @@ public sealed class ArcGISSendBinding : ISendBinding
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
MapMembersUtils mapMemberUtils,
IThreadContext threadContext,
ISpeckleApplication speckleApplication,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
@@ -84,6 +87,7 @@ public sealed class ArcGISSendBinding : ISendBinding
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
_mapMemberUtils = mapMemberUtils;
_threadContext = threadContext;
_speckleApplication = speckleApplication;
Parent = parent;
Commands = new SendBindingUICommands(parent);
@@ -101,7 +105,7 @@ public sealed class ArcGISSendBinding : ISendBinding
LayersRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForLayersRemovedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
),
true
);
@@ -109,7 +113,7 @@ public sealed class ArcGISSendBinding : ISendBinding
StandaloneTablesRemovedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
),
true
);
@@ -117,7 +121,7 @@ public sealed class ArcGISSendBinding : ISendBinding
MapPropertyChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapPropertyChangedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
),
true
); // Map units, CRS etc.
@@ -125,8 +129,7 @@ public sealed class ArcGISSendBinding : ISendBinding
MapMemberPropertiesChangedEvent.Subscribe(
a =>
_topLevelExceptionHandler.FireAndForget(
async () =>
await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
),
true
); // e.g. Layer name
@@ -135,7 +138,7 @@ public sealed class ArcGISSendBinding : ISendBinding
_ =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await _threadContext.RunOnWorker(SubscribeToMapMembersDataSourceChange);
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
}),
true
);
@@ -376,21 +379,25 @@ public sealed class ArcGISSendBinding : ISendBinding
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
using var scope = _serviceProvider.CreateScope();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
List<MapMember> mapMembers = modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
.Where(obj => obj != null)
.ToList();
List<MapMember> mapMembers = await QueuedTask.Run(() =>
{
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
.Initialize(
_arcGISConversionSettingsFactory.Create(
Project.Current,
MapView.Active.Map,
new CRSoffsetRotation(MapView.Active.Map)
)
);
return modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
.Where(obj => obj != null)
.ToList();
});
if (mapMembers.Count == 0)
{
@@ -398,24 +405,27 @@ public sealed class ArcGISSendBinding : ISendBinding
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
// subscribe to the selected layer events
foreach (MapMember mapMember in mapMembers)
await QueuedTask.Run(() =>
{
if (mapMember is FeatureLayer featureLayer)
// subscribe to the selected layer events
foreach (MapMember mapMember in mapMembers)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
if (mapMember is FeatureLayer featureLayer)
{
SubscribeToFeatureLayerDataSourceChange(featureLayer);
}
else if (mapMember is StandaloneTable table)
{
SubscribeToTableDataSourceChange(table);
}
}
else if (mapMember is StandaloneTable table)
{
SubscribeToTableDataSourceChange(table);
}
}
});
var sendResult = await scope
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
.Execute(
mapMembers,
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -1,4 +1,5 @@
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.DUI.Bindings;
@@ -66,19 +67,18 @@ public class BasicConnectorBinding : IBasicConnectorBinding
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
public Task HighlightObjects(IReadOnlyList<string> objectIds)
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
{
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
return Task.CompletedTask;
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
}
public Task HighlightModel(string modelCardId)
public async Task HighlightModel(string modelCardId)
{
var model = _store.GetModelById(modelCardId);
if (model is null)
{
return Task.CompletedTask;
return;
}
var objectIds = new List<ObjectID>();
@@ -95,22 +95,24 @@ public class BasicConnectorBinding : IBasicConnectorBinding
if (objectIds is null)
{
return Task.CompletedTask;
return;
}
HighlightObjectsOnView(objectIds);
return Task.CompletedTask;
await HighlightObjectsOnView(objectIds);
}
private void HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
{
MapView mapView = MapView.Active;
await QueuedTask.Run(() =>
{
MapView mapView = MapView.Active;
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
ClearSelectionInTOC();
ClearSelection();
SelectMapMembersInTOC(mapMembersFeatures);
SelectMapMembersAndFeatures(mapMembersFeatures);
mapView.ZoomToSelected();
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
ClearSelectionInTOC();
ClearSelection();
SelectMapMembersInTOC(mapMembersFeatures);
SelectMapMembersAndFeatures(mapMembersFeatures);
mapView.ZoomToSelected();
});
}
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
@@ -10,6 +10,7 @@ using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
@@ -27,7 +28,7 @@ public static class ArcGISConnectorModule
public static void AddArcGIS(this IServiceCollection serviceCollection)
{
serviceCollection.AddConnectorUtils();
serviceCollection.AddDUI<ArcGISThreadContext, ArcGISDocumentStore>();
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
serviceCollection.AddDUIView();
// Register bindings
@@ -1,6 +1,7 @@
using System.Diagnostics.Contracts;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.Utils;
@@ -60,6 +61,19 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
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
@@ -226,7 +240,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
// TODO: validated a correct set regarding bakedobject ids
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
return new HostObjectBuilderResult(bakedObjectIds, results);
}
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
@@ -1,5 +1,6 @@
using ArcGIS.Core.Data.Raster;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.ArcGIS.HostApp;
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
@@ -49,7 +50,14 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
_mapMemberUtils = mapMemberUtils;
}
public async Task<RootObjectBuilderResult> Build(
public Task<RootObjectBuilderResult> Build(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
private async Task<RootObjectBuilderResult> BuildInternal(
IReadOnlyList<ADM.MapMember> layers,
SendInfo __,
IProgress<CardProgress> onOperationProgressed,
@@ -94,19 +102,26 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
// Mapmember dynamically attached properties are also added at this step.
List<ADM.MapMember> unpackedLayers;
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
long allFeaturesCount;
ADM.Map map = ADM.MapView.Active.Map;
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
using (var _ = _activityFactory.Start("Unpacking selection"))
{
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
allFeaturesCount = layersWithFeatureCount.Values.Sum();
}
List<SendConversionResult> results = new(unpackedLayers.Count);
onOperationProgressed.Report(new("Converting", null));
using (var convertingActivity = _activityFactory.Start("Converting objects"))
{
int count = 0;
foreach (ADM.MapMember layer in unpackedLayers)
long count = 0;
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
{
cancellationToken.ThrowIfCancellationRequested();
string layerApplicationId = layer.GetSpeckleApplicationId();
@@ -134,15 +149,33 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
switch (layer)
{
case ADM.FeatureLayer featureLayer:
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(featureLayer);
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
featureLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
break;
case ADM.RasterLayer rasterLayer:
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(rasterLayer);
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
rasterLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedRasterLayerObjects);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(lasDatasetLayer);
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
lasDatasetLayer,
count,
allFeaturesCount,
onOperationProgressed,
cancellationToken
);
layerCollection.elements.AddRange(convertedLasDatasetObjects);
break;
default:
@@ -150,6 +183,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
sdkStatus = SdkActivityStatusCode.Error;
break;
}
count += layerFeatureCount;
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
convertingActivity?.SetStatus(sdkStatus);
}
@@ -166,7 +201,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
convertingActivity?.RecordException(ex);
}
onOperationProgressed.Report(new("Converting", (double)++count / layers.Count));
await Task.Yield();
}
}
@@ -182,7 +216,41 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
return new RootObjectBuilderResult(rootCollection, results);
}
private List<Base> ConvertFeatureLayerObjects(ADM.FeatureLayer featureLayer)
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
{
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
foreach (ADM.MapMember layer in unpackedLayers)
{
switch (layer)
{
case ADM.FeatureLayer featureLayer:
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
break;
case ADM.RasterLayer rasterLayer:
// count Raster layer as 1 feature: not optimal but this is the approach for now
layersFeatureCount.Add(rasterLayer, 1);
break;
case ADM.LasDatasetLayer lasDatasetLayer:
var dataset = lasDatasetLayer.GetLasDataset();
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
layersFeatureCount.Add(
lasDatasetLayer,
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
);
break;
}
}
return layersFeatureCount;
}
private List<Base> ConvertFeatureLayerObjects(
ADM.FeatureLayer featureLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
@@ -196,6 +264,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
{
while (rowCursor.MoveNext())
{
// allow cancellation before every feature
cancellationToken.ThrowIfCancellationRequested();
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
using (ACD.Row row = rowCursor.Current)
{
@@ -209,6 +280,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// process the object color
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
@@ -216,19 +289,38 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
}
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
private List<Base> ConvertRasterLayerObjects(ADM.RasterLayer rasterLayer)
private List<Base> ConvertRasterLayerObjects(
ADM.RasterLayer rasterLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
Raster raster = rasterLayer.GetRaster();
// check cancellation token before conversion
cancellationToken.ThrowIfCancellationRequested();
Base converted = _rootToSpeckleConverter.Convert(raster);
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
converted.applicationId = applicationId;
convertedObjects.Add(converted);
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
return convertedObjects;
}
private List<Base> ConvertLasDatasetLayerObjects(ADM.LasDatasetLayer lasDatasetLayer)
private List<Base> ConvertLasDatasetLayerObjects(
ADM.LasDatasetLayer lasDatasetLayer,
long count,
long allFeaturesCount,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
List<Base> convertedObjects = new();
@@ -242,6 +334,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
{
while (ptCursor.MoveNext())
{
// allow cancellation before every point
cancellationToken.ThrowIfCancellationRequested();
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
{
Base converted = _rootToSpeckleConverter.Convert(pt);
@@ -252,6 +347,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
// process the object color
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
}
// update report
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
}
}
}
@@ -1,36 +0,0 @@
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Speckle.Connectors.Common.Threading;
namespace Speckle.Connectors.ArcGIS.Utils;
//don't check for GUI as it's the same check we do in ThreadContext
public class ArcGISThreadContext : ThreadContext
{
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
{
if (QueuedTask.OnWorker)
{
return action();
}
else
{
return QueuedTask.Run(async () => await action());
}
}
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(async () => await action());
protected override Task<T> MainToWorker<T>(Func<T> action)
{
if (QueuedTask.OnWorker)
{
return Task.FromResult(action());
}
else
{
return QueuedTask.Run(action);
}
}
protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
}
@@ -1,5 +1,6 @@
using System.Xml.Linq;
using ArcGIS.Desktop.Core.Events;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.Mapping.Events;
using Speckle.Connectors.Common.Threading;
@@ -82,8 +83,8 @@ public class ArcGISDocumentStore : DocumentModelStore
}
protected override void HostAppSaveState(string modelCardState) =>
_threadContext
.RunOnWorker(() =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
@@ -112,8 +113,8 @@ public class ArcGISDocumentStore : DocumentModelStore
.FireAndForget();
protected override void LoadState() =>
_threadContext
.RunOnWorker(() =>
QueuedTask
.Run(() =>
{
Map map = MapView.Active.Map;
var metadata = map.GetMetadata();
@@ -226,9 +226,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -236,8 +236,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -261,7 +261,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -294,40 +294,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
"net6.0-windows7.0/win-x64": {
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -294,7 +294,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -333,40 +333,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -294,7 +294,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -333,40 +333,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -295,7 +295,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -215,9 +215,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -225,8 +225,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -251,7 +251,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -290,39 +290,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -184,7 +184,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
.Execute(
autocadObjects,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -167,7 +167,7 @@ public class AutocadHostObjectBuilder(
convertedEntities.Add(bakedEntity);
break;
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix);
convertedEntities.UnionWith(bakedFallbackEntities);
break;
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -278,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -304,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -343,40 +343,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -278,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -304,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -343,40 +343,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -278,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -304,7 +304,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -343,40 +343,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -224,9 +224,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -234,8 +234,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -261,7 +261,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -300,39 +300,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -6,7 +6,6 @@ using Speckle.Connectors.Civil3dShared.Bindings;
using Speckle.Connectors.Civil3dShared.Operations.Send;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Converters.Civil3dShared.Helpers;
using Speckle.Converters.Civil3dShared.ToSpeckle;
using Speckle.Sdk;
@@ -28,7 +27,5 @@ public static class Civil3dConnectorModule
// additional classes
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
serviceCollection.AddScoped<CatchmentGroupHandler>();
serviceCollection.AddScoped<PipeNetworkHandler>();
}
}
@@ -4,7 +4,6 @@ using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.Civil3dShared.Helpers;
using Speckle.Converters.Civil3dShared.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Sdk.Logging;
@@ -16,14 +15,10 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
{
private readonly AutocadLayerUnpacker _layerUnpacker;
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
private readonly CatchmentGroupHandler _catchmentGroupHandler;
private readonly PipeNetworkHandler _pipeNetworkHandler;
public Civil3dRootObjectBuilder(
AutocadLayerUnpacker layerUnpacker,
PropertySetDefinitionHandler propertySetDefinitionHandler,
CatchmentGroupHandler catchmentGroupHandler,
PipeNetworkHandler pipeNetworkHandler,
IRootToSpeckleConverter converter,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
@@ -46,8 +41,6 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
{
_layerUnpacker = layerUnpacker;
_propertySetDefinitionHandler = propertySetDefinitionHandler;
_catchmentGroupHandler = catchmentGroupHandler;
_pipeNetworkHandler = pipeNetworkHandler;
}
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
@@ -61,7 +54,5 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
public override void AddAdditionalProxiesToRoot(Collection rootObject)
{
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
}
}
@@ -1,4 +1,5 @@
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
@@ -11,6 +12,7 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
private readonly ISpeckleApplication _speckleApplication;
private readonly DocumentModelStore _store;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
public string Name => "baseBinding";
public IBrowserBridge Parent { get; }
public BasicConnectorBindingCommands Commands { get; }
@@ -19,9 +21,11 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
IBrowserBridge parent,
ISpeckleApplication speckleApplication,
DocumentModelStore store,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
{
_threadContext = threadContext;
Parent = parent;
_speckleApplication = speckleApplication;
_store = store;
@@ -31,7 +35,11 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
_store.DocumentChanged += (_, _) =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await Commands.NotifyDocumentChanged();
// enforce main thread
await _threadContext.RunOnMainAsync(async () =>
{
await Commands.NotifyDocumentChanged();
});
});
}
@@ -45,11 +53,17 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
public DocumentModelStore GetDocumentState() => _store;
public void AddModel(ModelCard model) => _store.AddModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void AddModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.AddModel(model), true));
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void UpdateModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.UpdateModel(model), true));
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
public void RemoveModel(ModelCard model) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModel(model), true));
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
@@ -1,4 +1,5 @@
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.CSiShared.HostApp;
using Speckle.Connectors.CSiShared.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
@@ -12,7 +13,9 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
private bool _disposed;
private readonly Timer _selectionTimer;
private readonly ICsiApplicationService _csiApplicationService;
private readonly IThreadContext _threadContext;
private HashSet<string> _lastSelection = new();
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public IBrowserBridge Parent { get; }
public string Name => "selectionBinding";
@@ -20,26 +23,37 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
public CsiSharedSelectionBinding(
IBrowserBridge parent,
ICsiApplicationService csiApplicationService,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
{
_threadContext = threadContext;
Parent = parent;
_csiApplicationService = csiApplicationService;
_topLevelExceptionHandler = topLevelExceptionHandler;
_selectionTimer = new Timer(1000);
_selectionTimer.Elapsed += (_, _) => topLevelExceptionHandler.CatchUnhandled(CheckSelectionChanged);
_selectionTimer.Elapsed += (_, _) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckSelectionChanged));
_selectionTimer.Start();
}
private void CheckSelectionChanged()
{
// timer callbacks are on a background thread, but CSI API calls must be on main thread
var currentSelection = GetSelection();
var currentIds = new HashSet<string>(currentSelection.SelectedObjectIds);
if (!_lastSelection.SetEquals(currentIds))
{
_lastSelection = currentIds;
Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection);
// ensure UI updates also run on main thread
_threadContext.RunOnMain(
() =>
_topLevelExceptionHandler.CatchUnhandled(
() => Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection)
)
);
}
}
@@ -101,7 +101,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
.Execute(
wrappers,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -1,5 +1,6 @@
using System.IO;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
@@ -16,6 +17,7 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
private readonly ILogger<CsiDocumentModelStore> _logger;
private readonly ICsiApplicationService _csiApplicationService;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
private readonly Timer _modelCheckTimer;
private string _lastModelFilename = string.Empty;
private bool _disposed;
@@ -28,10 +30,12 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
ISpeckleApplication speckleApplication,
ILogger<CsiDocumentModelStore> logger,
ICsiApplicationService csiApplicationService,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
: base(jsonSerializer)
{
_threadContext = threadContext;
_speckleApplication = speckleApplication;
_logger = logger;
_csiApplicationService = csiApplicationService;
@@ -39,7 +43,10 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
// initialize timer to check for model changes
_modelCheckTimer = new Timer(1000);
_modelCheckTimer.Elapsed += (_, _) => _topLevelExceptionHandler.CatchUnhandled(CheckModelChanges);
// timer runs on background thread but model checks must be on main thread
_modelCheckTimer.Elapsed += (_, _) =>
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckModelChanges));
_modelCheckTimer.Start();
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.etabs21": {
@@ -332,40 +332,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -215,9 +215,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -225,8 +225,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -243,7 +243,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.etabs22": {
@@ -288,39 +288,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2020": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".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.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2021": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".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.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2022": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".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.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2023": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".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.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2024": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".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.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -275,8 +275,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -293,7 +293,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.navisworks2025": {
@@ -334,40 +334,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
".NETFramework,Version=v4.8/win-x64": {
@@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Operations.Send.Filters;
using Speckle.Connector.Navisworks.Operations.Send.Settings;
using Speckle.Connector.Navisworks.Services;
using Speckle.Connectors.Common.Cancellation;
@@ -30,7 +31,6 @@ public class NavisworksSendBinding : ISendBinding
private readonly DocumentModelStore _store;
private readonly IServiceProvider _serviceProvider;
private readonly List<ISendFilter> _sendFilters;
private readonly ICancellationManager _cancellationManager;
private readonly IOperationProgressManager _operationProgressManager;
private readonly ILogger<NavisworksSendBinding> _logger;
@@ -44,7 +44,6 @@ public class NavisworksSendBinding : ISendBinding
public NavisworksSendBinding(
DocumentModelStore store,
IBrowserBridge parent,
IEnumerable<ISendFilter> sendFilters,
IServiceProvider serviceProvider,
ICancellationManager cancellationManager,
IOperationProgressManager operationProgressManager,
@@ -61,7 +60,6 @@ public class NavisworksSendBinding : ISendBinding
Commands = new SendBindingUICommands(parent);
_store = store;
_serviceProvider = serviceProvider;
_sendFilters = sendFilters.ToList();
_cancellationManager = cancellationManager;
_operationProgressManager = operationProgressManager;
_logger = logger;
@@ -76,7 +74,12 @@ public class NavisworksSendBinding : ISendBinding
private static void SubscribeToNavisworksEvents() { }
public List<ISendFilter> GetSendFilters() => _sendFilters;
// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise, we might not be able to update list of saved sets.
public List<ISendFilter> GetSendFilters() =>
[
new NavisworksSelectionFilter() { IsDefault = true },
new NavisworksSavedSetsFilter(new ElementSelectionService())
];
public List<ICardSetting> GetSendSettings() =>
[
@@ -84,6 +87,7 @@ public class NavisworksSendBinding : ISendBinding
new OriginModeSetting(OriginMode.ModelOrigin),
new IncludeInternalPropertiesSetting(false),
new ConvertHiddenElementsSetting(false),
new PreserveModelHierarchySetting(false),
];
public async Task Send(string modelCardId) =>
@@ -134,7 +138,8 @@ public class NavisworksSendBinding : ISendBinding
originMode: _toSpeckleSettingsManagerNavisworks.GetOriginMode(modelCard),
visualRepresentationMode: _toSpeckleSettingsManagerNavisworks.GetVisualRepresentationMode(modelCard),
convertHiddenElements: _toSpeckleSettingsManagerNavisworks.GetConvertHiddenElements(modelCard),
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard)
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard),
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard)
)
);
@@ -146,17 +151,23 @@ public class NavisworksSendBinding : ISendBinding
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
}
var modelItems = modelCard
.SendFilter.NotNull()
.RefreshObjectIds()
var modelItems = selectedPaths
.Select(_selectionService.GetModelItemFromPath)
.SelectMany(_selectionService.GetGeometryNodes)
.Where(_selectionService.IsVisible)
.ToList();
return modelItems.Count == 0
? throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!")
: modelItems;
if (modelItems.Count != 0)
{
return modelItems;
}
var convertHiddenElementsSetting =
modelCard.Settings!.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool? ?? false;
var message = convertHiddenElementsSetting
? "No visible objects were found to convert. Please update your publish filter!"
: "No objects were found to convert. Please update your publish filter, or check items are visible!";
throw new SpeckleSendFilterException(message);
}
private async Task<SendOperationResult> ExecuteSendOperation(
@@ -169,7 +180,7 @@ public class NavisworksSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<NAV.ModelItem>>()
.Execute(
navisworksModelItems,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId.NotNull(), token),
token
);
@@ -67,6 +67,7 @@ public static class NavisworksConnectorServiceRegistration
// register filters
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
}
}
@@ -43,12 +43,13 @@ public class NavisworksColorUnpacker(
Dictionary<string, ColorProxy> colorProxies = [];
Dictionary<string, string> mergedIds = [];
// Build mergedIds map once
foreach (var group in groupedNodes)
{
foreach (var node in group.Value)
string groupKey = group.Key;
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
{
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
mergedIds[nodePath] = groupKey;
}
}
@@ -56,13 +57,13 @@ public class NavisworksColorUnpacker(
{
try
{
// Skip non-2D elements
if (!Is2DElement(navisworksObject))
{
continue;
}
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
var geometry = navisworksObject.Geometry;
@@ -77,7 +78,6 @@ public class NavisworksColorUnpacker(
geometry.OriginalColor,
defaultColor
);
var colorId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
@@ -43,12 +43,13 @@ public class NavisworksMaterialUnpacker(
Dictionary<string, RenderMaterialProxy> renderMaterialProxies = [];
Dictionary<string, string> mergedIds = [];
// Build mergedIds map once
foreach (var group in groupedNodes)
{
foreach (var node in group.Value)
string groupKey = group.Key;
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
{
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
mergedIds[nodePath] = groupKey;
}
}
@@ -63,7 +64,6 @@ public class NavisworksMaterialUnpacker(
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
var geometry = navisworksObject.Geometry;
var mode = converterSettings.Current.User.VisualRepresentationMode;
@@ -76,7 +76,6 @@ public class NavisworksMaterialUnpacker(
geometry.OriginalColor,
defaultColor
);
var renderTransparency = Select(
mode,
geometry.ActiveTransparency,
@@ -84,7 +83,6 @@ public class NavisworksMaterialUnpacker(
geometry.OriginalTransparency,
0.0
);
var renderMaterialId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
@@ -0,0 +1,107 @@
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 NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
{
private readonly IElementSelectionService _selectionService;
public NavisworksSavedSetsFilter(IElementSelectionService selectionService)
{
_selectionService = selectionService;
GetSavedSets();
}
public string Id { get; set; } = "navisworksSavedSets";
public string Name { get; set; } = "Saved Sets";
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; } = true;
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;
}
NAV.SavedItemCollection? selectionSets = NavisworksApp.ActiveDocument.SelectionSets.RootItem.Children;
foreach (var selectedSetGuid in SelectedItems)
{
var guid = new Guid(selectedSetGuid.Id);
var index = selectionSets.IndexOfGuid(guid);
if (index == -1)
{
throw new SpeckleSendFilterException($"Selection set with GUID {guid} not found.");
}
var selectionSetItem = selectionSets[index];
var selectionSet = (NAV.SelectionSet)selectionSetItem;
if (selectionSet.HasSearch)
{
objectIds.AddRange(ResolveSearchSet(selectionSet.Search));
}
if (selectionSet.HasExplicitModelItems)
{
objectIds.AddRange(ResolveSelectionSet(selectionSet.ExplicitModelItems));
}
}
return objectIds;
}
private IEnumerable<string> ResolveSelectionSet(NAV.ModelItemCollection selectionSetExplicitModelItems) =>
selectionSetExplicitModelItems
.Where(_selectionService.IsVisible) // Exclude hidden elements
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
.ToList();
private IEnumerable<string> ResolveSearchSet(NAV.Search selectionSetSearch) =>
selectionSetSearch
.FindAll(NavisworksApp.ActiveDocument, false)
.Where(_selectionService.IsVisible) // Exclude hidden elements
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
.ToList();
/// <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 GetSavedSets()
{
List<NAV.SavedItem> savedSetRecords = NavisworksApp
.ActiveDocument.SelectionSets.RootItem.Children.Where(set => !set.IsGroup)
.ToList();
Items = savedSetRecords
.Select(setRecord =>
{
NAV.SavedItem? record = setRecord.CreateCopy();
string? name = record.DisplayName;
while (record.Parent != null)
{
name = record.Parent.DisplayName + "::" + name;
record = record.Parent;
}
return new SendFilterSelectItem(setRecord.Guid.ToString(), name);
})
.ToList();
}
}
@@ -1,4 +1,5 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Constants;
namespace Speckle.Connector.Navisworks.Operations.Send;
@@ -7,16 +8,158 @@ namespace Speckle.Connector.Navisworks.Operations.Send;
/// </summary>
public static class GeometryNodeMerger
{
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes) =>
nodes
/// <summary>
/// Groups sibling geometry nodes based on material properties for merging.
/// Only merges nodes that share the same parent and have identical material properties.
/// </summary>
/// <param name="nodes">The collection of ModelItems to process</param>
/// <returns>Dictionary mapping parent paths (with material signature suffix) to their mergeable child nodes</returns>
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes)
{
var selectionService = new ElementSelectionService();
// Group nameless geometry nodes by parent path and material signature
var mergeableGroups = nodes
.Where(node => node.HasGeometry && string.IsNullOrEmpty(node.DisplayName)) // Only anonymous geometry nodes
.GroupBy(node =>
{
var service = new ElementSelectionService();
var path = service.GetModelItemPath(node);
// Get parent path
var path = selectionService.GetModelItemPath(node);
var lastSeparatorIndex = path.LastIndexOf(PathConstants.SEPARATOR);
return lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
var parentPath = lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
// Generate material signature
string signature = GenerateSignature(node);
// Combine parent path with signature
return $"{parentPath}{PathConstants.MATERIAL_SEPARATOR}{signature}";
})
.Where(group => group.Count() > 1) // Only group multiples
.Where(group => group.Count() > 1) // Only include groups with multiple children
.ToDictionary(group => group.Key, group => group.ToList());
return mergeableGroups;
}
/// <summary>
/// Generates a signature for a node based on material properties
/// </summary>
private static string GenerateSignature(NAV.ModelItem node)
{
var signatureProperties = new Dictionary<string, object>();
// We can as many signature defining methods as we want here
AddMaterialProperties(node, signatureProperties);
// When we are done adding properties, we can generate the signature
return GetSignature(signatureProperties);
}
/// <summary>
/// Adds material-related properties to the properties dictionary
/// </summary>
private static void AddMaterialProperties(NAV.ModelItem node, Dictionary<string, object> properties)
{
if (!node.HasGeometry || node.Geometry == null)
{
return;
}
var geometry = node.Geometry;
if (geometry.ActiveColor != null)
{
properties["ActiveColor"] = (geometry.ActiveColor.R, geometry.ActiveColor.G, geometry.ActiveColor.B);
properties["ActiveTransparency"] = geometry.ActiveTransparency;
}
// Add material name if available
var materialName = GetMaterialName(node);
if (!string.IsNullOrEmpty(materialName))
{
properties["MaterialName"] = materialName;
}
}
/// <summary>
/// Creates a hash-based signature from a dictionary of properties.
/// </summary>
/// <param name="properties">Dictionary containing property name/value pairs to include in the signature</param>
/// <param name="hashLength">Length of the returned hash string (default: 8 characters)</param>
/// <returns>A hash string representing the combined properties</returns>
private static string GetSignature(Dictionary<string, object> properties, int hashLength = 8)
{
if (properties.Count == 0)
{
return "empty";
}
// Build a consistent string representation of all properties
var hashInput = new System.Text.StringBuilder();
// Sort keys to ensure consistent order
var sortedKeys = properties.Keys.OrderBy(k => k).ToList();
foreach (var key in sortedKeys)
{
var value = properties[key];
switch (value)
{
case null:
continue;
// Format numbers with fixed precision to avoid floating point inconsistencies
case double doubleValue:
hashInput.Append($"{key}:{Math.Round(doubleValue, 6)}_");
break;
case float floatValue:
hashInput.Append($"{key}:{Math.Round(floatValue, 6)}_");
break;
default:
hashInput.Append($"{key}:{value.GetHashCode()}_");
break;
}
}
if (hashInput.Length == 0)
{
return "empty";
}
// Use MD5 hash with warning suppression
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
using var md5 = System.Security.Cryptography.MD5.Create();
var inputBytes = System.Text.Encoding.UTF8.GetBytes(hashInput.ToString());
var hashBytes = md5.ComputeHash(inputBytes);
#pragma warning restore CA5351
var fullHashString = BitConverter.ToString(hashBytes).Replace("-", "");
return fullHashString[..Math.Min(hashLength, fullHashString.Length)];
}
/// <summary>
/// Extracts material name from a node if available.
/// </summary>
private static string GetMaterialName(NAV.ModelItem node)
{
// Check Item category for material name
var itemCategory = node.PropertyCategories.FindCategoryByDisplayName("Item");
if (itemCategory != null)
{
var itemProperties = itemCategory.Properties;
var itemMaterial = itemProperties.FindPropertyByDisplayName("Material");
if (itemMaterial != null && !string.IsNullOrEmpty(itemMaterial.DisplayName))
{
return itemMaterial.Value.ToDisplayString();
}
}
// Check Material category for material name
var materialPropertyCategory = node.PropertyCategories.FindCategoryByDisplayName("Material");
if (materialPropertyCategory == null)
{
return string.Empty;
}
var material = materialPropertyCategory.Properties;
var name = material.FindPropertyByDisplayName("Name");
return name != null && !string.IsNullOrEmpty(name.DisplayName) ? name.Value.ToDisplayString() : string.Empty;
}
}
@@ -0,0 +1,146 @@
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Constants;
using Speckle.Converters.Common;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connector.Navisworks.Operations.Send;
/// <summary>
/// Rebuilds the Navisworks document hierarchy from converted geometry leaves while preserving
/// the parent-child relationships between elements in the original model structure.
/// </summary>
public class NavisworksHierarchyBuilder
{
private readonly Dictionary<string, Base?> _geometryLeaves;
private readonly IRootToSpeckleConverter _converter;
private readonly IElementSelectionService _selectionService;
private readonly Dictionary<string, Base> _allNodes;
/// <summary>
/// Initializes a new instance of the NavisworksHierarchyBuilder.
/// </summary>
/// <param name="geometryLeaves">Dictionary of path-indexed converted geometry elements</param>
/// <param name="converter">Converter to transform Navisworks elements to Speckle objects</param>
/// <param name="selectionService">Service for resolving Navisworks element paths</param>
public NavisworksHierarchyBuilder(
Dictionary<string, Base?> geometryLeaves,
IRootToSpeckleConverter converter,
IElementSelectionService selectionService
)
{
_geometryLeaves = geometryLeaves;
_converter = converter;
_selectionService = selectionService;
_allNodes = new Dictionary<string, Base>();
}
/// <summary>
/// Constructs a hierarchical tree of Speckle objects that mirrors the Navisworks document structure.
/// </summary>
/// <returns>List of root-level Speckle Base objects containing the full hierarchy</returns>
public List<Base> BuildHierarchy()
{
foreach (var kvp in _geometryLeaves)
{
if (kvp.Value != null)
{
_allNodes[kvp.Key] = kvp.Value;
}
}
// For each leaf path, traverse up the document structure converting any missing ancestors
foreach (var nodePath in _allNodes.ToList().Select(kvp => kvp.Key))
{
ClimbUpToRoot(nodePath);
}
var allPaths = _allNodes.Keys.ToList();
allPaths.Sort(
(a, b) =>
{
var depthA = a.Count(c => c == PathConstants.SEPARATOR);
var depthB = b.Count(c => c == PathConstants.SEPARATOR);
return depthB.CompareTo(depthA); // <- Sort in ascending order of path length
}
);
// Link nodes to parents and identify root nodes that have no recognized parent
var rootCandidates = new Dictionary<string, Base>(_allNodes);
foreach (var nodePath in allPaths)
{
if (nodePath == "0")
{
continue;
}
var nodeBase = _allNodes[nodePath];
var parentPath = GetParentPath(nodePath);
if (string.IsNullOrEmpty(parentPath))
{
continue;
}
// Navisworks API: Add child elements to parent collections
if (!_allNodes.TryGetValue(parentPath, out var parentBase) || parentBase is not Collection parentCollection)
{
continue;
}
parentCollection.elements.Add(nodeBase);
rootCandidates.Remove(nodePath);
}
var rootNodes = rootCandidates.Values.ToList();
PruneEmptyCollections(rootNodes);
return rootNodes;
}
private void ClimbUpToRoot(string currentPath)
{
while (!string.IsNullOrEmpty(currentPath) && currentPath != "0")
{
var parentPath = GetParentPath(currentPath);
if (string.IsNullOrEmpty(parentPath))
{
return;
}
if (_allNodes.ContainsKey(parentPath))
{
currentPath = parentPath;
continue;
}
var parentModelItem = _selectionService.GetModelItemFromPath(parentPath);
var parentConverted = _converter.Convert(parentModelItem);
_allNodes[parentPath] = parentConverted;
currentPath = parentPath;
}
}
private static string GetParentPath(string path)
{
var idx = path.LastIndexOf(PathConstants.SEPARATOR);
return idx == -1 ? string.Empty : path[..idx];
}
private static void PruneEmptyCollections(List<Base> nodes)
{
foreach (var node in nodes.ToList())
{
if (node is not Collection collection)
{
continue;
}
PruneEmptyCollections(collection.elements);
collection.elements.RemoveAll(child => child is Collection { elements.Count: 0 });
}
}
}
@@ -144,12 +144,27 @@ public class NavisworksRootObjectBuilder(
Dictionary<string, List<NAV.ModelItem>> groupedNodes
)
{
// First build the grouped nodes as before
var finalElements = new List<Base>();
var processedPaths = new HashSet<string>();
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
AddRemainingElements(finalElements, convertedBases, processedPaths);
// If hierarchy mode is enabled, reorganize into proper nested structure
if (converterSettings.Current.User.PreserveModelHierarchy)
{
var hierarchyBuilder = new NavisworksHierarchyBuilder(
convertedBases,
rootToSpeckleConverter,
elementSelectionService
);
var hierarchy = hierarchyBuilder.BuildHierarchy();
return hierarchy;
}
// Otherwise continue with flat mode
AddRemainingElements(finalElements, convertedBases, processedPaths);
return finalElements;
}
@@ -221,7 +236,8 @@ public class NavisworksRootObjectBuilder(
/// </remarks>
private NavisworksObject CreateNavisworksObject(string groupKey, List<Base> siblingBases)
{
(string name, string path) = GetContext(groupKey);
string cleanParentPath = ElementSelectionHelper.GetCleanPath(groupKey);
(string name, string path) = GetContext(cleanParentPath);
return new NavisworksObject
{
@@ -229,7 +245,7 @@ public class NavisworksRootObjectBuilder(
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
units = converterSettings.Current.Derived.SpeckleUnits,
applicationId = groupKey,
applicationId = groupKey, // Use the full composite key as applicationId to preserve uniqueness
["path"] = path
};
}
@@ -0,0 +1,12 @@
using Speckle.Connectors.DUI.Settings;
namespace Speckle.Connector.Navisworks.Operations.Send.Settings;
public class PreserveModelHierarchySetting(bool value) : ICardSetting
{
public string? Id { get; set; } = "preserveModelHierarchy";
public string? Title { get; set; } = "Preserve Model Hierarchy";
public string? Type { get; set; } = "boolean";
public List<string>? Enum { get; set; }
public object? Value { get; set; } = value;
}
@@ -17,6 +17,7 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
private readonly Dictionary<string, OriginMode> _originModeCache = [];
private readonly Dictionary<string, bool?> _convertHiddenElementsCache = [];
private readonly Dictionary<string, bool?> _includeInternalPropertiesCache = [];
private readonly Dictionary<string, bool?> _preserveModelHierarchyCache = [];
public ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
{
@@ -120,6 +121,23 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
return returnValue;
}
public bool GetPreserveModelHierarchy([NotNull] SenderModelCard modelCard)
{
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "preserveModelHierarchy")?.Value as bool?;
var returnValue = value != null && value.NotNull();
if (_preserveModelHierarchyCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
{
if (previousValue != returnValue)
{
EvictCacheForModelCard(modelCard);
}
}
_preserveModelHierarchyCache[modelCard.ModelCardId] = returnValue;
return returnValue;
}
private void EvictCacheForModelCard(SenderModelCard modelCard)
{
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
@@ -1,6 +0,0 @@
namespace Speckle.Connector.Navisworks;
public static class PathConstants
{
public const char SEPARATOR = '/';
}
@@ -21,14 +21,16 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksMaterialUnpacker.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\GeometryNodeMerger.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksHierarchyBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksRootObjectBuilder.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ConvertHiddenEleementsSetting.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\IncludeInternalPropertiesSetting.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\OriginModeSetting.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\PreserveModelHierarchySetting.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManagerNavisworks.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\VisualRepresentationSetting.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSelectionFilter.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)PathConstants.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSavedSetsFilter.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Plugin\BrowserPane.xaml.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Plugin\DockableConnectorPane.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Plugin\NavisworksRibbon.xaml.cs"/>
@@ -287,9 +287,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -297,8 +297,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.logging": {
@@ -308,7 +308,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.revit2022": {
@@ -348,16 +348,16 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Revit.API": {
@@ -368,26 +368,26 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -287,9 +287,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -297,8 +297,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.logging": {
@@ -308,7 +308,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.revit2023": {
@@ -348,16 +348,16 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Revit.API": {
@@ -368,26 +368,26 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -287,9 +287,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -297,8 +297,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.logging": {
@@ -308,7 +308,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.revit2024": {
@@ -348,16 +348,16 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Revit.API": {
@@ -368,26 +368,26 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -237,9 +237,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -247,8 +247,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.logging": {
@@ -258,7 +258,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.revit2025": {
@@ -298,16 +298,16 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Revit.API": {
@@ -318,25 +318,25 @@
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
},
"net8.0-windows7.0/win-x64": {
@@ -103,7 +103,12 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
var view = revitViewsFilter.GetView();
if (view is not null)
{
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
await RevitTask
.RunAsync(() =>
{
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
})
.ConfigureAwait(false);
}
return;
}
@@ -8,6 +8,7 @@ using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Connectors.Revit.Plugin;
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Settings;
using Speckle.Sdk;
@@ -98,6 +99,10 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
// 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 (SpeckleRevitTaskException ex)
{
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
}
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);
@@ -16,6 +16,7 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Connectors.DUI.Settings;
using Speckle.Connectors.Revit.HostApp;
using Speckle.Connectors.Revit.Operations.Send.Settings;
using Speckle.Connectors.Revit.Plugin;
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Helpers;
@@ -147,7 +148,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<ElementId>>()
.Execute(
elementIds,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -160,6 +161,10 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
// 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 (SpeckleRevitTaskException ex)
{
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
}
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);
@@ -2,7 +2,7 @@ using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using Revit.Async;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;
@@ -22,6 +22,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
private readonly DocumentModelStorageSchema _documentModelStorageSchema;
private readonly IdStorageSchema _idStorageSchema;
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
private readonly IThreadContext _threadContext;
public RevitDocumentStore(
IAppIdleManager idleManager,
@@ -29,7 +30,8 @@ internal sealed class RevitDocumentStore : DocumentModelStore
IJsonSerializer jsonSerializer,
DocumentModelStorageSchema documentModelStorageSchema,
IdStorageSchema idStorageSchema,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
)
: base(jsonSerializer)
{
@@ -38,6 +40,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
_documentModelStorageSchema = documentModelStorageSchema;
_idStorageSchema = idStorageSchema;
_topLevelExceptionHandler = topLevelExceptionHandler;
_threadContext = threadContext;
UIApplication uiApplication = _revitContext.UIApplication.NotNull();
@@ -91,23 +94,25 @@ internal sealed class RevitDocumentStore : DocumentModelStore
return;
}
RevitTask.RunAsync(() =>
{
using Transaction t = new(doc, "Speckle Write State");
t.Start();
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
_threadContext
.RunOnMain(() =>
{
using Transaction t = new(doc, "Speckle Write State");
t.Start();
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
string serializedModels = Serialize();
stateEntity.Set("contents", serializedModels);
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
string serializedModels = Serialize();
stateEntity.Set("contents", serializedModels);
using Entity idEntity = new(_idStorageSchema.GetSchema());
idEntity.Set("Id", s_revitDocumentStoreId);
using Entity idEntity = new(_idStorageSchema.GetSchema());
idEntity.Set("Id", s_revitDocumentStoreId);
ds.SetEntity(idEntity);
ds.SetEntity(stateEntity);
t.Commit();
});
ds.SetEntity(idEntity);
ds.SetEntity(stateEntity);
t.Commit();
})
.FireAndForget();
}
protected override void LoadState()
@@ -12,6 +12,7 @@ public class SendCollectionManager
{
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
private readonly Dictionary<string, Collection> _collectionCache = new();
private readonly Dictionary<ElementId, (string name, Dictionary<string, object?> props)> _levelCache = new(); // stores level id and its properties
public SendCollectionManager(IConverterSettingsStore<RevitConversionSettings> converterSettings)
{
@@ -30,9 +31,29 @@ public class SendCollectionManager
var doc = _converterSettings.Current.Document;
var path = new List<string>();
// Step 0: get the level and its properties
string levelName = "No Level";
Dictionary<string, object?> levelProperties = new();
if (element.LevelId != ElementId.InvalidElementId)
{
if (_levelCache.TryGetValue(element.LevelId, out var cachedLevel))
{
levelName = cachedLevel.name;
levelProperties = cachedLevel.props;
}
else
{
var level = (Level)doc.GetElement(element.LevelId);
levelName = level.Name;
levelProperties.Add("elevation", level.Elevation);
levelProperties.Add("units", _converterSettings.Current.SpeckleUnits);
_levelCache.Add(element.LevelId, (levelName, levelProperties));
}
}
// Step 1: create path components. Currently, this is
// level > category > type
path.Add(doc.GetElement(element.LevelId) is not Level level ? "No level" : level.Name);
path.Add(levelName);
path.Add(element.Category?.Name ?? "No category");
var typeId = element.GetTypeId();
if (typeId != ElementId.InvalidElementId)
@@ -57,8 +78,9 @@ public class SendCollectionManager
string flatPathName = "";
Collection previousCollection = rootObject;
foreach (var pathItem in path)
for (int i = 0; i < path.Count; i++)
{
var pathItem = path[i];
flatPathName += pathItem;
Collection childCollection;
if (_collectionCache.TryGetValue(flatPathName, out Collection? collection))
@@ -68,6 +90,13 @@ public class SendCollectionManager
else
{
childCollection = new Collection(pathItem);
// add props if it's the 1st path item, representing level
// if the structure ever changes from level > category > type, this needs to be changed
if (i == 0 && levelProperties.Count > 0)
{
childCollection["properties"] = levelProperties;
}
previousCollection.elements.Add(childCollection);
_collectionCache[flatPathName] = childCollection;
}
@@ -5,7 +5,7 @@ namespace Speckle.Connectors.Revit.HostApp;
public static class SupportedCategoriesUtils
{
/// <summary>
/// Filters out all categories besides Model categories. This utility should be used
/// Filters out all categories besides Model categories, and Grids in Annotation. This utility should be used
/// to clean any elements we might want to send pre-conversion as well as in what categories
/// to display in our category filter.
/// </summary>
@@ -13,18 +13,32 @@ public static class SupportedCategoriesUtils
/// <returns></returns>
public static bool IsSupportedCategory(Category? category)
{
return category is not null
&& (
category.CategoryType == CategoryType.Model
// || category.CategoryType == CategoryType.AnalyticalModel
)
#if REVIT_2023_OR_GREATER
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines
if (category is null || !category.IsVisibleInUI)
{
return false;
}
switch (category.CategoryType)
{
case CategoryType.Annotation:
return
#if REVIT2023_OR_GREATER
category.BuiltInCategory == BuiltInCategory.OST_Grids;
#else
&& category.Name != "OST_AreaSchemeLines"
&& category.Name != "OST_AreaSchemes"
category.Name == "OST_Grids";
#endif
&& category.IsVisibleInUI;
case CategoryType.Model:
return
#if REVIT2023_OR_GREATER
category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines;
#else
category.Name != "OST_AreaSchemeLines" && category.Name != "OST_AreaSchemes";
#endif
default:
return false;
}
}
}
@@ -85,7 +85,7 @@ public class RevitRootObjectBuilder(
var countProgress = 0;
var cacheHitCount = 0;
var skippedObjectCount = 0;
foreach (Element revitElement in atomicObjects)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -105,6 +105,7 @@ public class RevitRootObjectBuilder(
new SpeckleException($"Category {cat} is not supported.")
)
);
skippedObjectCount++;
continue;
}
@@ -134,7 +135,7 @@ public class RevitRootObjectBuilder(
onOperationProgressed.Report(new("Converting", (double)++countProgress / atomicObjects.Count));
}
if (results.All(x => x.Status == Status.ERROR))
if (results.All(x => x.Status == Status.ERROR) || skippedObjectCount == atomicObjects.Count)
{
throw new SpeckleException("Failed to convert all objects.");
}
@@ -1,5 +1,6 @@
using Revit.Async;
using Speckle.Connectors.Common.Threading;
using Speckle.Sdk;
namespace Speckle.Connectors.Revit.Plugin;
@@ -7,16 +8,82 @@ public class RevitThreadContext : ThreadContext
{
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action) => action();
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) =>
RevitTask.RunAsync(async () => await action());
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
protected override Task<T> MainToWorker<T>(Func<T> action) => Task.FromResult(action());
protected override Task<T> WorkerToMain<T>(Func<T> action) => RevitTask.RunAsync(action);
protected override Task<T> WorkerToMain<T>(Func<T> action) => CatchExceptions(action);
protected override Task RunMainAsync(Func<Task> action) => RevitTask.RunAsync(action);
protected override Task RunMainAsync(Func<Task> action) => CatchExceptions(action);
protected override Task<T> RunMainAsync<T>(Func<T> action) => RevitTask.RunAsync(action);
protected override Task<T> RunMainAsync<T>(Func<T> action) => CatchExceptions(action);
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => RevitTask.RunAsync(action);
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
private static async Task<T> CatchExceptions<T>(Func<T> action)
{
Exception? ex = null;
//force the usage of the application overload
var ret = await RevitTask.RunAsync(_ =>
{
try
{
return action();
}
catch (Exception e) when (!e.IsFatal())
{
ex = e;
return default;
}
});
if (ex is not null)
{
throw new SpeckleRevitTaskException(ex);
}
return ret!;
}
private static async Task<T> CatchExceptions<T>(Func<Task<T>> action)
{
Exception? ex = null;
//force the usage of the application overload
var ret = await RevitTask.RunAsync(async _ =>
{
try
{
return await action();
}
catch (Exception e) when (!e.IsFatal())
{
ex = e;
return default;
}
});
if (ex is not null)
{
throw new SpeckleRevitTaskException(ex);
}
return ret!;
}
private static async Task CatchExceptions(Func<Task> action)
{
Exception? ex = null;
//force the usage of the application overload
await RevitTask.RunAsync(async _ =>
{
try
{
await action();
}
catch (Exception e) when (!e.IsFatal())
{
ex = e;
}
});
if (ex is not null)
{
throw new SpeckleRevitTaskException(ex);
}
}
}
@@ -0,0 +1,38 @@
using Microsoft.Extensions.Logging;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Logging;
using Speckle.Sdk;
using Speckle.Sdk.Common;
namespace Speckle.Connectors.Revit.Plugin;
#pragma warning disable CA1032
public class SpeckleRevitTaskException(Exception exception) : SpeckleException("Revit operation failed", exception)
#pragma warning restore CA1032
{
public static async Task ProcessException<T>(
string modelCardId,
SpeckleRevitTaskException ex,
ILogger<T> logger,
BasicConnectorBindingCommands commands
)
where T : IBinding
{
Exception e = ex.InnerException.NotNull();
while (e is SpeckleRevitTaskException srte)
{
e = srte.InnerException.NotNull();
}
if (e is 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;
}
//log everything though
logger.LogModelCardHandledError(ex);
//always process the inner exception
await commands.SetModelError(modelCardId, e);
}
}
@@ -50,5 +50,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitThreadContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCefPlugin.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleRevitTaskException.cs" />
</ItemGroup>
</Project>
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -278,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -296,7 +296,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.rhino7": {
@@ -342,40 +342,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -268,9 +268,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -278,8 +278,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -296,7 +296,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"speckle.converters.rhino8": {
@@ -342,40 +342,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -316,7 +316,7 @@ public sealed class RhinoSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<RhinoObject>>()
.Execute(
rhinoObjects,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -1,4 +1,6 @@
using Rhino;
using Rhino.DocObjects;
using Speckle.Sdk;
namespace Speckle.Connectors.Rhino.HostApp.Properties;
@@ -13,11 +15,18 @@ public class PropertiesExtractor
var userStrings = rhObject.Attributes.GetUserStrings();
foreach (var key in userStrings.AllKeys)
{
// POC: could not determine how to extract the value of a formula user string.
// So for now we are skipping them
if (userStrings[key].StartsWith("%<"))
try
{
continue;
if (userStrings[key].StartsWith("%<"))
{
var value = RhinoApp.ParseTextField(userStrings[key], rhObject, null);
properties[key] = value;
continue;
}
}
catch (Exception ex) when (!ex.IsFatal())
{
// Shh. We can fail silently here - it's not even worth logging. I expect users will complain properties are missing.
}
properties[key] = userStrings[key];
@@ -19,11 +19,6 @@ public class RhinoDocumentStore : DocumentModelStore
RhinoDoc.EndOpenDocument += (_, e) =>
topLevelExceptionHandler.CatchUnhandled(() =>
{
if (e.Merge)
{
return;
}
if (e.Document == null)
{
return;
@@ -13,7 +13,6 @@ using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Instances;
using RenderMaterial = Rhino.Render.RenderMaterial;
namespace Speckle.Connectors.Rhino.HostApp;
@@ -129,11 +128,9 @@ public class RhinoInstanceBaker : IInstanceBaker<IReadOnlyCollection<string>>
string instanceProxyId = instanceProxy.applicationId ?? instanceProxy.id.NotNull();
ObjectAttributes atts = new() { LayerIndex = layerIndex };
if (
_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(instanceProxyId, out RenderMaterial renderMaterial)
)
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(instanceProxyId, out int mIndex))
{
atts.RenderMaterial = renderMaterial;
atts.MaterialIndex = mIndex;
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
}
@@ -1,6 +1,5 @@
using Rhino;
using Rhino.DocObjects;
using Rhino.Render;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Sdk;
using Speckle.Sdk.Common;
@@ -116,11 +115,11 @@ public class RhinoLayerBaker : TraversalContextUnpacker
if (
_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(
collection.applicationId ?? collection.id.NotNull(),
out RenderMaterial renderMaterial
out int mIndex
)
)
{
newLayer.RenderMaterial = renderMaterial;
newLayer.RenderMaterialIndex = mIndex;
}
// set color
@@ -7,7 +7,6 @@ using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Material = Rhino.DocObjects.Material;
using RenderMaterial = Rhino.Render.RenderMaterial;
namespace Speckle.Connectors.Rhino.HostApp;
@@ -26,9 +25,9 @@ public class RhinoMaterialBaker
}
/// <summary>
/// A map keeping track of ids, <b>either layer id or object id</b>, and their render material guid. It's generated from the material proxy list as we bake materials; <see cref="BakeMaterials"/> must be called in advance for this to be populated with the correct data.
/// A map keeping track of ids, <b>either layer id or object id</b>, and their material index. It's generated from the material proxy list as we bake materials; <see cref="BakeMaterials"/> must be called in advance for this to be populated with the correct data.
/// </summary>
public Dictionary<string, RenderMaterial> ObjectIdAndMaterialIndexMap { get; } = new();
public Dictionary<string, int> ObjectIdAndMaterialIndexMap { get; } = new();
public void BakeMaterials(IReadOnlyCollection<RenderMaterialProxy> speckleRenderMaterialProxies, string baseLayerName)
{
@@ -68,23 +67,19 @@ public class RhinoMaterialBaker
rhinoMaterial.Shine = shine;
}
// We are creating a render material and adding it to the render material table because render materials have a guid independent of objects they are applied to.
// Regular materials and the material table is populated by materials applied to objects: the same material can therefore have multiple entries in the material table if it is applied to multiple objects
// see: https://discourse.mcneel.com/t/render-material-events/99886/5
RenderMaterial rhinoRenderMaterial = RenderMaterial.FromMaterial(rhinoMaterial, doc);
int matIndex = doc.Materials.Add(rhinoMaterial);
if (doc.RenderMaterials.Add(rhinoRenderMaterial))
{
// Create the object <> render material guid map
foreach (var objectId in proxy.objects)
{
ObjectIdAndMaterialIndexMap[objectId] = rhinoRenderMaterial;
}
}
else
// POC: check on matIndex -1, means we haven't created anything - this is most likely an recoverable error at this stage
if (matIndex == -1)
{
throw new ConversionException("Failed to add a material to the document.");
}
// Create the object <> material index map
foreach (var objectId in proxy.objects)
{
ObjectIdAndMaterialIndexMap[objectId] = matIndex;
}
}
catch (Exception ex) when (!ex.IsFatal())
{
@@ -100,13 +95,18 @@ public class RhinoMaterialBaker
public void PurgeMaterials(string namePrefix)
{
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
// POC: looping through the render material table somehow doesn't capture all render materials!! That's why we're doing it this way.
var materialsToDelete = currentDoc.RenderMaterials.Where(o => o.DisplayName.Contains(namePrefix)).ToList();
foreach (RenderMaterial materialToDelete in materialsToDelete)
foreach (Material material in currentDoc.Materials)
{
if (!currentDoc.RenderMaterials.Remove(materialToDelete))
try
{
_logger.LogError("Failed to purge a material from the document");
if (!material.IsDeleted && material.Name != null && material.Name.Contains(namePrefix))
{
currentDoc.Materials.Delete(material);
}
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to purge a material from the document");
}
}
}
@@ -29,12 +29,17 @@ public class RhinoMaterialUnpacker
/// Processes an object's material and adds the object id to a material proxy in <see cref="RenderMaterialProxies"/> if object color is set ByObject or ByParent.
/// </summary>
/// <param name="objId"></param>
private void ProcessObjectMaterial(string objId, RenderMaterial renderMaterial, ObjectMaterialSource source)
private void ProcessObjectMaterial(
string objId,
RenderMaterial? renderMaterial,
Material? material,
ObjectMaterialSource source
)
{
switch (source)
{
case ObjectMaterialSource.MaterialFromObject:
AddObjectIdToRenderMaterialProxy(objId, renderMaterial);
AddObjectIdToRenderMaterialProxy(objId, renderMaterial, material);
break;
// POC: skip if object material source is *not* by object. we don't support render material inheritance atm bc alex disagrees with the concept
@@ -43,29 +48,55 @@ public class RhinoMaterialUnpacker
}
}
private void AddObjectIdToRenderMaterialProxy(string objectId, RenderMaterial renderMaterial)
private void AddObjectIdToRenderMaterialProxy(string objectId, RenderMaterial? renderMaterial, Material? material)
{
string? renderMaterialId = renderMaterial.Id.ToString();
// NOTE: material ids are not the same, even if the underlying material is. the number of materials in the mat table corresponds
// with the number of objects, and each material will get a new id, even if it is THE SAME. shockingly, TY bob, material names
// are unique so we use those for identity checks rather than the material's id.
string? renderMaterialId = renderMaterial?.Name ?? material?.Name; //renderMaterial?.Id.ToString() ?? material?.Id.ToString();
if (RenderMaterialProxies.TryGetValue(renderMaterialId, out RenderMaterialProxy? proxy))
if (renderMaterialId is not null)
{
proxy.objects.Add(objectId);
}
else
{
if (
ConvertMaterialToRenderMaterialProxy(renderMaterialId, renderMaterial) is RenderMaterialProxy newRenderMaterial
)
if (RenderMaterialProxies.TryGetValue(renderMaterialId, out RenderMaterialProxy? proxy))
{
newRenderMaterial.objects.Add(objectId);
RenderMaterialProxies[renderMaterialId] = newRenderMaterial;
proxy.objects.Add(objectId);
}
else
{
if (
ConvertMaterialToRenderMaterialProxy(renderMaterialId, renderMaterial, material)
is RenderMaterialProxy newRenderMaterial
)
{
newRenderMaterial.objects.Add(objectId);
RenderMaterialProxies[renderMaterialId] = newRenderMaterial;
}
}
}
}
private RenderMaterialProxy? ConvertMaterialToRenderMaterialProxy(string materialId, RenderMaterial renderMaterial)
private RenderMaterialProxy? ConvertMaterialToRenderMaterialProxy(
string materialId,
RenderMaterial? renderMaterial,
Material? material
)
{
SpeckleRenderMaterial myMaterial = ConvertRenderMaterialToSpeckle(renderMaterial);
// TY Rhino api for being a bit confused about materials 💖
SpeckleRenderMaterial? myMaterial = null;
if (renderMaterial is not null)
{
myMaterial = ConvertRenderMaterialToSpeckle(renderMaterial);
}
else if (material is not null)
{
RenderMaterial convertedRender = ConvertMaterialToRenderMaterial(material);
myMaterial = ConvertRenderMaterialToSpeckle(convertedRender);
}
if (myMaterial is null)
{
return null;
}
RenderMaterialProxy renderMaterialProxy =
new()
@@ -92,26 +123,23 @@ public class RhinoMaterialUnpacker
// Stage 1: unpack materials from objects
foreach (RhinoObject rootObj in atomicObjects)
{
// materials are confusing in rhino - some objects can have render materials, other may only have a material.
// see: https://discourse.mcneel.com/t/getting-material-from-rhinoobject/114870/6
// basically, materials (old) are created PER OBJECT if they are assigned per object. This means the same material will have diff ids when called from the material table
// unfortunately, in the case where no rendermaterial exists, we'll have to create duplicate proxies.
RenderMaterial? rhinoRenderMaterial = rootObj.GetRenderMaterial(true);
if (rhinoRenderMaterial is null)
if (rootObj.Attributes.MaterialSource == ObjectMaterialSource.MaterialFromLayer)
{
if (rootObj.GetMaterial(true) is Material rhinoMaterial)
{
rhinoRenderMaterial = RenderMaterial.FromMaterial(rhinoMaterial, currentDoc);
}
else // could not get rendermaterial or material
{
continue;
}
continue;
}
// materials are confusing in rhino. we need both render material and material because objects can have either assigned
RenderMaterial? rhinoRenderMaterial = rootObj.GetRenderMaterial(true);
Material? rhinoMaterial = rootObj.GetMaterial(true);
try
{
ProcessObjectMaterial(rootObj.Id.ToString(), rhinoRenderMaterial, rootObj.Attributes.MaterialSource);
ProcessObjectMaterial(
rootObj.Id.ToString(),
rhinoRenderMaterial,
rhinoMaterial,
rootObj.Attributes.MaterialSource
);
}
catch (Exception ex) when (!ex.IsFatal())
{
@@ -122,29 +150,19 @@ public class RhinoMaterialUnpacker
// Stage 2: make sure we collect layer materials as well
foreach (Layer layer in layers)
{
// materials are confusing in rhino - some objects can have render materials, other may only have a material.
// see: https://discourse.mcneel.com/t/getting-material-from-rhinoobject/114870/6
// basically, materials (old) are created PER OBJECT if they are assigned per object. This means the same material will have diff ids when called from the material table
// unfortunately, in the case where no rendermaterial exists, we'll have to create duplicate proxies.
// materials are confusing in rhino. we will first try to get layer render material and then material by index if null
RenderMaterial? rhinoRenderMaterial = layer.RenderMaterial;
if (rhinoRenderMaterial is null)
{
if (layer.RenderMaterialIndex == -1) // no material assigned
{
continue;
}
else
{
rhinoRenderMaterial = RenderMaterial.FromMaterial(
currentDoc.Materials[layer.RenderMaterialIndex],
currentDoc
);
}
}
Material? rhinoMaterial =
layer.RenderMaterialIndex == -1 ? null : currentDoc.Materials[layer.RenderMaterialIndex];
try
{
ProcessObjectMaterial(layer.Id.ToString(), rhinoRenderMaterial, ObjectMaterialSource.MaterialFromObject);
ProcessObjectMaterial(
layer.Id.ToString(),
rhinoRenderMaterial,
rhinoMaterial,
ObjectMaterialSource.MaterialFromObject
);
}
catch (Exception ex) when (!ex.IsFatal())
{
@@ -155,6 +173,21 @@ public class RhinoMaterialUnpacker
return RenderMaterialProxies.Values.ToList();
}
// converts a rhino material to a rhino render material
private RenderMaterial ConvertMaterialToRenderMaterial(Material material)
{
// get physically based render material
Material pbMaterial = material;
if (!material.IsPhysicallyBased)
{
pbMaterial = new();
pbMaterial.CopyFrom(material);
pbMaterial.ToPhysicallyBased();
}
return RenderMaterial.FromMaterial(pbMaterial, null);
}
private SpeckleRenderMaterial ConvertRenderMaterialToSpeckle(RenderMaterial renderMaterial)
{
PhysicallyBasedMaterial pbRenderMaterial = renderMaterial.ConvertToPhysicallyBased(
@@ -16,7 +16,6 @@ using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Instances;
using RenderMaterial = Rhino.Render.RenderMaterial;
namespace Speckle.Connectors.Rhino.Operations.Receive;
@@ -104,7 +103,10 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
if (unpackedRoot.RenderMaterialProxies != null)
{
using var _ = _activityFactory.Start("Render Materials");
_materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseLayerName);
_threadContext.RunOnMain(() =>
{
_materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseLayerName);
});
}
if (unpackedRoot.ColorProxies != null)
@@ -301,16 +303,18 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
{
var objectId = originalObject.applicationId ?? originalObject.id.NotNull();
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(objectId, out RenderMaterial oRenderMaterial))
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(objectId, out int mIndex))
{
atts.RenderMaterial = oRenderMaterial; // no need to set source since setting render material handles this
atts.MaterialIndex = mIndex;
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
}
else if (
parentObjectId is not null
&& (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(parentObjectId, out RenderMaterial pRenderMaterial))
&& (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(parentObjectId, out int mIndexSpeckleObj))
)
{
atts.RenderMaterial = pRenderMaterial; // no need to set source since setting render material handles this
atts.MaterialIndex = mIndexSpeckleObj;
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
}
if (_colorBaker.ObjectColorsIdMap.TryGetValue(objectId, out (Color, ObjectColorSource) color))
+72 -18
View File
@@ -1,26 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Target AfterTargets="Build" Name="AfterBuildTekla" Condition="'$(TeklaVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<Target AfterTargets="Build" Name="AfterBuildTekla" Condition="'$(TeklaVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
<ItemGroup>
<TeklaDlls Include="$(TargetDir)\**\*.*" Exclude="$(TargetDir)*.bmp" />
<TeklaBmp Include="$(TargetDir)\Assets\et_element_Speckle.bmp"/>
<TeklaBmp Include="$(TargetDir)\Resources\et_element_Speckle.bmp"/>
<TeklaSvg Include="$(TargetDir)\Resources\speckle.svg"/>
<TeklaRibbonXml Include="$(TargetDir)\Resources\Speckle-Ribbon.xml"/>
</ItemGroup>
<Message Text="Tekla Version $(TeklaVersion)" Importance="high"/>
<Copy Condition="Exists('$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0')"
DestinationFolder="$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0\Environments\common\extensions\Speckle3TeklaStructures\%(RecursiveDir)"
SourceFiles="@(TeklaDlls)" />
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<Copy Condition="Exists('$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0')"
DestinationFolder="$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0\Bitmaps"
SourceFiles="@(TeklaBmp)" />
</ItemGroup>
<Copy Condition="Exists('C:\TeklaStructures\2024.0')"
DestinationFolder="C:\TeklaStructures\2024.0\Environments\common\extensions\Speckle3TeklaStructures\%(RecursiveDir)"
SourceFiles="@(TeklaDlls)" />
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<Copy Condition="Exists('C:\TeklaStructures\2024.0')"
DestinationFolder="$(ProgramFiles)\TeklaStructures\2024.0\bin\Env\Bitmaps"
SourceFiles="@(TeklaBmp)" />
</ItemGroup>
<!-- Define installation paths -->
<PropertyGroup>
<ProgramDataTeklaPath>$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0</ProgramDataTeklaPath>
<DirectTeklaPath>C:\TeklaStructures\$(TeklaVersion).0</DirectTeklaPath>
<!-- Define extension and ribbon paths -->
<ProgramDataRibbonPath>$(ProgramDataTeklaPath)\Environments\common\system\Ribbons\CustomTabs\Modeling</ProgramDataRibbonPath>
<DirectRibbonPath>$(DirectTeklaPath)\Environments\common\system\Ribbons\CustomTabs\Modeling</DirectRibbonPath>
<SpeckleExtensionPath Condition="Exists('$(ProgramDataTeklaPath)')">$(ProgramDataTeklaPath)\Environments\common\extensions\Speckle3TeklaStructures</SpeckleExtensionPath>
<SpeckleExtensionPath Condition="Exists('$(DirectTeklaPath)')">$(DirectTeklaPath)\Environments\common\extensions\Speckle3TeklaStructures</SpeckleExtensionPath>
</PropertyGroup>
<!-- Delete win-arm64 folder if it exists in the active installation path -->
<RemoveDir
Condition="Exists('$(SpeckleExtensionPath)\runtimes\win-arm64\native')"
Directories="$(SpeckleExtensionPath)\runtimes\win-arm64\native" />
<!-- Check which installation path exists for the specific version -->
<PropertyGroup>
<TeklaInstallPath Condition="Exists('$(ProgramDataTeklaPath)')">$(ProgramDataTeklaPath)</TeklaInstallPath>
<TeklaInstallPath Condition="Exists('$(DirectTeklaPath)')">$(DirectTeklaPath)</TeklaInstallPath>
</PropertyGroup>
<!-- Copy DLLs to extension folder -->
<Copy
Condition="'$(SpeckleExtensionPath)' != ''"
DestinationFolder="$(SpeckleExtensionPath)\%(RecursiveDir)"
SourceFiles="@(TeklaDlls)" />
<!-- Copy SVG to Resources folder -->
<Copy
Condition="'$(SpeckleExtensionPath)' != ''"
DestinationFolder="$(SpeckleExtensionPath)\Resources"
SourceFiles="@(TeklaSvg)" />
<!-- Copy BMP to Bitmaps folder -->
<Copy
Condition="'$(TeklaInstallPath)' != ''"
DestinationFolder="$(TeklaInstallPath)\Bitmaps"
SourceFiles="@(TeklaBmp)" />
<!-- Create Ribbon directories if they don't exist -->
<MakeDir Directories="$(ProgramDataRibbonPath)"
Condition="Exists('$(ProgramDataTeklaPath)') And !Exists('$(ProgramDataRibbonPath)')" />
<MakeDir Directories="$(DirectRibbonPath)"
Condition="Exists('$(DirectTeklaPath)') And !Exists('$(DirectRibbonPath)')" />
<!-- Copy the XML file to both possible destinations -->
<Copy
SourceFiles="@(TeklaRibbonXml)"
DestinationFolder="$(ProgramDataRibbonPath)"
Condition="Exists('$(ProgramDataTeklaPath)')" />
<Copy
SourceFiles="@(TeklaRibbonXml)"
DestinationFolder="$(DirectRibbonPath)"
Condition="Exists('$(DirectTeklaPath)')" />
<!-- Copy the SVG file to both possible ribbon destinations -->
<Copy
SourceFiles="@(TeklaSvg)"
DestinationFolder="$(ProgramDataRibbonPath)"
Condition="Exists('$(ProgramDataTeklaPath)')" />
<Copy
SourceFiles="@(TeklaSvg)"
DestinationFolder="$(DirectRibbonPath)"
Condition="Exists('$(DirectTeklaPath)')" />
</Target>
</Project>
@@ -325,9 +325,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -335,8 +335,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -362,7 +362,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"LibTessDotNet": {
@@ -412,35 +412,35 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -406,9 +406,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -416,8 +416,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -443,7 +443,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"LibTessDotNet": {
@@ -493,35 +493,35 @@
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -144,7 +144,7 @@ public sealed class TeklaSendBinding : ISendBinding
.ServiceProvider.GetRequiredService<SendOperation<ModelObject>>()
.Execute(
teklaObjects,
modelCard.GetSendInfo(_speckleApplication.Slug),
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
cancellationItem.Token
);
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Tab Header="Speckle" IsCollapsed="false" IsUserDefined="true">
<SimpleButton X="0" Y="0" Width="4" Height="4" Command="Plugin.CatalogPluginComponentItem?Speckle" Text="Speckle (Beta)" Icon="speckle.svg" ShowText="true" ShowIcon="true" Tooltip="Speckle Next-Gen Tekla Structures Connector"/>
</Tab>
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 166 KiB

@@ -13,6 +13,16 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\speckle.svg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Resources\Speckle-Ribbon.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Bindings\TeklaBasicConnectorBinding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\TeklaSelectionBinding.cs" />
@@ -36,4 +46,8 @@
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)app.config" />
</ItemGroup>
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)Resources\Speckle-Ribbon.xml" />
<Content Include="$(MSBuildThisFileDirectory)Resources\speckle.svg" />
</ItemGroup>
</Project>
@@ -219,7 +219,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -243,40 +243,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -258,7 +258,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -282,40 +282,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -258,7 +258,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -282,40 +282,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -259,9 +259,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -269,8 +269,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -287,7 +287,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -326,40 +326,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -215,9 +215,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -225,8 +225,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -243,7 +243,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -282,39 +282,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -4,50 +4,120 @@ using Speckle.Objects.Data;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
namespace Speckle.Converters.Rhino7.ToHost.TopLevel;
namespace Speckle.Converters.Autocad.ToHost.Geometry;
[NameAndRankValue(typeof(DataObject), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class DataObjectConverter : IToHostTopLevelConverter, ITypedConverter<DataObject, List<(ADB.Entity a, Base b)>>
{
private readonly ITypedConverter<SOG.Line, ADB.Line> _lineConverter;
private readonly ITypedConverter<SOG.Polyline, ADB.Polyline3d> _polylineConverter;
private readonly ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> _meshConverter;
private readonly ITypedConverter<SOG.Arc, ADB.Arc> _arcConverter;
private readonly ITypedConverter<SOG.BrepX, List<(ADB.Entity a, Base b)>> _brepXConverter;
private readonly ITypedConverter<SOG.Circle, ADB.Circle> _circleConverter;
private readonly ITypedConverter<SOG.Curve, ADB.Curve> _curveConverter;
private readonly ITypedConverter<SOG.Ellipse, ADB.Ellipse> _ellipseConverter;
private readonly ITypedConverter<SOG.ExtrusionX, List<(ADB.Entity a, Base b)>> _extrusionXConverter;
private readonly ITypedConverter<SOG.Line, ADB.Line> _lineConverter;
private readonly ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> _meshConverter;
private readonly ITypedConverter<SOG.Point, ADB.DBPoint> _pointConverter;
private readonly ITypedConverter<SOG.Polycurve, List<(ADB.Entity a, Base b)>> _polycurveConverter;
private readonly ITypedConverter<SOG.Polyline, ADB.Polyline3d> _polylineConverter;
private readonly ITypedConverter<SOG.SubDX, List<(ADB.Entity a, Base b)>> _subDXConverter;
public DataObjectConverter(
ITypedConverter<SOG.Line, ADB.Line> lineConverter,
ITypedConverter<SOG.Polyline, ADB.Polyline3d> polylineConverter,
ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> meshConverter,
ITypedConverter<SOG.Arc, ADB.Arc> arcConverter,
ITypedConverter<SOG.Point, ADB.DBPoint> pointConverter
ITypedConverter<SOG.BrepX, List<(ADB.Entity a, Base b)>> brepXConverter,
ITypedConverter<SOG.Circle, ADB.Circle> circleConverter,
ITypedConverter<SOG.Curve, ADB.Curve> curveConverter,
ITypedConverter<SOG.Ellipse, ADB.Ellipse> ellipseConverter,
ITypedConverter<SOG.ExtrusionX, List<(ADB.Entity a, Base b)>> extrusionXConverter,
ITypedConverter<SOG.Line, ADB.Line> lineConverter,
ITypedConverter<SOG.Mesh, ADB.PolyFaceMesh> meshConverter,
ITypedConverter<SOG.Point, ADB.DBPoint> pointConverter,
ITypedConverter<SOG.Polycurve, List<(ADB.Entity, Base)>> polycurveConverter,
ITypedConverter<SOG.Polyline, ADB.Polyline3d> polylineConverter,
ITypedConverter<SOG.SubDX, List<(ADB.Entity a, Base b)>> subDXConverter
)
{
_lineConverter = lineConverter;
_polylineConverter = polylineConverter;
_meshConverter = meshConverter;
_arcConverter = arcConverter;
_brepXConverter = brepXConverter;
_circleConverter = circleConverter;
_curveConverter = curveConverter;
_ellipseConverter = ellipseConverter;
_extrusionXConverter = extrusionXConverter;
_lineConverter = lineConverter;
_meshConverter = meshConverter;
_pointConverter = pointConverter;
_polycurveConverter = polycurveConverter;
_polylineConverter = polylineConverter;
_subDXConverter = subDXConverter;
}
public object Convert(Base target) => Convert((DataObject)target);
public List<(ADB.Entity a, Base b)> Convert(DataObject target)
{
var result = new List<ADB.Entity>();
var result = new List<(ADB.Entity a, Base b)>();
foreach (var item in target.displayValue)
{
ADB.Entity x = item switch
{
SOG.Line line => _lineConverter.Convert(line),
SOG.Polyline polyline => _polylineConverter.Convert(polyline),
SOG.Mesh mesh => _meshConverter.Convert(mesh),
SOG.Arc arc => _arcConverter.Convert(arc),
SOG.Point point => _pointConverter.Convert(point),
_ => throw new ConversionException($"Found unsupported fallback geometry: {item.GetType()}")
};
result.Add(x);
result.AddRange(ConvertDisplayObject(item));
}
return result;
}
public IEnumerable<(ADB.Entity a, Base b)> ConvertDisplayObject(Base displayObject)
{
switch (displayObject)
{
case SOG.Arc arc:
yield return (_arcConverter.Convert(arc), arc);
break;
case SOG.BrepX brepX:
foreach (var i in _brepXConverter.Convert(brepX))
{
yield return i;
}
break;
case SOG.Circle circle:
yield return (_circleConverter.Convert(circle), circle);
break;
case SOG.Curve curve:
yield return (_curveConverter.Convert(curve), curve);
break;
case SOG.Ellipse ellipse:
yield return (_ellipseConverter.Convert(ellipse), ellipse);
break;
case SOG.ExtrusionX extrusionX:
foreach (var i in _extrusionXConverter.Convert(extrusionX))
{
yield return i;
}
break;
case SOG.Line line:
yield return (_lineConverter.Convert(line), line);
break;
case SOG.Mesh mesh:
yield return (_meshConverter.Convert(mesh), mesh);
break;
case SOG.Point point:
yield return (_pointConverter.Convert(point), point);
break;
case SOG.Polycurve polycurve:
foreach (var i in _polycurveConverter.Convert(polycurve))
{
yield return i;
}
break;
case SOG.Polyline polyline:
yield return (_polylineConverter.Convert(polyline), polyline);
break;
case SOG.SubDX subDX:
foreach (var i in _subDXConverter.Convert(subDX))
{
yield return i;
}
break;
default:
throw new ConversionException($"Found unsupported geometry: {displayObject.GetType()}");
}
return result.Zip(target.displayValue, (a, b) => (a, b)).ToList();
}
}
@@ -1,3 +1,4 @@
using Autodesk.AutoCAD.DatabaseServices;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Sdk.Models;
@@ -10,33 +11,36 @@ namespace Speckle.Converters.AutocadShared.ToHost.Geometry;
/// Otherwise we convert it as spline (list of ADB.Entity) that switch cases according to each segment type.
/// </summary>
[NameAndRankValue(typeof(SOG.Polycurve), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class PolycurveToHostConverter : IToHostTopLevelConverter
public class PolycurveToHostConverter
: IToHostTopLevelConverter,
ITypedConverter<SOG.Polycurve, List<(Entity a, Base b)>>
{
private readonly ITypedConverter<SOG.Polycurve, ADB.Polyline> _polylineConverter;
private readonly ITypedConverter<SOG.Polycurve, List<ADB.Entity>> _splineConverter;
private readonly ITypedConverter<SOG.Polycurve, List<(Entity, Base)>> _splineConverter;
public PolycurveToHostConverter(
ITypedConverter<SOG.Polycurve, ADB.Polyline> polylineConverter,
ITypedConverter<SOG.Polycurve, List<ADB.Entity>> splineConverter
ITypedConverter<SOG.Polycurve, List<(Entity, Base)>> splineConverter
)
{
_polylineConverter = polylineConverter;
_splineConverter = splineConverter;
}
public object Convert(Base target)
public object Convert(Base target) => Convert((SOG.Polycurve)target);
public List<(Entity, Base)> Convert(SOG.Polycurve target)
{
SOG.Polycurve polycurve = (SOG.Polycurve)target;
bool convertAsSpline = polycurve.segments.Any(s => s is not SOG.Line and not SOG.Arc);
bool isPlanar = IsPolycurvePlanar(polycurve);
bool convertAsSpline = target.segments.Any(s => s is not SOG.Line and not SOG.Arc);
bool isPlanar = IsPolycurvePlanar(target);
if (convertAsSpline || !isPlanar)
{
return _splineConverter.Convert(polycurve);
return _splineConverter.Convert(target);
}
else
{
return _polylineConverter.Convert(polycurve);
return new() { (_polylineConverter.Convert(target), target) };
}
}
@@ -1,11 +1,13 @@
using Autodesk.AutoCAD.DatabaseServices;
using Speckle.Converters.Common.Objects;
using Speckle.Sdk.Models;
namespace Speckle.Converters.AutocadShared.ToHost.Raw;
/// <summary>
/// Polycurve segments might appear in different ICurve types which requires to handle separately for each segment.
/// </summary>
public class PolycurveToHostSplineRawConverter : ITypedConverter<SOG.Polycurve, List<ADB.Entity>>
public class PolycurveToHostSplineRawConverter : ITypedConverter<SOG.Polycurve, List<(Entity, Base)>>
{
private readonly ITypedConverter<SOG.Line, ADB.Line> _lineConverter;
private readonly ITypedConverter<SOG.Polyline, ADB.Polyline3d> _polylineConverter;
@@ -25,7 +27,7 @@ public class PolycurveToHostSplineRawConverter : ITypedConverter<SOG.Polycurve,
_curveConverter = curveConverter;
}
public List<ADB.Entity> Convert(SOG.Polycurve target)
public List<(Entity, Base)> Convert(SOG.Polycurve target)
{
// POC: We can improve this once we have IIndex of raw converters and we can get rid of case converters?
// POC: Should we join entities?
@@ -52,6 +54,6 @@ public class PolycurveToHostSplineRawConverter : ITypedConverter<SOG.Polycurve,
}
}
return list;
return list.Zip(target.segments, (a, b) => ((ADB.Entity)a, (Base)b)).ToList();
}
}
@@ -0,0 +1,129 @@
namespace Speckle.Converters.CSiShared.Extensions;
/// <summary>
/// Csi Api returns a one-dimensional array of the table data. Any cDatabaseTable queries will require some processing.
/// The TableData extension processes queries for GetTableForDisplayArray.
/// </summary>
/// <remarks>
/// TableData implemented as a record. Reasons for this include:
/// <list type="bullet">
/// <item><description>Keeping data immutable (preventing accidental modifications).</description></item>
/// <item><description>Better choice for large data sets (heap allocation).</description></item>
/// </list>
/// Notes:
/// <list type="bullet">
/// <item><description>A cDatabaseTable query returns ALL objects of a type. This is an expensive operation. However, the typical use-case involves sending the entire Etabs/Sap model.</description></item>
/// <item><description>High initial memory usage when creating dictionaries for all rows of data.</description></item>
/// <item><description>Benefits of the dictionary evident during send operations when most/all objects are sent (and thus queried).</description></item>
/// <item><description>Single upfront dictionary creation preferred over repeated on-demand creation</description></item>
/// <item><description>Yes, Csi returns all data as strings. Even int, double etc.</description></item>
/// </list>
/// </remarks>
public record TableData
{
private readonly string[] _columnNames; // "fieldKeys" in api docs
private readonly string[] _rawTableData; // indicating raw, one-dimensional array of table data (before processing)
private readonly int _rowCount; // Number of rows
private IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>>? _processedRows; // Cached data structure
private readonly string _indexColumn; // column used to index/identify rows (typically, "UniqueName")
public TableData(string[] columnNames, string[] rawTableData, int rowCount, string indexColumn)
{
_columnNames = columnNames;
_rawTableData = rawTableData;
_rowCount = rowCount;
_indexColumn = indexColumn;
}
/// <summary>
/// Gets table data as a dictionary mapping indexColumn (typically "UniqueName" to _processedRows).
/// Each row is itself a dictionary mapping column names to their values.
/// Computed once on first access and cached.
/// </summary>
/// <remarks>
/// Motivation:
/// <list type="bullet">
/// <item><description>One-dimensional array => structured dictionary format</description></item>
/// <item><description>Each row keyed by its "UniqueName" value</description></item>
/// <item><description>Each row value is itself a dictionary of field keys to values</description></item>
/// </list>
/// </remarks>
public IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> Rows
{
get
{
if (_processedRows != null) // Lazy loading - only build dictionary when first accessed
{
return _processedRows;
}
var columnsPerRow = _columnNames.Length;
var indexColumnIndex = Array.IndexOf(_columnNames, _indexColumn);
if (indexColumnIndex == -1)
{
throw new InvalidOperationException(
$"Row data structured according specified '{_indexColumn}' field. This was not found in the database."
);
}
// Pre-size dictionary with known capacity
var rows = new Dictionary<string, IReadOnlyDictionary<string, string>>(_rowCount);
// Create a field index lookup to avoid repeated Array.IndexOf calls
var fieldIndexLookup = new Dictionary<string, int>(columnsPerRow);
for (int i = 0; i < _columnNames.Length; i++)
{
fieldIndexLookup[_columnNames[i]] = i;
}
// Process each row
for (int rowStart = 0; rowStart < _rawTableData.Length; rowStart += columnsPerRow)
{
var keyValue = _rawTableData[rowStart + indexColumnIndex];
// Pre-size the row dictionary
var row = new Dictionary<string, string>(columnsPerRow, StringComparer.Ordinal);
// Use index lookup instead of repeated string comparisons
foreach (var kvp in fieldIndexLookup)
{
row[kvp.Key] = _rawTableData[rowStart + kvp.Value];
}
rows[keyValue] = row;
}
_processedRows = rows;
return _processedRows;
}
}
/// <summary>
/// Retrieves a string value from a specific row and column from the table data.
/// </summary>
/// <param name="rowKey">The unique identifier for the row, matching the value in the index column (e.g., "UniqueName")</param>
/// <param name="columnName">The name of the column containing the desired value</param>
/// <returns>The string value found at the specified row and column intersection</returns>
/// <exception cref="InvalidOperationException">Thrown when either the row or column is not found in the table</exception>
public string GetRowValue(string rowKey, string columnName)
{
if (TryGetValue(rowKey, columnName, out var value))
{
return value;
}
throw new InvalidOperationException($"Failed to get value for row '{rowKey}', column '{columnName}'");
}
private bool TryGetValue(string rowKey, string columnName, out string value)
{
if (Rows.TryGetValue(rowKey, out var row) && row.TryGetValue(columnName, out value!))
{
return true;
}
value = string.Empty;
return false;
}
}
@@ -20,8 +20,9 @@ public static class ServiceRegistration
serviceCollection.AddScoped<CsiFramePropertiesExtractor>();
serviceCollection.AddScoped<CsiJointPropertiesExtractor>();
serviceCollection.AddScoped<CsiShellPropertiesExtractor>();
serviceCollection.AddScoped<SharedPropertiesExtractor>();
serviceCollection.AddScoped<DatabaseTableExtractor>();
serviceCollection.AddScoped<DisplayValueExtractor>();
serviceCollection.AddScoped<SharedPropertiesExtractor>();
// Register connector caches
serviceCollection.AddScoped<CsiToSpeckleCacheSingleton>();
@@ -14,6 +14,7 @@
<Compile Include="$(MSBuildThisFileDirectory)CsiRootToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CsiToSpeckleUnitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CsiWrappers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DatabaseTableExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SpeckleApplicationIdExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
@@ -21,6 +22,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Helpers\CsiJointPropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Helpers\CsiShellPropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Helpers\CsiToSpeckleCacheSingleton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Helpers\DatabaseTableExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\LineToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\MeshToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Raw\PointToSpeckleConverter.cs" />
@@ -10,13 +10,18 @@ namespace Speckle.Converters.CSiShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Design Decisions:
/// - Individual methods preferred over batched calls due to:
/// * Independent API calls with no performance gain from batching (?)
/// * Easier debugging and error tracing
/// * Simpler maintenance as each method maps to one API concept
/// Integration:
/// - Part of the property extraction hierarchy
/// - Used by <see cref="SharedPropertiesExtractor"/> for delegating frame property extraction
/// <list type="bullet">
/// <item>
/// <description>
/// Individual methods preferred over batched calls due to:
/// <list type="bullet">
/// <item><description>Independent API calls with no performance gain from batching (?)</description></item>
/// <item><description>Easier debugging and error tracing</description></item>
/// <item><description>Simpler maintenance as each method maps to one API concept</description></item>
/// </list>
/// </description>
/// </item>
/// </list>
/// </remarks>
public sealed class CsiFramePropertiesExtractor
{
@@ -10,16 +10,24 @@ namespace Speckle.Converters.CSiShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Design Decisions:
/// - Individual methods preferred over batched calls due to:
/// * Independent API calls with no performance gain from batching (?)
/// * Easier debugging and error tracing
/// * Simpler maintenance as each method maps to one API concept
/// <list type="bullet">
/// <item>
/// <description>
/// Individual methods preferred over batched calls due to:
/// <list type="bullet">
/// <item><description>Independent API calls with no performance gain from batching (?)</description></item>
/// <item><description>Easier debugging and error tracing</description></item>
/// <item><description>Simpler maintenance as each method maps to one API concept</description></item>
/// </list>
/// </description>
/// </item>
/// </list>
///
/// Responsibilities:
/// - Provides a focused interface for extracting properties specific to joint elements.
/// - Ensures consistency in property extraction logic across supported CSi products.
/// Integration:
/// - Part of the property extraction hierarchy
/// - Used by <see cref="SharedPropertiesExtractor"/> for delegating joint property extraction
/// <list type="bullet">
/// <item><description>Provides a focused interface for extracting properties specific to joint elements.</description></item>
/// <item><description>Ensures consistency in property extraction logic across supported CSi products.</description></item>
/// </list>
/// </remarks>
public sealed class CsiJointPropertiesExtractor
{
@@ -10,13 +10,18 @@ namespace Speckle.Converters.CSiShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Design Decisions:
/// - Individual methods preferred over batched calls due to:
/// * Independent API calls with no performance gain from batching (?)
/// * Easier debugging and error tracing
/// * Simpler maintenance as each method maps to one API concept
/// Integration:
/// - Part of the property extraction hierarchy
/// - Used by <see cref="SharedPropertiesExtractor"/> for delegating shell property extraction
/// <list type="bullet">
/// <item>
/// <description>
/// Individual methods preferred over batched calls due to:
/// <list type="bullet">
/// <item><description>Independent API calls with no performance gain from batching (?)</description></item>
/// <item><description>Easier debugging and error tracing</description></item>
/// <item><description>Simpler maintenance as each method maps to one API concept</description></item>
/// </list>
/// </description>
/// </item>
/// </list>
/// </remarks>
public sealed class CsiShellPropertiesExtractor
{
@@ -0,0 +1,87 @@
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared.Extensions;
namespace Speckle.Converters.CSiShared.ToSpeckle.Helpers;
/// <summary>
/// Implementation of database table extraction and caching for CSI API.
/// </summary>
/// <remarks>
/// In the current context, an interface was not deemed necessary. We only have this implementation.
/// Consider introducing an interface IDatabaseTableExtractor if the need arises.
/// </remarks>
public class DatabaseTableExtractor
{
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
private readonly Dictionary<string, TableData> _tableCache;
private const string DEFAULT_KEY_FIELD = "UniqueName";
public DatabaseTableExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
{
_settingsStore = settingsStore;
_tableCache = [];
}
/// <summary>
/// Uses the cDatabaseTables.GetTableForDisplayArray() to request data for a specified table name.
/// Processes the one-dimensional array return with the <see cref="Speckle.Converters.CSiShared.Extensions.TableData"/>
/// extension for improved workability/reliability.
/// </summary>
/// <param name="tableName">String identifying the table to fetch. This typically matches the UI.</param>
/// <param name="indexingColumn">Key used to organize and (later) lookup specific rows of data. Optional argument, default is "UniqueName"</param>
/// <param name="requestedColumns">Optional list of specific fields to fetch. If null or empty, all fields will be returned. Ask Björn about how to determine these strings.</param>
/// <returns>TableData containing the requested fields and records</returns>
public TableData GetTableData(string tableName, string? indexingColumn = null, string[]? requestedColumns = null)
{
string tableKeyField = indexingColumn ?? DEFAULT_KEY_FIELD; // most queries will use "UniqueName"
string cacheKey = $"{tableName}_{tableKeyField}";
if (_tableCache.TryGetValue(cacheKey, out var cachedData))
{
return cachedData;
}
var tableData = FetchTableData(tableName, tableKeyField, requestedColumns);
_tableCache[cacheKey] = tableData;
return tableData;
}
public void RefreshTable(string tableKey, string? keyField = null) =>
_tableCache.Remove($"{tableKey}_{keyField ?? DEFAULT_KEY_FIELD}");
public void ClearCache() => _tableCache.Clear();
private TableData FetchTableData(string tableName, string indexingColumn, string[]? requestedColumns = null)
{
string[] requestedFields = requestedColumns ?? []; // only fetch the keys needed (memory reduction potential)
string[] fieldsKeysIncluded = [];
string[] tableData = []; // one-dimensional gross mess
int tableVersion = 0;
int numberOfRecords = 0;
// ensure indexingColumn is included in the requested fields
// if user forgets to include indexingColumn in requestedColumns => problem when it comes to creating dictionaries!
if (requestedFields != Array.Empty<string>() && !requestedFields.Contains(indexingColumn))
{
requestedFields = [.. requestedFields, indexingColumn];
}
var result = _settingsStore.Current.SapModel.DatabaseTables.GetTableForDisplayArray(
tableName,
ref requestedFields,
string.Empty, // empty means all objects (not group-specific)
ref tableVersion,
ref fieldsKeysIncluded,
ref numberOfRecords,
ref tableData
);
if (result != 0)
{
throw new InvalidOperationException(
$"Failed to fetch table data for {tableName}. Check correctness of tableName and requestedColumns."
);
}
return new TableData(fieldsKeysIncluded, tableData, numberOfRecords, indexingColumn);
}
}
@@ -258,7 +258,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -282,40 +282,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -214,7 +214,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -238,39 +238,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -10,25 +10,30 @@ namespace Speckle.Converters.ETABSShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Responsibilities:
/// - Extracts properties only available in ETABS (e.g., Label, Level)
/// - Complements <see cref="CsiFramePropertiesExtractor"/> by adding product-specific data
/// - Follows same pattern of single-purpose methods for clear API mapping
/// <list type="bullet">
/// <item><description>Extracts properties only available in ETABS (e.g., Label, Level)</description></item>
/// <item><description>Complements <see cref="CsiFramePropertiesExtractor"/> by adding product-specific data</description></item>
/// <item><description>Follows same pattern of single-purpose methods for clear API mapping</description></item>
/// </list>
///
/// Design Decisions:
/// - Maintains separate methods for each property following CSI API structure
/// - Properties are organized by their functional groups (Object ID, Assignments, Design)
///
/// Integration:
/// - Used by <see cref="EtabsPropertiesExtractor"/> for frame-specific property extraction
/// - Works alongside CsiFramePropertiesExtractor to build complete property set
/// <list type="bullet">
/// <item><description>Maintains separate methods for each property following CSI API structure</description></item>
/// <item><description>Properties are organized by their functional groups (Object ID, Assignments, Design)</description></item>
/// </list>
/// </remarks>
public sealed class EtabsFramePropertiesExtractor
{
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
private readonly DatabaseTableExtractor _databaseTableExtractor;
public EtabsFramePropertiesExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
public EtabsFramePropertiesExtractor(
IConverterSettingsStore<CsiConversionSettings> settingsStore,
DatabaseTableExtractor databaseTableExtractor
)
{
_settingsStore = settingsStore;
_databaseTableExtractor = databaseTableExtractor;
}
public void ExtractProperties(CsiFrameWrapper frame, Dictionary<string, object?> properties)
@@ -42,6 +47,10 @@ public sealed class EtabsFramePropertiesExtractor
var design = properties.EnsureNested(ObjectPropertyCategory.DESIGN);
design["Design Procedure"] = GetDesignProcedure(frame);
var geometry = properties.EnsureNested(ObjectPropertyCategory.GEOMETRY);
double length = GetLength(frame);
geometry.AddWithUnits("Length", length, _settingsStore.Current.SpeckleUnits);
}
private (string label, string level) GetLabelAndLevel(CsiFrameWrapper frame)
@@ -81,4 +90,16 @@ public sealed class EtabsFramePropertiesExtractor
_ = _settingsStore.Current.SapModel.FrameObj.GetSpringAssignment(frame.Name, ref springPropertyName);
return springPropertyName;
}
private double GetLength(CsiFrameWrapper frame)
{
// using the DatabaseTableExtractor fetch table with key "Frame Assignments - Summary"
// limit query size to "UniqueName" and "Length" fields
string length = _databaseTableExtractor
.GetTableData("Frame Assignments - Summary", requestedColumns: ["UniqueName", "Length"])
.GetRowValue(frame.Name, "Length");
// all database data is returned as strings
return double.TryParse(length, out double result) ? result : double.NaN;
}
}
@@ -10,17 +10,17 @@ namespace Speckle.Converters.ETABSShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Responsibilities:
/// - Extracts properties only available in ETABS (e.g., Diaphragm)
/// - Complements <see cref="CsiJointPropertiesExtractor"/> by adding product-specific data
/// - Follows same pattern of single-purpose methods for clear API mapping
/// <list type="bullet">
/// <item><description>Extracts properties only available in ETABS (e.g., Diaphragm)</description></item>
/// <item><description>Complements <see cref="CsiJointPropertiesExtractor"/> by adding product-specific data</description></item>
/// <item><description>Follows same pattern of single-purpose methods for clear API mapping</description></item>
/// </list>
///
/// Design Decisions:
/// - Maintains separate methods for each property following CSI API structure
/// - Properties are organized by their functional groups (Object ID, Assignments, Design)
///
/// Integration:
/// - Used by <see cref="EtabsPropertiesExtractor"/> for joint-specific property extraction
/// - Works alongside CsiJointPropertiesExtractor to build complete property set
/// <list type="bullet">
/// <item><description>Maintains separate methods for each property following CSI API structure</description></item>
/// <item><description>Properties are organized by their functional groups (Object ID, Assignments, Design)</description></item>
/// </list>
/// </remarks>
public sealed class EtabsJointPropertiesExtractor
{
@@ -1,4 +1,3 @@
using System.Collections.Concurrent;
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared;
using Speckle.Converters.CSiShared.Extensions;
@@ -12,38 +11,40 @@ namespace Speckle.Converters.ETABSShared.ToSpeckle.Helpers;
/// </summary>
/// <remarks>
/// Responsibilities:
/// - Extracts properties only available in ETABS (e.g., Label, Level)
/// - Complements <see cref="CsiShellPropertiesExtractor"/> by adding product-specific data
/// - Follows same pattern of single-purpose methods for clear API mapping
/// <list type="bullet">
/// <item><description>Extracts properties only available in ETABS (e.g., Label, Level)</description></item>
/// <item><description>Complements <see cref="CsiShellPropertiesExtractor"/> by adding product-specific data</description></item>
/// <item><description>Follows same pattern of single-purpose methods for clear API mapping</description></item>
/// </list>
///
/// Design Decisions:
/// - Maintains separate methods for each property following CSI API structure
/// - Properties are organized by their functional groups (Object ID, Assignments, Design)
///
/// Integration:
/// - Used by <see cref="EtabsPropertiesExtractor"/> for shell-specific property extraction
/// - Works alongside CsiShellPropertiesExtractor to build complete property set
/// <list type="bullet">
/// <item><description>Maintains separate methods for each property following CSI API structure</description></item>
/// <item><description>Properties are organized by their functional groups (Object ID, Assignments, Design)</description></item>
/// </list>
/// </remarks>
public sealed class EtabsShellPropertiesExtractor
{
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
private readonly MaterialNameLookup _materialNameLookup;
private readonly CsiToSpeckleCacheSingleton _csiToSpeckleCacheSingleton;
private readonly DatabaseTableExtractor _databaseTableExtractor;
public EtabsShellPropertiesExtractor(
CsiToSpeckleCacheSingleton csiToSpeckleCacheSingleton,
IConverterSettingsStore<CsiConversionSettings> settingsStore
IConverterSettingsStore<CsiConversionSettings> settingsStore,
DatabaseTableExtractor databaseTableExtractor
)
{
_settingsStore = settingsStore;
_materialNameLookup = new MaterialNameLookup(settingsStore);
_csiToSpeckleCacheSingleton = csiToSpeckleCacheSingleton;
_databaseTableExtractor = databaseTableExtractor;
}
public void ExtractProperties(CsiShellWrapper shell, Dictionary<string, object?> properties)
{
var objectId = properties.EnsureNested(ObjectPropertyCategory.OBJECT_ID);
objectId[CommonObjectProperty.DESIGN_ORIENTATION] = GetDesignOrientation(shell);
string designOrientation = GetDesignOrientation(shell);
objectId[CommonObjectProperty.DESIGN_ORIENTATION] = designOrientation;
(objectId[CommonObjectProperty.LABEL], objectId[CommonObjectProperty.LEVEL]) = GetLabelAndLevel(shell);
var assignments = properties.EnsureNested(ObjectPropertyCategory.ASSIGNMENTS);
@@ -57,10 +58,14 @@ public sealed class EtabsShellPropertiesExtractor
// Assign Section Property to variable as this will be an argument for the GetMaterialName method
string shellAppId = shell.GetSpeckleApplicationId(_settingsStore.Current.SapModel);
string sectionId = GetSectionName(shell);
string materialId = _materialNameLookup.GetMaterialForSection(sectionId);
string materialId = GetMaterialForSection(sectionId, designOrientation);
assignments[ObjectPropertyKey.SECTION_ID] = sectionId;
assignments[ObjectPropertyKey.MATERIAL_ID] = materialId;
var geometry = properties.EnsureNested(ObjectPropertyCategory.GEOMETRY);
double area = GetArea(shell, designOrientation);
geometry.AddWithUnits("Area", area, $"{_settingsStore.Current.SpeckleUnits}²");
// store the object, section, and material id relationships in their corresponding caches to be accessed by the connector
if (!string.IsNullOrEmpty(sectionId))
{
@@ -151,71 +156,36 @@ public sealed class EtabsShellPropertiesExtractor
return sectionName;
}
// TODO: This is a temporary solution until proper DatabaseTables implementation is available.
// FrameObj can use the following query: PropFrame.GetMaterial
// AreaObj doesn't have a PropArea.GetMaterial method
// So, what to do? Simplest solution: query the cDatabaseTable for the summary of area sections
// Cache the results as a dictionary where keys are sectionName and values are materialId
// Use the cached result to return the material string given a section name
// This is a temporary solution! The use of cDatabaseTable are being explored as a way to simplify a lot moving forward
private sealed class MaterialNameLookup
private string GetMaterialForSection(string sectionName, string designOrientation)
{
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
private readonly ConcurrentDictionary<string, string> _materialLookup = new();
private bool _isInitialized;
public MaterialNameLookup(IConverterSettingsStore<CsiConversionSettings> settingsStore)
if (designOrientation == "Null") // openings don't have a material
{
_settingsStore = settingsStore;
return string.Empty;
}
string materialId = _databaseTableExtractor
.GetTableData("Area Section Property Definitions - Summary", "Name", ["Name", "Material"])
.GetRowValue(sectionName, "Material");
return materialId;
}
public string GetMaterialForSection(string sectionName)
private double GetArea(CsiShellWrapper shell, string designOrientation)
{
// database to use depends on sub shell-type
string tableKey = designOrientation switch
{
if (!_isInitialized)
{
InitializeCache();
}
"Floor" => "Floor Object Connectivity",
"Wall" => "Wall Object Connectivity",
"Null" => "Null Area Object Connectivity",
_ => throw new ArgumentException($"Unexpected design orientation: {designOrientation}")
};
return _materialLookup.TryGetValue(sectionName, out string? value) ? value : string.Empty;
}
// using the DatabaseTableExtractor fetch table with key from the designOrientation
// limit query size to "UniqueName" and "Area"
string area = _databaseTableExtractor
.GetTableData(tableKey, requestedColumns: ["UniqueName", "Area"])
.GetRowValue(shell.Name, "Area");
private void InitializeCache()
{
string[] fieldKeyList = [],
fieldKeysIncluded = [],
tableData = [];
int tableVersion = 0,
numberOfRecords = 0;
int result = _settingsStore.Current.SapModel.DatabaseTables.GetTableForDisplayArray(
"Area Section Property Definitions - Summary",
ref fieldKeyList,
"",
ref tableVersion,
ref fieldKeysIncluded,
ref numberOfRecords,
ref tableData
);
if (result != 0 || numberOfRecords == 0)
{
_isInitialized = true; // Mark as initialized even on failure
return;
}
// Process each record (each record has fieldKeysIncluded.Length columns)
for (int i = 0; i < tableData.Length; i += fieldKeysIncluded.Length)
{
string name = tableData[i]; // Name is first column
string material = tableData[i + 3]; // Material is fourth column
if (!string.IsNullOrEmpty(name))
{
_materialLookup.TryAdd(name, material);
}
}
_isInitialized = true;
}
// all database data is returned as strings
return double.TryParse(area, out var result) ? result : double.NaN;
}
}
@@ -267,7 +267,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -291,40 +291,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -267,7 +267,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -291,40 +291,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -267,7 +267,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.Logging": {
@@ -291,40 +291,40 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}
@@ -224,9 +224,9 @@
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )",
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui": {
@@ -234,8 +234,8 @@
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.255, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
"Speckle.Sdk": "[3.1.0-dev.270, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
}
},
"speckle.connectors.dui.webview": {
@@ -252,7 +252,7 @@
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.255, )"
"Speckle.Objects": "[3.1.0-dev.270, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
@@ -291,39 +291,39 @@
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
"resolved": "4.1.0",
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.255"
"Speckle.Sdk": "3.1.0-dev.270"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "[7.0.5]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
"Microsoft.Extensions.Logging": "[2.2.0]",
"Speckle.DoubleNumerics": "4.0.1",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.1.0",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.255, )",
"resolved": "3.1.0-dev.255",
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
"requested": "[3.1.0-dev.270, )",
"resolved": "3.1.0-dev.270",
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
}
}
}

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