feat: plant 3d connector (#1344)
.NET Build and Publish / build-connectors (push) Has been cancelled
.NET Build and Publish / deploy-installers (push) Has been cancelled

* wip

* feat: data extraction from db

* Fallback conversions

* Fix line segments

* Fix: do not skip empty values

* Remove claude generated receive boilerplates and civil related extractor

* Fix compile errors and custom assembly resolver

* Guids for bundle

* Nuget

* Use TagValue as object name

* add plant3d to slnx (#1347)

* add plant3d to slnx

* format

* and the local (#1348)

* Resolve comments

* final comments

* lockfiles

* don't swallow image exception

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
This commit is contained in:
Mucahit Bilal GOKER
2026-04-02 18:20:49 +03:00
committed by GitHub
parent 24442ab0a9
commit a1f392a33b
43 changed files with 1716 additions and 57 deletions
+2
View File
@@ -21,3 +21,5 @@ tools
coverage.xml
output/
Images/Thumbs.db
.claude
+1
View File
@@ -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",
[
@@ -35,4 +35,23 @@
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
<StartArguments>/product C3D</StartArguments>
</PropertyGroup>
<Target AfterTargets="Clean" Name="CleanAddinPlant3D" Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\Contents\Windows\Speckle.Connectors.Plant3d$(Plant3DVersion);" />
</Target>
<Target AfterTargets="Build" Name="AfterBuildPlant3D" Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<ItemGroup>
<Plant3DDLLs Include="$(TargetDir)\**\*.*" />
</ItemGroup>
<Message Text="Plant3D Version $(Plant3DVersion)" Importance="high"/>
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\Contents\Windows\Speckle.Connectors.Plant3d$(Plant3DVersion)\%(RecursiveDir)" SourceFiles="@(Plant3DDLLs)" />
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Plant3d.bundle\" SourceFiles="$(TargetDir)\Plugin\BundlePlant3D\PackageContents.xml" />
</Target>
<PropertyGroup Condition="'$(Plant3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true' And '$(OS)' == 'Windows_NT'">
<StartAction>Program</StartAction>
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Plant3DVersion)\acad.exe</StartProgram>
<StartArguments>/product PLNT3D</StartArguments>
</PropertyGroup>
</Project>
@@ -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;
@@ -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();
@@ -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
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage
SchemaVersion="1.0"
AppVersion="1.0"
Author="AEC SYSTEMS LTD"
Name="Speckle for Plant 3D"
Description="Speckle for Plant 3D"
Icon="./Contents/Resources/Logo.ico"
ProductCode="{b91352b6-01db-4084-93c8-684bb231947e}"
UpgradeCode="{91c7e43f-e962-40e9-85bd-d6bd733b6964}">
<CompanyDetails
Name="Speckle"
Url="https://speckle.systems"
Email="support@speckle.systems" />
<Components>
<!-- Plant 3D 2026 -->
<ComponentEntry
AppName="Speckle.Connectors.Plant3d2026"
ModuleName="./Contents/Windows/Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.dll"
LoadOnAutoCADStartup="True">
<RuntimeRequirements
OS="Win64"
Platform="Plant3D"
SeriesMin="R25.1"
SeriesMax="R25.1" />
</ComponentEntry>
</Components>
</ApplicationPackage>
@@ -60,5 +60,8 @@
<Content Include="$(MSBuildThisFileDirectory)Plugin\BundleAutoCAD\PackageContents.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Plugin\BundlePlant3D\PackageContents.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Plant3DVersion>2026</Plant3DVersion>
<DefineConstants>$(DefineConstants);PLANT3D2026;PLANT3D;PLANT3D2024_OR_GREATER;PLANT3D2025_OR_GREATER;PLANT3D2026_OR_GREATER</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<PropertyGroup>
<!-- .NET Core uses this to move native dependencies into a root for runtime selection and usage for non-windows development https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#enablewindowstargeting -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!--This is needed for managed dependencies-->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!--This is needed for the rest-->
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <!--This is needed just to keep folder paths the same as the netframework versions-->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Plant3D.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.csproj" />
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
</ItemGroup>
<Import Project="..\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.projitems" Label="Shared" />
<Import Project="..\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
</Project>
@@ -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=="
}
}
}
}
@@ -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<ISendFilter> 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<IConverterSettingsStore<Plant3dConversionSettings>>()
.Initialize(_plant3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
serviceProvider
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
}
}
@@ -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<IRootObjectBuilder<AutocadRootObject>, Plant3dRootObjectBuilder>();
serviceCollection.AddSingleton<IBinding, Plant3dSendBinding>();
// automatically detects the Class:IClass interface pattern to register all generated interfaces
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
}
}
@@ -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<AutocadConversionSettings> converterSettings,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
AutocadMaterialUnpacker materialUnpacker,
AutocadColorUnpacker colorUnpacker,
AutocadGroupUnpacker groupUnpacker,
ILogger<AutocadRootObjectBuilder> 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);
}
}
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Speckle.Connectors.Plant3dShared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Plant3dConnectorModule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Plant3dRootObjectBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Plant3dSendBinding.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
</ItemGroup>
</Project>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{B1C4A14C-2F4E-4C3D-9B71-A3F5D8E6C912}</ProjectGuid>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<Import Project="Speckle.Connectors.Plant3dShared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
@@ -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<string, object?> 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<string, object?> properties = _propertiesExtractor.GetProperties((Entity)dbObject);
if (properties.Count > 0)
{
convertedObject["properties"] = properties;
}
tr.Commit();
return convertedObject;
}
convertedObject["properties"] = properties;
}
tr.Commit();
return convertedObject;
}
}
@@ -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;
}
}
@@ -1,5 +1,3 @@
using Speckle.Sdk;
namespace Speckle.Converters.Civil3dShared.Helpers;
/// <summary>
@@ -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;
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<Plant3DVersion>2026</Plant3DVersion>
<DefineConstants>$(DefineConstants);PLANT3D2026;PLANT3D;PLANT3D2024_OR_GREATER;PLANT3D2025_OR_GREATER;PLANT3D2026_OR_GREATER</DefineConstants>
<Configurations>Debug;Release;Local</Configurations>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
<PackageReference Include="Speckle.Plant3D.API" VersionOverride="2026.0.0" ExcludeAssets="runtime"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
</ItemGroup>
<Import Project="..\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.projitems" Label="Shared" />
<Import Project="..\..\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.projitems" Label="Shared" />
</Project>
@@ -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"
}
}
}
}
}
@@ -0,0 +1,2 @@
global using PP = Autodesk.ProcessPower;
global using PPDL = Autodesk.ProcessPower.DataLinks;
@@ -0,0 +1,43 @@
using Speckle.Sdk;
namespace Speckle.Converters.Plant3dShared.Helpers;
/// <summary>
/// Used to help with properties on classes that may throw exceptions when accessed
/// </summary>
public sealed class PropertyHandler
{
public bool TryGetValue<T>(Func<T> 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<T>(Dictionary<string, object?> dict, string key, Func<T> getValue)
{
if (dict.ContainsKey(key))
{
return false;
}
if (TryGetValue<T>(getValue, out var value))
{
dict.Add(key, value);
return true;
}
return false;
}
}
@@ -0,0 +1,3 @@
namespace Speckle.Converters.Plant3dShared;
public record Plant3dConversionSettings(Document Document, string SpeckleUnits);
@@ -0,0 +1,13 @@
using Autodesk.AutoCAD.DatabaseServices;
using Speckle.Converters.Common;
using Speckle.InterfaceGenerator;
namespace Speckle.Converters.Plant3dShared;
[GenerateAutoInterface]
public class Plant3dConversionSettingsFactory(IHostToSpeckleUnitConverter<UnitsValue> unitsConverter)
: IPlant3dConversionSettingsFactory
{
public Plant3dConversionSettings Create(Document document) =>
new(document, unitsConverter.ConvertOrThrow(document.Database.Insunits));
}
@@ -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<IToSpeckleTopLevelConverter> toSpeckle,
IConverterSettingsStore<Plant3dConversionSettings> 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;
}
}
@@ -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<UnitsValue>
{
private static readonly IReadOnlyDictionary<UnitsValue, string> s_unitsMapping = Create();
private static IReadOnlyDictionary<UnitsValue, string> Create()
{
var dict = new Dictionary<UnitsValue, string>();
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.");
}
}
@@ -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<Plant3dRootToSpeckleConverter>(plant3dAssembly);
// register all application converters
serviceCollection.AddApplicationConverters<Plant3dToSpeckleUnitConverter, ADB.UnitsValue>(plant3dAssembly);
// serviceCollection.AddApplicationConverters<AutocadToSpeckleUnitConverter, ADB.UnitsValue>(autocadAssembly);
serviceCollection.AddScoped<
IConverterSettingsStore<Plant3dConversionSettings>,
ConverterSettingsStore<Plant3dConversionSettings>
>();
serviceCollection.AddScoped<
IConverterSettingsStore<AutocadConversionSettings>,
ConverterSettingsStore<AutocadConversionSettings>
>();
serviceCollection.AddScoped<IReferencePointConverter, ReferencePointConverter>();
// add other classes
serviceCollection.AddScoped<Speckle.Converters.Plant3dShared.ToSpeckle.PropertiesExtractor>(); // for plant3d
serviceCollection.AddScoped<Speckle.Converters.AutocadShared.ToSpeckle.IPropertiesExtractor, PropertiesExtractor>();
serviceCollection.AddScoped<ExtensionDictionaryExtractor>();
serviceCollection.AddScoped<Plant3dDataExtractor>();
serviceCollection.AddScoped<EntityUnitConverter>();
}
}
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Speckle.Converters.Plant3dShared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Plant3dConversionSettings.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plant3dConversionSettingsFactory.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plant3dRootToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Plant3dToSpeckleUnitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsings.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\PropertyHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\PropertiesExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\ExtensionDictionaryExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Properties\Plant3dDataExtractor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\Plant3dEntityToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\EquipmentToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\PipeToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\PipeInlineAssetToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\FallbackEntityToSpeckleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToSpeckle\Geometry\LineSegmentToSpeckleConverter.cs" />
</ItemGroup>
</Project>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>C7E3A28D-5F91-4B6E-A8D2-3F1C9E7B4D56</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="Speckle.Converters.Plant3dShared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
@@ -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<IToSpeckleTopLevelConverter> converterManager,
IConverterSettingsStore<Plant3dConversionSettings> settingsStore
) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore);
@@ -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;
/// <summary>
/// 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.
/// </summary>
[NameAndRankValue(typeof(ADB.Entity), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK - 1)]
public class FallbackEntityToSpeckleConverter(
IConverterManager<IToSpeckleTopLevelConverter> converterManager,
IConverterSettingsStore<Plant3dConversionSettings> settingsStore
) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore);
@@ -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;
/// <summary>
/// Converts P&amp;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.
/// </summary>
[NameAndRankValue(typeof(PP.PnIDObjects.LineSegment), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class LineSegmentToSpeckleConverter : IToSpeckleTopLevelConverter
{
private readonly IConverterSettingsStore<AutocadConversionSettings> _settingsStore;
private readonly IReferencePointConverter _referencePointConverter;
public LineSegmentToSpeckleConverter(
IConverterSettingsStore<AutocadConversionSettings> 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<double> 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<Base> { polyline },
properties = new Dictionary<string, object?>(),
applicationId = lineSegment.Handle.Value.ToString()
};
return dataObject;
}
}
@@ -0,0 +1,14 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.Common.Registration;
namespace Speckle.Converters.Plant3dShared.ToSpeckle.Geometry;
/// <summary>
/// Converts inline pipe assets (valves, instruments, etc.) to Speckle.
/// </summary>
[NameAndRankValue(typeof(PP.PnP3dObjects.PipeInlineAsset), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class PipeInlineAssetToSpeckleConverter(
IConverterManager<IToSpeckleTopLevelConverter> converterManager,
IConverterSettingsStore<Plant3dConversionSettings> settingsStore
) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore);
@@ -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<IToSpeckleTopLevelConverter> converterManager,
IConverterSettingsStore<Plant3dConversionSettings> settingsStore
) : Plant3dEntityToSpeckleConverter(converterManager, settingsStore);
@@ -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;
/// <summary>
/// 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.).
/// </summary>
public abstract class Plant3dEntityToSpeckleConverter : IToSpeckleTopLevelConverter
{
private readonly IConverterManager<IToSpeckleTopLevelConverter> _converterManager;
private readonly IConverterSettingsStore<Plant3dConversionSettings> _settingsStore;
private const int MAX_DEPTH = 5;
protected Plant3dEntityToSpeckleConverter(
IConverterManager<IToSpeckleTopLevelConverter> converterManager,
IConverterSettingsStore<Plant3dConversionSettings> settingsStore
)
{
_converterManager = converterManager;
_settingsStore = settingsStore;
}
public Base Convert(object target) => ConvertEntity((ADB.Entity)target);
private DataObject ConvertEntity(ADB.Entity entity)
{
List<Base> 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<string, object?>(),
applicationId = entity.Handle.Value.ToString()
};
return dataObject;
}
#pragma warning disable CA1031 // Autodesk APIs throw various exception types
private List<Base> ExtractDisplayValue(ADB.Entity entity)
{
List<Base> results = new();
CollectDisplayObjects(entity, results, 0);
return results;
}
/// <summary>
/// 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.
/// </summary>
private void CollectDisplayObjects(ADB.Entity entity, List<Base> 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
}
@@ -0,0 +1,55 @@
using Speckle.Converters.Common;
namespace Speckle.Converters.Plant3dShared.ToSpeckle;
/// <summary>
/// Extracts extension dictionaries out from an element. Expects to be scoped per operation.
/// </summary>
public class ExtensionDictionaryExtractor
{
private readonly IConverterSettingsStore<Plant3dConversionSettings> _settingsStore;
public ExtensionDictionaryExtractor(IConverterSettingsStore<Plant3dConversionSettings> settingsStore)
{
_settingsStore = settingsStore;
}
/// <summary>
/// Extracts extension dictionary out from an entity. Expects to be scoped per operation.
/// </summary>
public Dictionary<string, object?>? GetExtensionDictionary(ADB.Entity entity)
{
if (entity is null || entity.ExtensionDictionary == ADB.ObjectId.Null)
{
return null;
}
Dictionary<string, object?> 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<string, object?> 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;
}
}
@@ -0,0 +1,67 @@
using Speckle.Converters.Common;
namespace Speckle.Converters.Plant3dShared.ToSpeckle;
/// <summary>
/// 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).
/// </summary>
public class Plant3dDataExtractor
{
private readonly IConverterSettingsStore<Plant3dConversionSettings> _settingsStore;
public Plant3dDataExtractor(IConverterSettingsStore<Plant3dConversionSettings> settingsStore)
{
_settingsStore = settingsStore;
}
/// <summary>
/// Gets Plant3D database properties for the given entity.
/// Returns a dictionary of property name → value pairs from the project database.
/// </summary>
#pragma warning disable CA1031 // Plant3D data APIs can throw various exceptions
public Dictionary<string, object?> GetDataProperties(ADB.Entity entity)
{
var result = new Dictionary<string, object?>();
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
}
@@ -0,0 +1,43 @@
namespace Speckle.Converters.Plant3dShared.ToSpeckle;
/// <summary>
/// Extracts properties for Plant3D objects.
/// </summary>
public class PropertiesExtractor : Speckle.Converters.AutocadShared.ToSpeckle.IPropertiesExtractor
{
private readonly ExtensionDictionaryExtractor _extensionDictionaryExtractor;
public PropertiesExtractor(ExtensionDictionaryExtractor extensionDictionaryExtractor)
{
_extensionDictionaryExtractor = extensionDictionaryExtractor;
}
public Dictionary<string, object?> GetProperties(ADB.Entity entity)
{
Dictionary<string, object?> 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<string, object?>? entryDictionary,
string entryName,
Dictionary<string, object?> propertyDictionary
)
{
if (entryDictionary is not null && entryDictionary.Count > 0)
{
propertyDictionary.Add(entryName, entryDictionary);
}
}
}
+25 -1
View File
@@ -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
+6 -2
View File
@@ -49,14 +49,18 @@
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3d2025\Speckle.Converters.Civil3d2025.csproj" />
</Folder>
<Folder Name="/Connectors/Autocad/2026/">
<Project Path="Connectors\Autocad\Speckle.Connectors.Plant3d2026/Speckle.Connectors.Plant3d2026.csproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Autocad2026\Speckle.Connectors.Autocad2026.csproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Civil3d2026\Speckle.Connectors.Civil3d2026.csproj" />
<Project Path="Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.csproj" />
<Project Path="Converters\Autocad\Speckle.Converters.Autocad2026\Speckle.Converters.Autocad2026.csproj" />
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3d2026\Speckle.Converters.Civil3d2026.csproj" />
</Folder>
<Folder Name="/Connectors/Autocad/Shared/">
<Project Path="Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.shproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.shproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.shproj" />
<Project Path="Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.shproj" />
<Project Path="Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.shproj" />
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.shproj" />
</Folder>
@@ -151,7 +155,7 @@
<Folder Name="/Connectors/Rhino/8/">
<Project Path="Connectors\Rhino\Speckle.Connectors.Grasshopper8\Speckle.Connectors.Grasshopper8.csproj" />
<Project Path="Connectors\Rhino\Speckle.Connectors.Rhino8\Speckle.Connectors.Rhino8.csproj" />
<Project Path="Connectors\Rhino\Speckle.Connectors.RhinoImporter\Speckle.Connectors.RhinoImporter.csproj" Type="C#" />
<Project Path="Connectors\Rhino\Speckle.Connectors.RhinoImporter\Speckle.Connectors.RhinoImporter.csproj" />
<Project Path="Converters\Rhino\Speckle.Converters.Rhino8\Speckle.Converters.Rhino8.csproj" />
</Folder>
<Folder Name="/Connectors/Rhino/Shared/">
@@ -180,7 +184,7 @@
</Folder>
<Folder Name="/Importers/" />
<Folder Name="/Importers/Rhino/">
<Project Path="Importers\Rhino\Speckle.Importers.JobProcessor\Speckle.Importers.JobProcessor.csproj" Type="C#">
<Project Path="Importers\Rhino\Speckle.Importers.JobProcessor\Speckle.Importers.JobProcessor.csproj">
<Configuration Solution="Local|Any CPU" Project="Debug|Any CPU" />
</Project>
<Project Path="Importers\Rhino\Speckle.Importers.Rhino\Speckle.Importers.Rhino.csproj" />
@@ -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"),
+38
View File
@@ -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
+6 -2
View File
@@ -49,14 +49,18 @@
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3d2025\Speckle.Converters.Civil3d2025.csproj" />
</Folder>
<Folder Name="/Connectors/Autocad/2026/">
<Project Path="Connectors\Autocad\Speckle.Connectors.Plant3d2026\Speckle.Connectors.Plant3d2026.csproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Autocad2026\Speckle.Connectors.Autocad2026.csproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Civil3d2026\Speckle.Connectors.Civil3d2026.csproj" />
<Project Path="Converters\Plant3d\Speckle.Converters.Plant3d2026\Speckle.Converters.Plant3d2026.csproj" />
<Project Path="Converters\Autocad\Speckle.Converters.Autocad2026\Speckle.Converters.Autocad2026.csproj" />
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3d2026\Speckle.Converters.Civil3d2026.csproj" />
</Folder>
<Folder Name="/Connectors/Autocad/Shared/">
<Project Path="Connectors\Autocad\Speckle.Connectors.Plant3dShared\Speckle.Connectors.Plant3dShared.shproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.shproj" />
<Project Path="Connectors\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.shproj" />
<Project Path="Converters\Plant3d\Speckle.Converters.Plant3dShared\Speckle.Converters.Plant3dShared.shproj" />
<Project Path="Converters\Autocad\Speckle.Converters.AutocadShared\Speckle.Converters.AutocadShared.shproj" />
<Project Path="Converters\Civil3d\Speckle.Converters.Civil3dShared\Speckle.Converters.Civil3dShared.shproj" />
</Folder>
@@ -151,7 +155,7 @@
<Folder Name="/Connectors/Rhino/8/">
<Project Path="Connectors\Rhino\Speckle.Connectors.Grasshopper8\Speckle.Connectors.Grasshopper8.csproj" />
<Project Path="Connectors\Rhino\Speckle.Connectors.Rhino8\Speckle.Connectors.Rhino8.csproj" />
<Project Path="Connectors\Rhino\Speckle.Connectors.RhinoImporter\Speckle.Connectors.RhinoImporter.csproj" Type="Classic C#" />
<Project Path="Connectors\Rhino\Speckle.Connectors.RhinoImporter\Speckle.Connectors.RhinoImporter.csproj" Type="C#" />
<Project Path="Converters\Rhino\Speckle.Converters.Rhino8\Speckle.Converters.Rhino8.csproj" />
</Folder>
<Folder Name="/Connectors/Rhino/Shared/">
@@ -180,7 +184,7 @@
</Folder>
<Folder Name="/Importers/" />
<Folder Name="/Importers/Rhino/">
<Project Path="Importers\Rhino\Speckle.Importers.JobProcessor\Speckle.Importers.JobProcessor.csproj" Type="Classic C#">
<Project Path="Importers\Rhino\Speckle.Importers.JobProcessor\Speckle.Importers.JobProcessor.csproj" Type="C#">
<Configuration Solution="Local|Any CPU" Project="Debug|Any CPU" />
</Project>
<Project Path="Importers\Rhino\Speckle.Importers.Rhino\Speckle.Importers.Rhino.csproj" />