diff --git a/.gitignore b/.gitignore index 2646b24de..5b1cd032a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ tools coverage.xml output/ Images/Thumbs.db + +.claude diff --git a/Build/Consts.cs b/Build/Consts.cs index 3e0b119c5..614c69717 100644 --- a/Build/Consts.cs +++ b/Build/Consts.cs @@ -43,6 +43,7 @@ public static class Consts new("Connectors/Autocad/Speckle.Connectors.Civil3d2026", "net8.0-windows") ] ), + new("plant3d", [new("Connectors/Autocad/Speckle.Connectors.Plant3d2026", "net8.0-windows")]), new( "navisworks", [ diff --git a/Connectors/Autocad/Directory.Build.targets b/Connectors/Autocad/Directory.Build.targets index 5d93d9f50..36e48644e 100644 --- a/Connectors/Autocad/Directory.Build.targets +++ b/Connectors/Autocad/Directory.Build.targets @@ -35,4 +35,23 @@ $(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe /product C3D + + + + + + + + + + + + + + + + Program + $(ProgramW6432)\Autodesk\AutoCAD $(Plant3DVersion)\acad.exe + /product PLNT3D + diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AppUtils.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AppUtils.cs index f50818580..100f488c7 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AppUtils.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AppUtils.cs @@ -7,6 +7,8 @@ public static class AppUtils public static Speckle.Sdk.Application App => #if CIVIL3D HostApplications.Civil3D; +#elif PLANT3D + HostApplications.Plant3D; #elif AUTOCAD HostApplications.AutoCAD; #else @@ -14,11 +16,11 @@ public static class AppUtils #endif public static HostAppVersion Version => -#if AUTOCAD2026 || CIVIL3D2026 +#if AUTOCAD2026 || CIVIL3D2026 || PLANT3D2026 HostAppVersion.v2026; -#elif AUTOCAD2025 || CIVIL3D2025 +#elif AUTOCAD2025 || CIVIL3D2025 || PLANT3D2025 HostAppVersion.v2025; -#elif AUTOCAD2024 || CIVIL3D2024 +#elif AUTOCAD2024 || CIVIL3D2024 || PLANT3D2024 HostAppVersion.v2024; #elif AUTOCAD2023|| CIVIL3D2023 HostAppVersion.v2023; diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs index c8ad7ad2a..1b2ade7fc 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs @@ -11,6 +11,9 @@ using Speckle.Converters.Autocad; #elif CIVIL3D using Speckle.Converters.Civil3dShared; using Speckle.Connectors.Civil3dShared.DependencyInjection; +#elif PLANT3D +using Speckle.Connectors.Plant3dShared.DependencyInjection; +using Speckle.Converters.Plant3dShared; #endif namespace Speckle.Connectors.Autocad.Plugin; @@ -39,13 +42,18 @@ public class AutocadCommand // init DI var services = new ServiceCollection(); + _disposableLogger = services.Initialize(AppUtils.App, AppUtils.Version); + #if AUTOCAD services.AddAutocad(); services.AddAutocadConverters(); #elif CIVIL3D services.AddCivil3d(); services.AddCivil3dConverters(); +#elif PLANT3D + services.AddPlant3d(); + services.AddPlant3dConverters(); #endif Container = services.BuildServiceProvider(); Container.UseDUI(); diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadRibbon.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadRibbon.cs index f20b15fa0..6d773f330 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadRibbon.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadRibbon.cs @@ -3,7 +3,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using Autodesk.Windows; using Speckle.Sdk; -#if !AUTOCAD2025_OR_GREATER && !CIVIL3D2025_OR_GREATER +#if !AUTOCAD2025_OR_GREATER && !CIVIL3D2025_OR_GREATER && !PLANT3D2025_OR_GREATER using System.IO; #endif diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundlePlant3D/PackageContents.xml b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundlePlant3D/PackageContents.xml new file mode 100644 index 000000000..4f12bdf61 --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundlePlant3D/PackageContents.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems index 1c3a680cd..c393079d5 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems @@ -60,5 +60,8 @@ Always + + Always + \ No newline at end of file diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.csproj b/Connectors/Autocad/Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.csproj new file mode 100644 index 000000000..a4f8ff6eb --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.csproj @@ -0,0 +1,30 @@ + + + net8.0-windows + 2026 + $(DefineConstants);PLANT3D2026;PLANT3D;PLANT3D2024_OR_GREATER;PLANT3D2025_OR_GREATER;PLANT3D2026_OR_GREATER + Debug;Release;Local + + + + + win-x64 + true + false + + + + + + + + + + + + + + + + + diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3d2026/packages.lock.json b/Connectors/Autocad/Speckle.Connectors.Plant3d2026/packages.lock.json new file mode 100644 index 000000000..6d82dde10 --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3d2026/packages.lock.json @@ -0,0 +1,341 @@ +{ + "version": 2, + "dependencies": { + "net8.0-windows7.0": { + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "PolySharp": { + "type": "Direct", + "requested": "[1.14.1, )", + "resolved": "1.14.1", + "contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ==" + }, + "Speckle.AutoCAD.API": { + "type": "Direct", + "requested": "[2026.0.0, )", + "resolved": "2026.0.0", + "contentHash": "WlkV81PmbK/ftoM7aGpU6LGosKbePBQej9MO/m63rFMozX89tsitEhE12o58wu7K/4FmRUdAMolYtdK20EDBnw==" + }, + "Speckle.InterfaceGenerator": { + "type": "Direct", + "requested": "[0.9.6, )", + "resolved": "0.9.6", + "contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w==" + }, + "Speckle.Plant3D.API": { + "type": "Direct", + "requested": "[2026.0.0, )", + "resolved": "2026.0.0", + "contentHash": "VT8M6CGQl1mk3/5Ro3AEAOVrOs/cX58YRwYZnu+6xeHvsazK07Et/6kMJsde4Y7Xrpox7eBLKgYeOspiRVvX5g==", + "dependencies": { + "Speckle.AutoCAD.API": "2026.0.0" + } + }, + "GraphQL.Client": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0", + "GraphQL.Client.Abstractions.Websocket": "6.0.0", + "System.Reactive": "5.0.0" + } + }, + "GraphQL.Client.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==", + "dependencies": { + "GraphQL.Primitives": "6.0.0" + } + }, + "GraphQL.Client.Abstractions.Websocket": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0" + } + }, + "GraphQL.Primitives": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Data.Sqlite": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", + "dependencies": { + "Microsoft.Data.Sqlite.Core": "7.0.5", + "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4" + } + }, + "Microsoft.Data.Sqlite.Core": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "2.2.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Primitives": "2.2.0", + "System.ComponentModel.Annotations": "4.5.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==", + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net461": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Speckle.Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.2", + "contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA==" + }, + "Speckle.Sdk": { + "type": "Transitive", + "resolved": "3.15.3", + "contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==", + "dependencies": { + "GraphQL.Client": "6.0.0", + "Microsoft.Data.Sqlite": "7.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging": "2.2.0", + "Speckle.DoubleNumerics": "4.1.0", + "Speckle.Newtonsoft.Json": "13.0.2", + "Speckle.Sdk.Dependencies": "3.15.3" + } + }, + "Speckle.Sdk.Dependencies": { + "type": "Transitive", + "resolved": "3.15.3", + "contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==" + }, + "SQLitePCLRaw.bundle_e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==", + "dependencies": { + "SQLitePCLRaw.lib.e_sqlite3": "2.1.4", + "SQLitePCLRaw.provider.e_sqlite3": "2.1.4" + } + }, + "SQLitePCLRaw.core": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==", + "dependencies": { + "System.Memory": "4.5.3" + } + }, + "SQLitePCLRaw.lib.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==" + }, + "SQLitePCLRaw.provider.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==" + }, + "System.Reactive": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==" + }, + "speckle.connectors.common": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "[2.2.0, )", + "Speckle.Connectors.Logging": "[1.0.0, )", + "Speckle.Converters.Common": "[1.0.0, )", + "Speckle.Objects": "[3.15.3, )" + } + }, + "speckle.connectors.dui": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )", + "Speckle.Connectors.Common": "[1.0.0, )" + } + }, + "speckle.connectors.dui.webview": { + "type": "Project", + "dependencies": { + "Microsoft.Web.WebView2": "[1.0.1938.49, )", + "Speckle.Connectors.DUI": "[1.0.0, )" + } + }, + "speckle.connectors.logging": { + "type": "Project" + }, + "speckle.converters.common": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )", + "Speckle.Objects": "[3.15.3, )" + } + }, + "speckle.converters.plant3d2026": { + "type": "Project", + "dependencies": { + "Speckle.AutoCAD.API": "[2026.0.0, )", + "Speckle.Connectors.DUI.WebView": "[1.0.0, )", + "Speckle.Converters.Common": "[1.0.0, )", + "Speckle.Plant3D.API": "[2026.0.0, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Logging": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "2.2.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==" + }, + "Microsoft.Web.WebView2": { + "type": "CentralTransitive", + "requested": "[1.0.1938.49, )", + "resolved": "1.0.1938.49", + "contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw==" + }, + "Speckle.DoubleNumerics": { + "type": "CentralTransitive", + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" + }, + "Speckle.Objects": { + "type": "CentralTransitive", + "requested": "[3.15.3, )", + "resolved": "3.15.3", + "contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==", + "dependencies": { + "Speckle.Sdk": "3.15.3" + } + } + }, + "net8.0-windows7.0/win-x64": { + "SQLitePCLRaw.lib.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==" + }, + "Microsoft.Web.WebView2": { + "type": "CentralTransitive", + "requested": "[1.0.1938.49, )", + "resolved": "1.0.1938.49", + "contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw==" + } + } + } +} \ No newline at end of file diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Bindings/Plant3dSendBinding.cs b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Bindings/Plant3dSendBinding.cs new file mode 100644 index 000000000..450d02b41 --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Bindings/Plant3dSendBinding.cs @@ -0,0 +1,61 @@ +using Microsoft.Extensions.DependencyInjection; +using Speckle.Connectors.Autocad.Bindings; +using Speckle.Connectors.Common.Caching; +using Speckle.Connectors.Common.Cancellation; +using Speckle.Connectors.Common.Threading; +using Speckle.Connectors.DUI.Bindings; +using Speckle.Connectors.DUI.Bridge; +using Speckle.Connectors.DUI.Models; +using Speckle.Connectors.DUI.Models.Card.SendFilter; +using Speckle.Converters.Autocad; +using Speckle.Converters.Common; +using Speckle.Converters.Plant3dShared; + +namespace Speckle.Connectors.Plant3dShared.Bindings; + +public sealed class Plant3dSendBinding : AutocadSendBaseBinding +{ + private readonly IPlant3dConversionSettingsFactory _plant3dConversionSettingsFactory; + private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory; + + public Plant3dSendBinding( + DocumentModelStore store, + IBrowserBridge parent, + IEnumerable sendFilters, + ICancellationManager cancellationManager, + ISendConversionCache sendConversionCache, + IPlant3dConversionSettingsFactory plant3dConversionSettingsFactory, + IAutocadConversionSettingsFactory autocadConversionSettingsFactory, + IThreadContext threadContext, + ITopLevelExceptionHandler topLevelExceptionHandler, + IAppIdleManager appIdleManager, + ISendOperationManagerFactory sendOperationManagerFactory + ) + : base( + store, + parent, + sendFilters, + cancellationManager, + sendConversionCache, + threadContext, + topLevelExceptionHandler, + appIdleManager, + sendOperationManagerFactory + ) + { + _plant3dConversionSettingsFactory = plant3dConversionSettingsFactory; + _autocadConversionSettingsFactory = autocadConversionSettingsFactory; + } + + // We need a separate send binding for Plant3D due to using a different unit converter (needed for conversion settings construction) + protected override void InitializeSettings(IServiceProvider serviceProvider) + { + serviceProvider + .GetRequiredService>() + .Initialize(_plant3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument)); + + serviceProvider + .GetRequiredService>() + .Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument)); + } +} diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3dShared/DependencyInjection/Plant3dConnectorModule.cs b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/DependencyInjection/Plant3dConnectorModule.cs new file mode 100644 index 000000000..9b11f1abb --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/DependencyInjection/Plant3dConnectorModule.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Speckle.Connectors.Autocad.DependencyInjection; +using Speckle.Connectors.Autocad.Operations.Send; +using Speckle.Connectors.Common.Builders; +using Speckle.Connectors.DUI.Bindings; +using Speckle.Connectors.Plant3dShared.Bindings; +using Speckle.Connectors.Plant3dShared.Operations.Send; +using Speckle.Sdk; + +namespace Speckle.Connectors.Plant3dShared.DependencyInjection; + +public static class Plant3dConnectorModule +{ + public static void AddPlant3d(this IServiceCollection serviceCollection) + { + serviceCollection.AddAutocadBase(); + + // add send + serviceCollection.LoadSend(); + serviceCollection.AddScoped, Plant3dRootObjectBuilder>(); + serviceCollection.AddSingleton(); + + // automatically detects the Class:IClass interface pattern to register all generated interfaces + serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly()); + } +} diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Operations/Send/Plant3dRootObjectBuilder.cs b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Operations/Send/Plant3dRootObjectBuilder.cs new file mode 100644 index 000000000..b2cc81fac --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Operations/Send/Plant3dRootObjectBuilder.cs @@ -0,0 +1,50 @@ +using Autodesk.AutoCAD.DatabaseServices; +using Microsoft.Extensions.Logging; +using Speckle.Connectors.Autocad.HostApp; +using Speckle.Connectors.Autocad.Operations.Send; +using Speckle.Connectors.Common.Caching; +using Speckle.Converters.Autocad; +using Speckle.Converters.Common; +using Speckle.Sdk.Logging; +using Speckle.Sdk.Models.Collections; + +namespace Speckle.Connectors.Plant3dShared.Operations.Send; + +public sealed class Plant3dRootObjectBuilder : AutocadRootObjectBaseBuilder +{ + private readonly AutocadLayerUnpacker _layerUnpacker; + + public Plant3dRootObjectBuilder( + AutocadLayerUnpacker layerUnpacker, + IRootToSpeckleConverter converter, + IConverterSettingsStore converterSettings, + ISendConversionCache sendConversionCache, + AutocadInstanceUnpacker instanceObjectManager, + AutocadMaterialUnpacker materialUnpacker, + AutocadColorUnpacker colorUnpacker, + AutocadGroupUnpacker groupUnpacker, + ILogger logger, + ISdkActivityFactory activityFactory + ) + : base( + converter, + converterSettings, + sendConversionCache, + instanceObjectManager, + materialUnpacker, + colorUnpacker, + groupUnpacker, + logger, + activityFactory + ) + { + _layerUnpacker = layerUnpacker; + } + + public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr) + { + Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer); + + return (layer, autocadLayer); + } +} diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.projitems b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.projitems new file mode 100644 index 000000000..915ec726d --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.projitems @@ -0,0 +1,20 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912 + + + Speckle.Connectors.Plant3dShared + + + + + + + + + + + diff --git a/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.shproj b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.shproj new file mode 100644 index 000000000..9724f8108 --- /dev/null +++ b/Connectors/Autocad/Speckle.Connectors.Plant3dShared/Speckle.Connectors.Plant3dShared.shproj @@ -0,0 +1,11 @@ + + + + {B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912} + + + + + + + diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadRootToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadRootToSpeckleConverter.cs index b8b3236bd..02b753fcb 100644 --- a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadRootToSpeckleConverter.cs +++ b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadRootToSpeckleConverter.cs @@ -36,24 +36,20 @@ public class AutocadRootToSpeckleConverter : IRootToSpeckleConverter Type type = dbObject.GetType(); - using (var l = _settingsStore.Current.Document.LockDocument()) + using var l = _settingsStore.Current.Document.LockDocument(); + using var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction(); + var objectConverter = _toSpeckle.ResolveConverter(type); + + var convertedObject = objectConverter.Convert(dbObject); + + // add properties + Dictionary properties = _propertiesExtractor.GetProperties((Entity)dbObject); + if (properties.Count > 0) { - using (var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction()) - { - var objectConverter = _toSpeckle.ResolveConverter(type); - - var convertedObject = objectConverter.Convert(dbObject); - - // add properties - Dictionary properties = _propertiesExtractor.GetProperties((Entity)dbObject); - if (properties.Count > 0) - { - convertedObject["properties"] = properties; - } - - tr.Commit(); - return convertedObject; - } + convertedObject["properties"] = properties; } + + tr.Commit(); + return convertedObject; } } diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Civil3dRootToSpeckleConverter.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Civil3dRootToSpeckleConverter.cs index 980e0daab..f725c07f7 100644 --- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Civil3dRootToSpeckleConverter.cs +++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Civil3dRootToSpeckleConverter.cs @@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; using Speckle.Converters.Common.Registration; -using Speckle.Sdk; using Speckle.Sdk.Models; namespace Speckle.Converters.Civil3dShared; @@ -50,34 +49,22 @@ public class Civil3dRootToSpeckleConverter : IRootToSpeckleConverter var objectConverter = _toSpeckle.ResolveConverter(type); - try + using var l = _settingsStore.Current.Document.LockDocument(); + using var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction(); + var result = objectConverter.Convert(target); + + // This is needed to retrieve property sets on solids + // Civil entity properties are retrieved in the CivilEntityToSpeckleTopLevelConverter + if (target is not CDB.Entity && target is ADB.Entity autocadEntity) { - using (var l = _settingsStore.Current.Document.LockDocument()) + var properties = _propertiesExtractor.GetProperties(autocadEntity); + if (properties.Count > 0) { - using (var tr = _settingsStore.Current.Document.Database.TransactionManager.StartTransaction()) - { - var result = objectConverter.Convert(target); - - // This is needed to retrieve property sets on solids - // Civil entity properties are retrieved in the CivilEntityToSpeckleTopLevelConverter - if (target is not CDB.Entity && target is ADB.Entity autocadEntity) - { - var properties = _propertiesExtractor.GetProperties(autocadEntity); - if (properties.Count > 0) - { - result["properties"] = properties; - } - } - - tr.Commit(); - return result; - } + result["properties"] = properties; } } - catch (SpeckleException e) - { - Console.WriteLine(e); - throw; // Just rethrowing for now, Logs may be needed here. - } + + tr.Commit(); + return result; } } diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/PropertyHandler.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/PropertyHandler.cs index 84ae9d987..2397e885c 100644 --- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/PropertyHandler.cs +++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/Helpers/PropertyHandler.cs @@ -1,5 +1,3 @@ -using Speckle.Sdk; - namespace Speckle.Converters.Civil3dShared.Helpers; /// @@ -16,9 +14,9 @@ public sealed class PropertyHandler } catch (Exception e) when (e is InvalidOperationException - || e is ArgumentException argEx && !argEx.IsFatal() - || e is Autodesk.AutoCAD.Runtime.Exception acEx && !acEx.IsFatal() // eNotApplicable - || e is Autodesk.Civil.CivilException civilEx && !civilEx.IsFatal() + || e is ArgumentException + || e is Autodesk.AutoCAD.Runtime.Exception // eNotApplicable + || e is Autodesk.Civil.CivilException ) { value = default; diff --git a/Converters/Plant3d/Speckle.Converters.Plant3d2026/Speckle.Converters.Plant3d2026.csproj b/Converters/Plant3d/Speckle.Converters.Plant3d2026/Speckle.Converters.Plant3d2026.csproj new file mode 100644 index 000000000..3e1f87c35 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3d2026/Speckle.Converters.Plant3d2026.csproj @@ -0,0 +1,23 @@ + + + net8.0-windows + x64 + 2026 + $(DefineConstants);PLANT3D2026;PLANT3D;PLANT3D2024_OR_GREATER;PLANT3D2025_OR_GREATER;PLANT3D2026_OR_GREATER + Debug;Release;Local + + + + + + + + + + + + + + + + diff --git a/Converters/Plant3d/Speckle.Converters.Plant3d2026/packages.lock.json b/Converters/Plant3d/Speckle.Converters.Plant3d2026/packages.lock.json new file mode 100644 index 000000000..230d71b38 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3d2026/packages.lock.json @@ -0,0 +1,319 @@ +{ + "version": 2, + "dependencies": { + "net8.0-windows7.0": { + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "PolySharp": { + "type": "Direct", + "requested": "[1.14.1, )", + "resolved": "1.14.1", + "contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ==" + }, + "Speckle.AutoCAD.API": { + "type": "Direct", + "requested": "[2026.0.0, )", + "resolved": "2026.0.0", + "contentHash": "WlkV81PmbK/ftoM7aGpU6LGosKbePBQej9MO/m63rFMozX89tsitEhE12o58wu7K/4FmRUdAMolYtdK20EDBnw==" + }, + "Speckle.InterfaceGenerator": { + "type": "Direct", + "requested": "[0.9.6, )", + "resolved": "0.9.6", + "contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w==" + }, + "Speckle.Plant3D.API": { + "type": "Direct", + "requested": "[2026.0.0, )", + "resolved": "2026.0.0", + "contentHash": "VT8M6CGQl1mk3/5Ro3AEAOVrOs/cX58YRwYZnu+6xeHvsazK07Et/6kMJsde4Y7Xrpox7eBLKgYeOspiRVvX5g==", + "dependencies": { + "Speckle.AutoCAD.API": "2026.0.0" + } + }, + "GraphQL.Client": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0", + "GraphQL.Client.Abstractions.Websocket": "6.0.0", + "System.Reactive": "5.0.0" + } + }, + "GraphQL.Client.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==", + "dependencies": { + "GraphQL.Primitives": "6.0.0" + } + }, + "GraphQL.Client.Abstractions.Websocket": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0" + } + }, + "GraphQL.Primitives": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Data.Sqlite": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", + "dependencies": { + "Microsoft.Data.Sqlite.Core": "7.0.5", + "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4" + } + }, + "Microsoft.Data.Sqlite.Core": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "2.2.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Primitives": "2.2.0", + "System.ComponentModel.Annotations": "4.5.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==", + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net461": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Speckle.Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.2", + "contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA==" + }, + "Speckle.Sdk": { + "type": "Transitive", + "resolved": "3.15.3", + "contentHash": "6gmPoWTv7DwqvUae57wCLF93upE9RIjaCZFue9UMY4I6FB8vLbMGfcyiUwnUY551WlGOual15ISS3G15/kMmnw==", + "dependencies": { + "GraphQL.Client": "6.0.0", + "Microsoft.Data.Sqlite": "7.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging": "2.2.0", + "Speckle.DoubleNumerics": "4.1.0", + "Speckle.Newtonsoft.Json": "13.0.2", + "Speckle.Sdk.Dependencies": "3.15.3" + } + }, + "Speckle.Sdk.Dependencies": { + "type": "Transitive", + "resolved": "3.15.3", + "contentHash": "VLgyGi1kQNWe0fzRO0U3qnZZUQGDeFacnpn25Yy3esE0qeo4tqa1BrvXPv2ivEZbbhBkkg6+Gd+CztDIyw3Y/w==" + }, + "SQLitePCLRaw.bundle_e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==", + "dependencies": { + "SQLitePCLRaw.lib.e_sqlite3": "2.1.4", + "SQLitePCLRaw.provider.e_sqlite3": "2.1.4" + } + }, + "SQLitePCLRaw.core": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==", + "dependencies": { + "System.Memory": "4.5.3" + } + }, + "SQLitePCLRaw.lib.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==" + }, + "SQLitePCLRaw.provider.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==" + }, + "System.Reactive": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==" + }, + "speckle.connectors.common": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "[2.2.0, )", + "Speckle.Connectors.Logging": "[1.0.0, )", + "Speckle.Converters.Common": "[1.0.0, )", + "Speckle.Objects": "[3.15.3, )" + } + }, + "speckle.connectors.dui": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )", + "Speckle.Connectors.Common": "[1.0.0, )" + } + }, + "speckle.connectors.dui.webview": { + "type": "Project", + "dependencies": { + "Microsoft.Web.WebView2": "[1.0.1938.49, )", + "Speckle.Connectors.DUI": "[1.0.0, )" + } + }, + "speckle.connectors.logging": { + "type": "Project" + }, + "speckle.converters.common": { + "type": "Project", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )", + "Speckle.Objects": "[3.15.3, )" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Logging": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "2.2.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==" + }, + "Microsoft.Web.WebView2": { + "type": "CentralTransitive", + "requested": "[1.0.1938.49, )", + "resolved": "1.0.1938.49", + "contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw==" + }, + "Speckle.DoubleNumerics": { + "type": "CentralTransitive", + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" + }, + "Speckle.Objects": { + "type": "CentralTransitive", + "requested": "[3.15.3, )", + "resolved": "3.15.3", + "contentHash": "zmHnLKR46in0xH5ashD+ENlYUPDktUMZhXYYOb8aWHAG3Zxai2WvmDJtdf7pV9GTafkpR6fCo2EQTeCoY+XXxQ==", + "dependencies": { + "Speckle.Sdk": "3.15.3" + } + } + } + } +} \ No newline at end of file diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/GlobalUsings.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/GlobalUsings.cs new file mode 100644 index 000000000..edabdb007 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using PP = Autodesk.ProcessPower; +global using PPDL = Autodesk.ProcessPower.DataLinks; diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Helpers/PropertyHandler.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Helpers/PropertyHandler.cs new file mode 100644 index 000000000..c30c00e97 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Helpers/PropertyHandler.cs @@ -0,0 +1,43 @@ +using Speckle.Sdk; + +namespace Speckle.Converters.Plant3dShared.Helpers; + +/// +/// Used to help with properties on classes that may throw exceptions when accessed +/// +public sealed class PropertyHandler +{ + public bool TryGetValue(Func getValue, out T? value) + { + try + { + value = getValue(); + return true; + } + catch (Exception e) + when (e is InvalidOperationException + || e is ArgumentException argEx && !argEx.IsFatal() + || e is Autodesk.AutoCAD.Runtime.Exception acEx && !acEx.IsFatal() + ) + { + value = default; + return false; + } + } + + public bool TryAddToDictionary(Dictionary dict, string key, Func getValue) + { + if (dict.ContainsKey(key)) + { + return false; + } + + if (TryGetValue(getValue, out var value)) + { + dict.Add(key, value); + return true; + } + + return false; + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettings.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettings.cs new file mode 100644 index 000000000..a9f7a12a6 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettings.cs @@ -0,0 +1,3 @@ +namespace Speckle.Converters.Plant3dShared; + +public record Plant3dConversionSettings(Document Document, string SpeckleUnits); diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettingsFactory.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettingsFactory.cs new file mode 100644 index 000000000..08215668b --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dConversionSettingsFactory.cs @@ -0,0 +1,13 @@ +using Autodesk.AutoCAD.DatabaseServices; +using Speckle.Converters.Common; +using Speckle.InterfaceGenerator; + +namespace Speckle.Converters.Plant3dShared; + +[GenerateAutoInterface] +public class Plant3dConversionSettingsFactory(IHostToSpeckleUnitConverter unitsConverter) + : IPlant3dConversionSettingsFactory +{ + public Plant3dConversionSettings Create(Document document) => + new(document, unitsConverter.ConvertOrThrow(document.Database.Insunits)); +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dRootToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dRootToSpeckleConverter.cs new file mode 100644 index 000000000..9e0cb21cd --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dRootToSpeckleConverter.cs @@ -0,0 +1,72 @@ +using System.ComponentModel.DataAnnotations; +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; +using Speckle.Objects.Data; +using Speckle.Sdk.Models; + +namespace Speckle.Converters.Plant3dShared; + +public class Plant3dRootToSpeckleConverter( + IConverterManager toSpeckle, + IConverterSettingsStore settingsStore, + ToSpeckle.PropertiesExtractor propertiesExtractor, + ToSpeckle.Plant3dDataExtractor dataExtractor +) : IRootToSpeckleConverter +{ + public Base Convert(object target) + { + if (target is not ADB.DBObject dbObject) + { + throw new ValidationException( + $"Conversion of {target.GetType().Name} to Speckle is not supported. Only objects that inherit from DBObject are." + ); + } + + Type type = dbObject.GetType(); + + var objectConverter = toSpeckle.ResolveConverter(type); + + using var l = settingsStore.Current.Document.LockDocument(); + using var tr = settingsStore.Current.Document.Database.TransactionManager.StartTransaction(); + Base result = objectConverter.Convert(target); + + if (target is ADB.Entity autocadEntity) + { + // Extract AEC property sets and extension dictionaries + var properties = propertiesExtractor.GetProperties(autocadEntity); + + // Extract Plant3D project database properties (Tag, NominalDiameter, etc.) + var dataProperties = dataExtractor.GetDataProperties(autocadEntity); + + if (result is DataObject dataObject) + { + // Merge AEC properties + foreach (var kvp in properties) + { + dataObject.properties[kvp.Key] = kvp.Value; + } + + // Merge Plant3D data under "P&ID" key + if (dataProperties.Count > 0) + { + dataObject.properties["P&ID"] = dataProperties; + } + } + else + { + if (properties.Count > 0) + { + result["properties"] = properties; + } + if (dataProperties.Count > 0) + { + result["Plant3D Data"] = dataProperties; + } + } + } + + tr.Commit(); + return result; + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dToSpeckleUnitConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dToSpeckleUnitConverter.cs new file mode 100644 index 000000000..b7c2a7501 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Plant3dToSpeckleUnitConverter.cs @@ -0,0 +1,37 @@ +using Autodesk.AutoCAD.DatabaseServices; +using Speckle.Converters.Common; +using Speckle.Sdk.Common; +using Speckle.Sdk.Common.Exceptions; + +namespace Speckle.Converters.Plant3dShared; + +public class Plant3dToSpeckleUnitConverter : IHostToSpeckleUnitConverter +{ + private static readonly IReadOnlyDictionary s_unitsMapping = Create(); + + private static IReadOnlyDictionary Create() + { + var dict = new Dictionary(); + + dict[UnitsValue.Undefined] = Units.Meters; + dict[UnitsValue.Millimeters] = Units.Millimeters; + dict[UnitsValue.Centimeters] = Units.Centimeters; + dict[UnitsValue.Meters] = Units.Meters; + dict[UnitsValue.Kilometers] = Units.Kilometers; + dict[UnitsValue.Inches] = Units.Inches; + dict[UnitsValue.Feet] = Units.Feet; + dict[UnitsValue.Yards] = Units.Yards; + dict[UnitsValue.Miles] = Units.Miles; + return dict; + } + + public string ConvertOrThrow(UnitsValue hostUnit) + { + if (s_unitsMapping.TryGetValue(hostUnit, out string? value)) + { + return value; + } + + throw new UnitNotSupportedException($"The Unit System \"{hostUnit}\" is unsupported."); + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ServiceRegistration.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ServiceRegistration.cs new file mode 100644 index 000000000..afa28fd8a --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ServiceRegistration.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.DependencyInjection; +using Speckle.Converters.Autocad; +using Speckle.Converters.Autocad.ToHost.Helpers; +using Speckle.Converters.Common; +using Speckle.Converters.Common.Registration; +using Speckle.Converters.Plant3dShared.ToSpeckle; +using Speckle.Sdk; + +namespace Speckle.Converters.Plant3dShared; + +public static class ServiceRegistration +{ + public static void AddPlant3dConverters(this IServiceCollection serviceCollection) + { + var plant3dAssembly = typeof(Plant3dConversionSettings).Assembly; + var autocadAssembly = typeof(AutocadConversionSettings).Assembly; + // register types by default + serviceCollection.AddMatchingInterfacesAsTransient(plant3dAssembly); + serviceCollection.AddMatchingInterfacesAsTransient(autocadAssembly); + // Register single root + serviceCollection.AddRootCommon(plant3dAssembly); + + // register all application converters + serviceCollection.AddApplicationConverters(plant3dAssembly); + // serviceCollection.AddApplicationConverters(autocadAssembly); + serviceCollection.AddScoped< + IConverterSettingsStore, + ConverterSettingsStore + >(); + serviceCollection.AddScoped< + IConverterSettingsStore, + ConverterSettingsStore + >(); + serviceCollection.AddScoped(); + + // add other classes + serviceCollection.AddScoped(); // for plant3d + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.projitems b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.projitems new file mode 100644 index 000000000..aa9193041 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.projitems @@ -0,0 +1,29 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56 + + + Speckle.Converters.Plant3dShared + + + + + + + + + + + + + + + + + + + + diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.shproj b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.shproj new file mode 100644 index 000000000..292cf8614 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/Speckle.Converters.Plant3dShared.shproj @@ -0,0 +1,13 @@ + + + + C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56 + 14.0 + + + + + + + + diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/EquipmentToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/EquipmentToSpeckleConverter.cs new file mode 100644 index 000000000..9dd935920 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/EquipmentToSpeckleConverter.cs @@ -0,0 +1,11 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +[NameAndRankValue(typeof(PP.PnP3dObjects.Equipment), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] +public class EquipmentToSpeckleConverter( + IConverterManager converterManager, + IConverterSettingsStore settingsStore +) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore); diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/FallbackEntityToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/FallbackEntityToSpeckleConverter.cs new file mode 100644 index 000000000..a7607cfef --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/FallbackEntityToSpeckleConverter.cs @@ -0,0 +1,18 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; + +//using Speckle.Objects.Data; +//using Speckle.Sdk.Models; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +/// +/// Fallback converter for any ADB.Entity that doesn't have a specific Plant3D converter. +/// Uses a rank lower than SPECKLE_DEFAULT_RANK so specific converters always win. +/// +[NameAndRankValue(typeof(ADB.Entity), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK - 1)] +public class FallbackEntityToSpeckleConverter( + IConverterManager converterManager, + IConverterSettingsStore settingsStore +) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore); diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/LineSegmentToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/LineSegmentToSpeckleConverter.cs new file mode 100644 index 000000000..45f6fb396 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/LineSegmentToSpeckleConverter.cs @@ -0,0 +1,66 @@ +using Speckle.Converters.Autocad; +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Objects.Data; +using Speckle.Sdk.Models; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +/// +/// Converts P&ID LineSegment (SLINE) entities to Speckle. +/// Unlike 3D Plant objects (Pipe, Equipment) which are block references needing Explode(), +/// LineSegment is a Curve-based entity. We read its Vertices directly and produce a Polyline, +/// applying the same coordinate transforms as the AutoCAD converters. +/// +[NameAndRankValue(typeof(PP.PnIDObjects.LineSegment), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] +public class LineSegmentToSpeckleConverter : IToSpeckleTopLevelConverter +{ + private readonly IConverterSettingsStore _settingsStore; + private readonly IReferencePointConverter _referencePointConverter; + + public LineSegmentToSpeckleConverter( + IConverterSettingsStore settingsStore, + IReferencePointConverter referencePointConverter + ) + { + _settingsStore = settingsStore; + _referencePointConverter = referencePointConverter; + } + + public Base Convert(object target) + { + var lineSegment = (PP.PnIDObjects.LineSegment)target; + + // Build a flat list of xyz coordinates from the Vertices collection + var vertices = lineSegment.Vertices; + List value = new(vertices.Count * 3); + foreach (AG.Point3d pt in vertices) + { + value.Add(pt.X); + value.Add(pt.Y); + value.Add(pt.Z); + } + + // Apply the same WCS → external coordinate transform that all AutoCAD converters use + value = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(value); + + SOG.Polyline polyline = + new() + { + value = value, + closed = lineSegment.Closed, + units = _settingsStore.Current.SpeckleUnits + }; + + DataObject dataObject = + new() + { + name = lineSegment.TagValue is { Length: > 0 } tag ? tag : lineSegment.GetType().Name, + displayValue = new List { polyline }, + properties = new Dictionary(), + applicationId = lineSegment.Handle.Value.ToString() + }; + + return dataObject; + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeInlineAssetToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeInlineAssetToSpeckleConverter.cs new file mode 100644 index 000000000..a73c593b0 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeInlineAssetToSpeckleConverter.cs @@ -0,0 +1,14 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +/// +/// Converts inline pipe assets (valves, instruments, etc.) to Speckle. +/// +[NameAndRankValue(typeof(PP.PnP3dObjects.PipeInlineAsset), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] +public class PipeInlineAssetToSpeckleConverter( + IConverterManager converterManager, + IConverterSettingsStore settingsStore +) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore); diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeToSpeckleConverter.cs new file mode 100644 index 000000000..70e6278d9 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/PipeToSpeckleConverter.cs @@ -0,0 +1,11 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +[NameAndRankValue(typeof(PP.PnP3dObjects.Pipe), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] +public class PipeToSpeckleConverter( + IConverterManager converterManager, + IConverterSettingsStore settingsStore +) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore); diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/Plant3dEntityToSpeckleConverter.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/Plant3dEntityToSpeckleConverter.cs new file mode 100644 index 000000000..ba4759532 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Geometry/Plant3dEntityToSpeckleConverter.cs @@ -0,0 +1,119 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.Common.Registration; +using Speckle.Objects.Data; +using Speckle.Sdk.Models; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry; + +/// +/// Generic converter for Plant3D entity types. +/// Plant3D entities are internally block references (often nested). +/// Uses Explode() to decompose into world-coordinate geometry, then converts each +/// sub-entity using the existing AutoCAD converters (Line, Arc, Solid3d, etc.). +/// +public abstract class Plant3dEntityToSpeckleConverter : IToSpeckleTopLevelConverter +{ + private readonly IConverterManager _converterManager; + private readonly IConverterSettingsStore _settingsStore; + + private const int MAX_DEPTH = 5; + + protected Plant3dEntityToSpeckleConverter( + IConverterManager converterManager, + IConverterSettingsStore settingsStore + ) + { + _converterManager = converterManager; + _settingsStore = settingsStore; + } + + public Base Convert(object target) => ConvertEntity((ADB.Entity)target); + + private DataObject ConvertEntity(ADB.Entity entity) + { + List displayValue = ExtractDisplayValue(entity); + + // Plant3D P&ID types (Asset, LineSegment, EndLineObject, etc.) each have a TagValue property + // that provides a unique, human-readable identifier (e.g. "T-0001", "1 1/2"-CIPS-Util1049-..."). + // These types all inherit directly from ADB.Entity — there is no shared P&ID base class + // that declares TagValue, so we use reflection to read it regardless of the concrete type. + // I don't like this but its a good tradeoff since Plant3d API does not have common class to find TagValue + string name = entity.GetType().Name; + if (entity.GetType().GetProperty("TagValue")?.GetValue(entity) is string tagValue && tagValue.Length > 0) + { + name = tagValue; + } + + DataObject dataObject = + new() + { + name = name, + displayValue = displayValue, + properties = new Dictionary(), + applicationId = entity.Handle.Value.ToString() + }; + + return dataObject; + } + +#pragma warning disable CA1031 // Autodesk APIs throw various exception types + private List ExtractDisplayValue(ADB.Entity entity) + { + List results = new(); + CollectDisplayObjects(entity, results, 0); + return results; + } + + /// + /// Recursively explodes the entity to reach leaf geometry, then converts + /// each piece using the registered AutoCAD converters. + /// Explode() produces entities in world coordinates (transforms are applied), + /// unlike opening the BlockTableRecord directly which gives local coordinates. + /// + private void CollectDisplayObjects(ADB.Entity entity, List results, int depth) + { + // If this is NOT a block reference, try converting it directly + // (Line, Arc, Circle, Polyline, Solid3d, etc.) + if (entity is not ADB.BlockReference) + { + try + { + var converter = _converterManager.ResolveConverter(entity.GetType(), false); + + var converted = converter.Convert(entity); + results.Add(converted); + return; + } + catch (System.Exception) + { + // Fall through to explode on ConversionNotSupportedException or failed + } + } + + // For BlockReferences or unconvertible entities, explode to get sub-entities + // Explode produces world-coordinate geometry (block transform is applied) + if (depth >= MAX_DEPTH) + { + return; + } + + try + { + using ADB.DBObjectCollection exploded = new(); + entity.Explode(exploded); + foreach (ADB.DBObject obj in exploded) + { + if (obj is ADB.Entity subEntity) + { + CollectDisplayObjects(subEntity, results, depth + 1); + } + } + } + catch (System.Exception) + { + // Can't explode — no display value from this entity + } + } +#pragma warning restore CA1031 +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/ExtensionDictionaryExtractor.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/ExtensionDictionaryExtractor.cs new file mode 100644 index 000000000..7844b8b96 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/ExtensionDictionaryExtractor.cs @@ -0,0 +1,55 @@ +using Speckle.Converters.Common; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle; + +/// +/// Extracts extension dictionaries out from an element. Expects to be scoped per operation. +/// +public class ExtensionDictionaryExtractor +{ + private readonly IConverterSettingsStore _settingsStore; + + public ExtensionDictionaryExtractor(IConverterSettingsStore settingsStore) + { + _settingsStore = settingsStore; + } + + /// + /// Extracts extension dictionary out from an entity. Expects to be scoped per operation. + /// + public Dictionary? GetExtensionDictionary(ADB.Entity entity) + { + if (entity is null || entity.ExtensionDictionary == ADB.ObjectId.Null) + { + return null; + } + + Dictionary extensionDictionaryDict = new(); + + using (ADB.Transaction tr = _settingsStore.Current.Document.TransactionManager.StartTransaction()) + { + var extensionDictionary = (ADB.DBDictionary)tr.GetObject(entity.ExtensionDictionary, ADB.OpenMode.ForRead, false); + + foreach (ADB.DBDictionaryEntry entry in extensionDictionary) + { + if (tr.GetObject(entry.Value, ADB.OpenMode.ForRead) is ADB.Xrecord xRecord) + { + Dictionary entryDict = new(); + foreach (ADB.TypedValue xEntry in xRecord.Data) + { + entryDict[xEntry.TypeCode.ToString()] = xEntry.Value; + } + + if (entryDict.Count > 0) + { + extensionDictionaryDict[$"{entry.Key}"] = entryDict; + } + } + } + + tr.Commit(); + } + + return extensionDictionaryDict.Count > 0 ? extensionDictionaryDict : null; + } +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/Plant3dDataExtractor.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/Plant3dDataExtractor.cs new file mode 100644 index 000000000..af8095022 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/Plant3dDataExtractor.cs @@ -0,0 +1,67 @@ +using Speckle.Converters.Common; + +namespace Speckle.Converters.Plant3dShared.ToSpeckle; + +/// +/// Extracts Plant3D project database properties for entities. +/// Uses the PnPDataLinks API to find the data row linked to a DWG entity, +/// then reads all properties from that row in the project database (DCF files). +/// +public class Plant3dDataExtractor +{ + private readonly IConverterSettingsStore _settingsStore; + + public Plant3dDataExtractor(IConverterSettingsStore settingsStore) + { + _settingsStore = settingsStore; + } + + /// + /// Gets Plant3D database properties for the given entity. + /// Returns a dictionary of property name → value pairs from the project database. + /// +#pragma warning disable CA1031 // Plant3D data APIs can throw various exceptions + public Dictionary GetDataProperties(ADB.Entity entity) + { + var result = new Dictionary(); + + try + { + var database = _settingsStore.Current.Document.Database; + + // Get the DataLinksManager for this database + var dlm = PPDL.DataLinksManager.GetManager(database); + if (dlm is null) + { + return result; + } + + // Find the data row linked to this entity (returns single int row ID) + int rowId = dlm.FindAcPpRowId(entity.ObjectId); + if (rowId <= 0) + { + return result; + } + + // Read all properties from the linked row + var allProps = dlm.GetAllProperties(rowId, true); + if (allProps is not null) + { + foreach (var kvp in allProps) + { + string key = kvp.Key ?? "unknown"; + + result[key] = kvp.Value; + } + } + } + catch (PPDL.DLException) + { + // DataLinksManager not available or other API failure + } + + return result; + } + +#pragma warning restore CA1031 +} diff --git a/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/PropertiesExtractor.cs b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/PropertiesExtractor.cs new file mode 100644 index 000000000..3bfe539a0 --- /dev/null +++ b/Converters/Plant3d/Speckle.Converters.Plant3dShared/ToSpeckle/Properties/PropertiesExtractor.cs @@ -0,0 +1,43 @@ +namespace Speckle.Converters.Plant3dShared.ToSpeckle; + +/// +/// Extracts properties for Plant3D objects. +/// +public class PropertiesExtractor : Speckle.Converters.AutocadShared.ToSpeckle.IPropertiesExtractor +{ + private readonly ExtensionDictionaryExtractor _extensionDictionaryExtractor; + + public PropertiesExtractor(ExtensionDictionaryExtractor extensionDictionaryExtractor) + { + _extensionDictionaryExtractor = extensionDictionaryExtractor; + } + + public Dictionary GetProperties(ADB.Entity entity) + { + Dictionary properties = new(); + + // TODO: Add Plant3D class-specific property extraction here + // For example, extract pipe spec data, equipment data, etc. + + // add property sets and extension dictionaries to the properties dict + AddDictionaryToPropertyDictionary( + _extensionDictionaryExtractor.GetExtensionDictionary(entity), + "Extension Dictionary", + properties + ); + + return properties; + } + + private void AddDictionaryToPropertyDictionary( + Dictionary? entryDictionary, + string entryName, + Dictionary propertyDictionary + ) + { + if (entryDictionary is not null && entryDictionary.Count > 0) + { + propertyDictionary.Add(entryName, entryDictionary); + } + } +} diff --git a/Local.sln b/Local.sln index e05884507..1ecc177f0 100644 --- a/Local.sln +++ b/Local.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{DEE5DD87-39C1-BF34-B639-A387DCCF972B}" ProjectSection(SolutionItems) = preProject .github\workflows\pr.yml = .github\workflows\pr.yml @@ -309,6 +309,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk", "..\speckle-s EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk.Dependencies", "..\speckle-sharp-sdk\src\Speckle.Sdk.Dependencies\Speckle.Sdk.Dependencies.csproj", "{0677CA87-027F-D526-4463-3517F75B76EC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Plant3d2026", "Connectors\Autocad\Speckle.Connectors.Plant3d2026\Speckle.Connectors.Plant3d2026.csproj", "{B68103BE-A274-4F61-AE98-DE0B75B8BD1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Converters.Plant3d2026", "Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.csproj", "{AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.Plant3dShared", "Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.shproj", "{B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.Plant3dShared", "Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.shproj", "{C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -790,6 +798,18 @@ Global {0677CA87-027F-D526-4463-3517F75B76EC}.Local|Any CPU.Build.0 = Local|Any CPU {0677CA87-027F-D526-4463-3517F75B76EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {0677CA87-027F-D526-4463-3517F75B76EC}.Release|Any CPU.Build.0 = Release|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Local|Any CPU.ActiveCfg = Local|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Local|Any CPU.Build.0 = Local|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C}.Release|Any CPU.Build.0 = Release|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Local|Any CPU.ActiveCfg = Local|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Local|Any CPU.Build.0 = Local|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -927,5 +947,9 @@ Global {37C78F74-1AFB-8865-7C2A-03B6B4262134} = {FF13A09E-0E72-1904-124B-A4E979EF28D3} {C3BD4841-7C1F-23F7-20AB-C30A678001F5} = {FF13A09E-0E72-1904-124B-A4E979EF28D3} {02E79865-6261-CDE0-77EA-3DD2E01DACBD} = {FF13A09E-0E72-1904-124B-A4E979EF28D3} + {B68103BE-A274-4F61-AE98-DE0B75B8BD1C} = {D3670C11-52FA-1950-6D7E-27C5DEA68A33} + {AEF997CA-1413-4DF7-AFA7-AB4DC9BF92FF} = {D3670C11-52FA-1950-6D7E-27C5DEA68A33} + {B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912} = {A97EFA6B-D703-EF29-A34D-BAD7BA42B5BE} + {C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56} = {A97EFA6B-D703-EF29-A34D-BAD7BA42B5BE} EndGlobalSection EndGlobal diff --git a/Local.slnx b/Local.slnx index 7dbcf2058..93c389168 100644 --- a/Local.slnx +++ b/Local.slnx @@ -49,14 +49,18 @@ + + + + @@ -151,7 +155,7 @@ - + @@ -180,7 +184,7 @@ - + diff --git a/Sdk/Speckle.Connectors.Common/HostApplications.cs b/Sdk/Speckle.Connectors.Common/HostApplications.cs index e5a97e2d3..fac1bbdaa 100644 --- a/Sdk/Speckle.Connectors.Common/HostApplications.cs +++ b/Sdk/Speckle.Connectors.Common/HostApplications.cs @@ -16,6 +16,7 @@ public static class HostApplications Civil = new("Civil 3D", "civil3d"), Civil3D = new("Civil 3D", "civil3d"), AutoCAD = new("AutoCAD", "autocad"), + Plant3D = new("Plant 3D", "plant3d"), MicroStation = new("MicroStation", "microstation"), OpenRoads = new("OpenRoads", "openroads"), OpenRail = new("OpenRail", "openrail"), diff --git a/Speckle.Connectors.sln b/Speckle.Connectors.sln index ef552f92b..820b3160e 100644 --- a/Speckle.Connectors.sln +++ b/Speckle.Connectors.sln @@ -307,6 +307,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Importers.JobProces EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.RhinoImporter", "Connectors\Rhino\Speckle.Connectors.RhinoImporter\Speckle.Connectors.RhinoImporter.csproj", "{5422F2C8-1E00-4DAE-BB01-65A17BE8CD68}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Plant3d2026", "Connectors\Autocad\Speckle.Connectors.Plant3d2026\Speckle.Connectors.Plant3d2026.csproj", "{F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Converters.Plant3d2026", "Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.csproj", "{C6D7E8F9-0123-4567-89AB-CDEF01234567}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Connectors.Plant3dShared", "Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.shproj", "{B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Speckle.Converters.Plant3dShared", "Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.shproj", "{C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -770,6 +778,18 @@ Global {5422F2C8-1E00-4DAE-BB01-65A17BE8CD68}.Local|Any CPU.Build.0 = Local|Any CPU {5422F2C8-1E00-4DAE-BB01-65A17BE8CD68}.Release|Any CPU.ActiveCfg = Release|Any CPU {5422F2C8-1E00-4DAE-BB01-65A17BE8CD68}.Release|Any CPU.Build.0 = Release|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Local|Any CPU.ActiveCfg = Local|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Local|Any CPU.Build.0 = Local|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01}.Release|Any CPU.Build.0 = Release|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Local|Any CPU.ActiveCfg = Local|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Local|Any CPU.Build.0 = Local|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6D7E8F9-0123-4567-89AB-CDEF01234567}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -907,6 +927,10 @@ Global {92F065BE-97E2-4192-B561-88A6A8CFA53F} = {CD0C216A-2A96-4423-956E-3DDFCAEA510C} {1953F875-B271-484B-B589-3D4AC1288C2B} = {CD0C216A-2A96-4423-956E-3DDFCAEA510C} {5422F2C8-1E00-4DAE-BB01-65A17BE8CD68} = {5929C9C7-F971-449E-BC5B-4486016BD11F} + {F3A4B5C6-D7E8-4F01-A345-6789ABCDEF01} = {1D9F4468-A382-4D25-8195-F93A884B14DA} + {C6D7E8F9-0123-4567-89AB-CDEF01234567} = {1D9F4468-A382-4D25-8195-F93A884B14DA} + {B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6} + {C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56} = {4721AA15-AF6E-4A62-A2C3-65564DC563E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8} @@ -1010,5 +1034,19 @@ Global Connectors\Revit\Speckle.Connectors.RevitShared\Speckle.Connectors.RevitShared.projitems*{f98f97ac-d862-4750-b952-fbe4e9ee0eba}*SharedItemsImports = 5 Connectors\Navisworks\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems*{fd44e1f0-d20a-49b6-adc9-482d911a74fb}*SharedItemsImports = 5 Connectors\Navisworks\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems*{fe797118-07cb-44a7-a779-68ff3b69ee40}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems*{b1c4a14c-2f4e-4c3d-9b71-a3f5d8e6c912}*SharedItemsImports = 13 + Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{d1e2f3a4-b5c6-4d8e-9f01-234567890abc}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems*{d1e2f3a4-b5c6-4d8e-9f01-234567890abc}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{e2f3a4b5-c6d7-4e9f-8123-456789abcdef}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems*{e2f3a4b5-c6d7-4e9f-8123-456789abcdef}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems*{f3a4b5c6-d7e8-4f01-a345-6789abcdef01}*SharedItemsImports = 5 + Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems*{f3a4b5c6-d7e8-4f01-a345-6789abcdef01}*SharedItemsImports = 5 + Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.projitems*{c7e3a28d-5f91-4b6e-a8d2-3f1c9e7b4d56}*SharedItemsImports = 13 + Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{a4b5c6d7-e8f9-4123-8567-89abcdef0123}*SharedItemsImports = 5 + Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.projitems*{a4b5c6d7-e8f9-4123-8567-89abcdef0123}*SharedItemsImports = 5 + Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{b5c6d7e8-f901-4345-a789-abcdef012345}*SharedItemsImports = 5 + Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.projitems*{b5c6d7e8-f901-4345-a789-abcdef012345}*SharedItemsImports = 5 + Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems*{c6d7e8f9-0123-4567-89ab-cdef01234567}*SharedItemsImports = 5 + Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.projitems*{c6d7e8f9-0123-4567-89ab-cdef01234567}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/Speckle.Connectors.slnx b/Speckle.Connectors.slnx index c764603db..e78cd8d86 100644 --- a/Speckle.Connectors.slnx +++ b/Speckle.Connectors.slnx @@ -49,14 +49,18 @@ + + + + @@ -151,7 +155,7 @@ - + @@ -180,7 +184,7 @@ - +