diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d2512ca3..6c358f36a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,10 @@ jobs: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} - - name: ⚒️ Run build + - name: ⚒️ Run Build on Linux + run: ./build.sh build-linux + + - name: ⚒️ Run tests run: ./build.sh test-only - name: Upload coverage reports to Codecov with GitHub Action diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 478f552d6..af72f5344 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -87,7 +87,10 @@ jobs: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} - - name: ⚒️ Run build + - name: ⚒️ Run Build and Pack on Linux + run: ./build.sh build-linux + + - name: ⚒️ Run tests run: ./build.sh test-only - name: Upload coverage reports to Codecov with GitHub Action @@ -95,3 +98,6 @@ jobs: with: file: Converters/**/coverage.xml token: ${{ secrets.CODECOV_TOKEN }} + + - name: Push to nuget.org + run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate diff --git a/Build/Program.cs b/Build/Program.cs index 3eb8dac67..cb6e5fc36 100644 --- a/Build/Program.cs +++ b/Build/Program.cs @@ -7,6 +7,7 @@ const string CLEAN = "clean"; const string RESTORE = "restore"; const string BUILD = "build"; +const string BUILD_LINUX = "build-linux"; const string TEST = "test"; const string TEST_ONLY = "test-only"; const string FORMAT = "format"; @@ -183,6 +184,28 @@ void RemoveDirectory(string d) } ); +Target( + BUILD_LINUX, + DependsOn(FORMAT), + Glob.Files(".", "**/Speckle.Importers.Ifc.csproj"), + file => + { + Run("dotnet", $"restore {file} --locked-mode"); + var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild"; + var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0"; + Console.WriteLine($"Version: {version} & {fileVersion}"); + Run( + "dotnet", + $"build {file} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m" + ); + + RunAsync( + "dotnet", + $"pack {file} -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m" + ); + } +); + Target( ZIP, DependsOn(TEST), diff --git a/Directory.Packages.props b/Directory.Packages.props index d012b1634..6a648e78a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,5 +1,8 @@ + + + diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummySendCacheManager.cs b/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummySendCacheManager.cs new file mode 100644 index 000000000..10f5d8454 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummySendCacheManager.cs @@ -0,0 +1,28 @@ +using Speckle.Sdk.SQLite; + +namespace Speckle.Importers.Ifc.Tester; + +public sealed class DummySendCacheManager(Dictionary objects) : ISqLiteJsonCacheManager +{ + public void Dispose() { } + + public IReadOnlyCollection<(string, string)> GetAllObjects() => throw new NotImplementedException(); + + public void DeleteObject(string id) => throw new NotImplementedException(); + + public string? GetObject(string id) => null; + + public void SaveObject(string id, string json) => throw new NotImplementedException(); + + public bool HasObject(string objectId) => false; + + public void SaveObjects(IEnumerable<(string id, string json)> items) + { + foreach (var (id, json) in items) + { + objects[id] = json; + } + } + + public void UpdateObject(string id, string json) => throw new NotImplementedException(); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummyServerObjectManager.cs b/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummyServerObjectManager.cs new file mode 100644 index 000000000..0adb1a878 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/DummyServerObjectManager.cs @@ -0,0 +1,43 @@ +using System.Text; +using Speckle.Sdk.Serialisation.V2; +using Speckle.Sdk.Serialisation.V2.Send; +using Speckle.Sdk.Transports; + +namespace Speckle.Importers.Ifc.Tester; + +public class DummyServerObjectManager : IServerObjectManager +{ + public IAsyncEnumerable<(string, string)> DownloadObjects( + IReadOnlyCollection objectIds, + IProgress? progress, + CancellationToken cancellationToken + ) => throw new NotImplementedException(); + + public Task DownloadSingleObject( + string objectId, + IProgress? progress, + CancellationToken cancellationToken + ) => throw new NotImplementedException(); + + public Task> HasObjects( + IReadOnlyCollection objectIds, + CancellationToken cancellationToken + ) => Task.FromResult(objectIds.ToDictionary(id => id, id => false)); + + public Task UploadObjects( + IReadOnlyList objects, + bool compressPayloads, + IProgress? progress, + CancellationToken cancellationToken + ) + { + long totalBytes = 0; + foreach (var item in objects) + { + totalBytes += Encoding.Default.GetByteCount(item.Json.Value); + } + + progress?.Report(new(ProgressEvent.UploadBytes, totalBytes, totalBytes)); + return Task.CompletedTask; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/Program.cs b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Program.cs new file mode 100644 index 000000000..a8d0c4758 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Program.cs @@ -0,0 +1,65 @@ +#pragma warning disable CA1506 +using System.Diagnostics; +using Ara3D.Utils; +//using JetBrains.Profiler.SelfApi; +using Microsoft.Extensions.DependencyInjection; +using Speckle.Importers.Ifc; +using Speckle.Importers.Ifc.Ara3D.IfcParser; +using Speckle.Importers.Ifc.Converters; +using Speckle.Importers.Ifc.Tester; +using Speckle.Importers.Ifc.Types; +using Speckle.Sdk.Serialisation.V2.Send; +using Speckle.Sdk.SQLite; + +var serviceProvider = Import.GetServiceProvider(); + +//DotMemory.Init(); +var filePath = new FilePath( + //"C:\\Users\\adam\\Git\\speckle-server\\packages\\fileimport-service\\ifc-dotnet\\ifcs\\20210221PRIMARK.ifc" + //"C:\\Users\\adam\\Git\\speckle-server\\packages\\fileimport-service\\ifc-dotnet\\ifcs\\231110ADT-FZK-Haus-2005-2006.ifc" + //"C:\\Users\\adam\\Downloads\\T03PV06IMPMI01C.ifc" + "C:\\Users\\adam\\Downloads\\20231128_HW_Bouwkosten.ifc" +); + +var ifcFactory = serviceProvider.GetRequiredService(); +var stopwatch = Stopwatch.StartNew(); + +Console.WriteLine($"Opening with WebIFC: {filePath}"); +var model = ifcFactory.Open(filePath); +var ms = stopwatch.ElapsedMilliseconds; +Console.WriteLine($"Opened with WebIFC: {ms} ms"); + +var graph = IfcGraph.Load(new FilePath(filePath)); +var ms2 = stopwatch.ElapsedMilliseconds; +Console.WriteLine($"Loaded with StepParser: {ms2 - ms} ms"); + +var converter = serviceProvider.GetRequiredService(); +var b = converter.Convert(model, graph); +ms = ms2; +ms2 = stopwatch.ElapsedMilliseconds; +Console.WriteLine($"Converted to Speckle Bases: {ms2 - ms} ms"); + +var cache = $"C:\\Users\\adam\\Git\\temp\\{Guid.NewGuid()}.db"; +using var sqlite = new SqLiteJsonCacheManager($"Data Source={cache};", 2); +using var process2 = new SerializeProcess( + new Progress(true), + sqlite, + new DummyServerObjectManager(), + new BaseChildFinder(new BasePropertyGatherer()), + new ObjectSerializerFactory(new BasePropertyGatherer()), + new SerializeProcessOptions(SkipServer: true) +); +Console.WriteLine($"Caching to Speckle: {cache}"); + +/*var config = new DotMemory.Config(); +config.OpenDotMemory(); +config.SaveToDir("C:\\Users\\adam\\dotTraceSnapshots"); +DotMemory.Attach(config); +DotMemory.GetSnapshot("Before");*/ +var (rootId, _) = await process2.Serialize(b, default).ConfigureAwait(false); +Console.WriteLine(rootId); +ms2 = stopwatch.ElapsedMilliseconds; +Console.WriteLine($"Converted to JSON: {ms2 - ms} ms"); +//DotMemory.GetSnapshot("After"); +//DotMemory.Detach(); +#pragma warning restore CA1506 diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/Progress.cs b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Progress.cs new file mode 100644 index 000000000..0601c31f7 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Progress.cs @@ -0,0 +1,36 @@ +using Speckle.Sdk.Transports; + +namespace Speckle.Importers.Ifc.Tester; + +public class Progress(bool write) : IProgress +{ + private readonly TimeSpan _debounce = TimeSpan.FromMilliseconds(1000); + private DateTime _lastTime = DateTime.UtcNow; + + private long _totalBytes; + + public void Report(ProgressArgs value) + { + if (write) + { + if (value.ProgressEvent == ProgressEvent.DownloadBytes) + { + Interlocked.Add(ref _totalBytes, value.Count); + } + var now = DateTime.UtcNow; + if (now - _lastTime >= _debounce) + { + if (value.ProgressEvent == ProgressEvent.DownloadBytes) + { + Console.WriteLine(value.ProgressEvent + " t " + _totalBytes); + } + else + { + Console.WriteLine(value.ProgressEvent + " c " + value.Count + " t " + value.Total); + } + + _lastTime = now; + } + } + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/Speckle.Importers.Ifc.Tester.csproj b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Speckle.Importers.Ifc.Tester.csproj new file mode 100644 index 000000000..17b459a6c --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/Speckle.Importers.Ifc.Tester.csproj @@ -0,0 +1,13 @@ + + + + Exe + net8.0 + Debug;Release;Local + + + + + + + diff --git a/Importers/Ifc/Speckle.Importers.Ifc.Tester/packages.lock.json b/Importers/Ifc/Speckle.Importers.Ifc.Tester/packages.lock.json new file mode 100644 index 000000000..13a4b3737 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc.Tester/packages.lock.json @@ -0,0 +1,307 @@ +{ + "version": 2, + "dependencies": { + "net8.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.InterfaceGenerator": { + "type": "Direct", + "requested": "[0.9.6, )", + "resolved": "0.9.6", + "contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w==" + }, + "GraphQL.Client": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0", + "GraphQL.Client.Abstractions.Websocket": "6.0.0", + "System.Reactive": "5.0.0" + } + }, + "GraphQL.Client.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==", + "dependencies": { + "GraphQL.Primitives": "6.0.0" + } + }, + "GraphQL.Client.Abstractions.Websocket": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==", + "dependencies": { + "GraphQL.Client.Abstractions": "6.0.0" + } + }, + "GraphQL.Primitives": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==" + }, + "Microsoft.Data.Sqlite": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", + "dependencies": { + "Microsoft.Data.Sqlite.Core": "7.0.5", + "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4" + } + }, + "Microsoft.Data.Sqlite.Core": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "2.2.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Primitives": "2.2.0", + "System.ComponentModel.Annotations": "4.5.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==", + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net461": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Speckle.DoubleNumerics": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + }, + "Speckle.Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.2", + "contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA==" + }, + "SQLitePCLRaw.bundle_e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==", + "dependencies": { + "SQLitePCLRaw.lib.e_sqlite3": "2.1.4", + "SQLitePCLRaw.provider.e_sqlite3": "2.1.4" + } + }, + "SQLitePCLRaw.core": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==", + "dependencies": { + "System.Memory": "4.5.3" + } + }, + "SQLitePCLRaw.lib.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==" + }, + "SQLitePCLRaw.provider.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==" + }, + "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.importers.ifc": { + "type": "Project", + "dependencies": { + "Ara3D.Buffers": "[1.4.5, )", + "Ara3D.Logging": "[1.4.5, )", + "Ara3D.Utils": "[1.4.5, )", + "Microsoft.Extensions.DependencyInjection": "[2.2.0, )", + "Speckle.Objects": "[3.1.0-dev.228, )", + "Speckle.Sdk": "[3.1.0-dev.228, )" + } + }, + "Ara3D.Buffers": { + "type": "CentralTransitive", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "SKcQqgtXukyHTlTKFPCaUW4spSkue3XfBU/GmoA7KhH6H995v6TbJxtqjs0EfSgnXEkajL8U7X1NqktScRozXw==", + "dependencies": { + "System.Memory": "4.5.5" + } + }, + "Ara3D.Logging": { + "type": "CentralTransitive", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "7HPCe5Dq21JoOBF1iclk9H37XFCoB2ZzCPqTMNgdg4PWFvuRsofNbiuMdiE/HKgMHCVhy1C5opB2KwDKcO7Axw==", + "dependencies": { + "Ara3D.Utils": "1.4.5" + } + }, + "Ara3D.Utils": { + "type": "CentralTransitive", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "yba/E7PpbWP0+RDp+KbKw/vBXnXBSIheScdpVKuDnr8ytRg8pZ2Jd6nwKES+G0FcVEB9PeOVmEW7SGrFvAwRCg==" + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Logging": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "2.2.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==" + }, + "Speckle.Objects": { + "type": "CentralTransitive", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "BxtORgyOorKHmvBUldyL7t747g3wgXPhkjIKi6qVWxhPxZqzswGf9jQD1GZL57dcWkZPgdQ/vmDsowq6K89T/w==", + "dependencies": { + "Speckle.Sdk": "3.1.0-dev.228" + } + }, + "Speckle.Sdk": { + "type": "CentralTransitive", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "2jb3t9KoYEeqGsGLuzR/O3GefG5cs+Zxcpq6dGmHuYLa3cw3nanGJ1X0UkiKFv1CcvZ+aNHPT36QoDVtNvWfow==", + "dependencies": { + "GraphQL.Client": "6.0.0", + "Microsoft.CSharp": "4.7.0", + "Microsoft.Data.Sqlite": "7.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging": "2.2.0", + "Speckle.DoubleNumerics": "4.0.1", + "Speckle.Newtonsoft.Json": "13.0.2", + "Speckle.Sdk.Dependencies": "3.1.0-dev.228" + } + }, + "Speckle.Sdk.Dependencies": { + "type": "CentralTransitive", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "Ul2flG1qAnpXYESNB2W4o3x7jxW3BFT2L/jdyO7lgsSVGiNhhVskaXVZXHvqGYwlu0y1J/fhFGANsc+1xnCoQA==" + } + } + } +} \ No newline at end of file diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/Extensions.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/Extensions.cs new file mode 100644 index 000000000..dc5933a1d --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/Extensions.cs @@ -0,0 +1,197 @@ +using System.Text; +using Ara3D.Buffers; +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public static class IfcExtensions +{ + public static void Add(this IDictionary> self, TKey key, TValue value) + { + if (!self.ContainsKey(key)) + self[key] = new List(); + self[key].Add(value); + } + + public static uint AsId(this StepValue value) => value is StepUnassigned ? 0u : ((StepId)value).Id; + + public static string AsString(this StepValue value) => + value is StepString ss + ? ss.AsString() + : value is StepNumber sn + ? sn.Value.ToString() + : value is StepId si + ? si.Id.ToString() + : value is StepSymbol ssm + ? ssm.Name.ToString() + : ""; + + public static double AsNumber(this StepValue value) => value is StepUnassigned ? 0 : ((StepNumber)value).Value; + + public static List AsList(this StepValue value) => + value is StepUnassigned ? new List() : ((StepList)value).Values; + + public static List AsIdList(this StepValue value) => + value is StepUnassigned ? new List() : value.AsList().Select(AsId).ToList(); + + // Uses Latin1 encoding (aka ISO-8859-1) + // Extended characters converted using an IFC specific system + public static string AsString(this ByteSpan span) => Encoding.Latin1.GetString(span.ToSpan()).IfcToUnicode(); + + // https://technical.buildingsmart.org/resources/ifcimplementationguidance/string-encoding/ + public static string IfcToUnicode(this string input) + { + if (!input.Contains('\\')) + return input; + + var output = new StringBuilder(); + var i = 0; + var length = input.Length; + while (i < length) + { + if (input[i] != '\\') + { + // Regular character, append to output + output.Append(input[i++]); + continue; + } + + i++; // Move past '\' + if (i >= length) + { + output.Append('\\'); + break; + } + + var escapeChar = input[i++]; + + if (escapeChar == 'S' && i < length && input[i] == '\\') + { + i++; // Move past '\' + if (i < length) + { + var c = input[i++]; + var code = c + 128; + output.Append((char)code); + } + else + { + output.Append("\\S\\"); + } + continue; + } + + if (escapeChar == 'X') + { + if (i < length && input[i] == '\\') + { + // Handle \X\XX escape sequence (8-bit character code) + i++; // Move past '\' + if (i + 1 < length) + { + var hex = input.Substring(i, 2); + i += 2; + var code = Convert.ToInt32(hex, 16); + output.Append((char)code); + } + else + { + output.Append("\\X\\"); + } + + continue; + } + + // Handle extended \Xn\...\X0\ escape sequence + // Skip 'n' until the next '\' + while (i < length && input[i] != '\\') + i++; + if (i < length) + i++; // Move past '\' + + // Collect hex digits until '\X0\' + var hexDigits = new StringBuilder(); + while (i + 3 <= length && input.Substring(i, 3) != "\\X0") + { + hexDigits.Append(input[i++]); + } + + if (i + 3 <= length && input.Substring(i, 3) == "\\X0") + { + i += 3; // Move past '\X0' + if (i < length && input[i] == '\\') + i++; // Move past '\' + + var hexStr = hexDigits.ToString(); + + // Process hex digits in chunks of 4 (representing Unicode code points) + for (var k = 0; k + 4 <= hexStr.Length; k += 4) + { + var codeHex = hexStr.Substring(k, 4); + var code = Convert.ToInt32(codeHex, 16); + output.Append(char.ConvertFromUtf32(code)); + } + continue; + } + + // Invalid format, append as is + output.Append("\\X"); + continue; + } + + // Unrecognized escape sequence, append as is + output.Append('\\').Append(escapeChar); + } + + return output.ToString(); + } + + public static string AsString(this StepString ss) => ss.Value.AsString(); + + public static object? ToJsonObject(this StepValue sv) + { + switch (sv) + { + case StepEntity stepEntity: + { + var attr = stepEntity.Attributes; + if (attr.Values.Count == 0) + return stepEntity.ToString(); + + if (attr.Values.Count == 1) + return attr.Values[0].ToJsonObject(); + + return attr.Values.Select(ToJsonObject).ToList(); + } + + case StepId stepId: + return stepId.Id; + + case StepList stepList: + return stepList.Values.Select(ToJsonObject).ToList(); + + case StepNumber stepNumber: + return stepNumber.AsNumber(); + + case StepRedeclared stepRedeclared: + return null; + + case StepString stepString: + return stepString.AsString(); + + case StepSymbol stepSymbol: + var tmp = stepSymbol.Name.AsString(); + if (tmp == "T") + return true; + if (tmp == "F") + return false; + return tmp; + + case StepUnassigned stepUnassigned: + return null; + + default: + throw new ArgumentOutOfRangeException(nameof(sv)); + } + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcEntity.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcEntity.cs new file mode 100644 index 000000000..899daa146 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcEntity.cs @@ -0,0 +1,65 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +/// +/// It represents an entity definition. It is usually a single line in a STEP file. +/// Many entity definitions are derived from IfcRoot (including relations). +/// IfcRoot has a GUID, OwnerId, optional Name, and optional Description +/// https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifckernel/lexical/ifcroot.htm +/// +public class IfcEntity +{ + public StepInstance LineData { get; } + public IfcGraph Graph { get; } + public uint Id => LineData.Id; + public string Type => LineData?.EntityType ?? ""; + + public IfcEntity(IfcGraph graph, StepInstance lineData) + { + Graph = graph; + LineData = lineData; + } + + public override bool Equals(object? obj) + { + if (obj is IfcEntity other) + return Id == other.Id; + return false; + } + + public override int GetHashCode() => (int)Id; + + public override string ToString() => $"{Type}#{Id}"; + + public bool IsIfcRoot => Count >= 4 && this[0] is StepString && (this[1] is StepId) || (this[1] is StepUnassigned); + + // Modern IFC files conform to this, but older ones have been observed to have different length IDs. + // Leaving as a comment for now. + //&& str.Value.Length == 22; + + public string? Guid => IsIfcRoot ? (this[0] as StepString)?.Value.ToString() : null; + + public uint OwnerId => IsIfcRoot ? (this[1] as StepId)?.Id ?? 0 : 0; + + public string? Name => IsIfcRoot ? (this[2] as StepString)?.AsString() : null; + + public string? Description => IsIfcRoot ? (this[3] as StepString)?.AsString() : null; + + public int Count => LineData.Count; + + public StepValue this[int i] => LineData[i]; + + public IReadOnlyList GetOutgoingRelations() => Graph.GetRelationsFrom(Id); + + public IEnumerable GetAggregatedChildren() => + GetOutgoingRelations().OfType().SelectMany(r => r.GetRelatedNodes()); + + public IEnumerable GetSpatialChildren() => + GetOutgoingRelations().OfType().SelectMany(r => r.GetRelatedNodes()); + + public IEnumerable GetChildren() => GetAggregatedChildren().Concat(GetSpatialChildren()); + + public IReadOnlyList GetPropSets() => + Graph.PropertySetsByNode.TryGetValue(Id, out var list) ? list : Array.Empty(); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcGraph.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcGraph.cs new file mode 100644 index 000000000..1f2664e6d --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcGraph.cs @@ -0,0 +1,232 @@ +using System.Diagnostics; +using Ara3D.Logging; +using Ara3D.Utils; +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +/// +/// This is a high-level representation of an IFC model as a graph of nodes and relations. +/// It also contains the properties, and property sets. +/// +public class IfcGraph +{ + public static IfcGraph Load(FilePath fp, ILogger? logger = null) => + new IfcGraph(new StepDocument(fp, logger), logger); + + public StepDocument Document { get; } + + public Dictionary Nodes { get; } = new Dictionary(); + public List Relations { get; } = new List(); + public Dictionary> RelationsByNode { get; } = new Dictionary>(); + public Dictionary> PropertySetsByNode { get; } = new Dictionary>(); + + public IReadOnlyList RootIds { get; } + + public IfcNode AddNode(IfcNode n) => Nodes[n.Id] = n; + + public IfcRelation AddRelation(IfcRelation r) + { + Relations.Add(r); + RelationsByNode.Add(r.From.Id, r); + return r; + } + + public IfcGraph(StepDocument d, ILogger? logger = null) + { + Document = d; + + logger?.Log("Computing entities"); + foreach (var inst in Document.RawInstances) + { + if (!inst.IsValid()) + continue; + + // TODO: converting entities into numerical hashes would likely improve performance significantly. + // Here we are doing a lot of comparisons. + + // Property Values + if (inst.Type.Equals("IFCPROPERTYSINGLEVALUE")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[2])); + } + else if (inst.Type.Equals("IFCPROPERTYENUMERATEDVALUE")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[2])); + } + else if (inst.Type.Equals("IFCPROPERTYREFERENCEVALUE")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCPROPERTYLISTVALUE")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[2])); + } + else if (inst.Type.Equals("IFCCOMPLEXPROPERTY")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + // Quantities which are a treated as a kind of prop + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcphysicalquantity.htm + else if (inst.Type.Equals("IFCQUANTITYLENGTH")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantitylength.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCQUANTITYAREA")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantityarea.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCQUANTITYVOLUME")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantityvolume.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCQUANTITYCOUNT")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantitycount.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCQUANTITYWEIGHT")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantityweight.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCQUANTITYTIME")) + { + // https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcquantitytime.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[3])); + } + else if (inst.Type.Equals("IFCPHYSICALCOMPLEXQUANTITY")) + { + //https://iaiweb.lbl.gov/Resources/IFC_Releases/R2x3_final/ifcquantityresource/lexical/ifcphysicalcomplexquantity.htm + var e = d.GetInstanceWithData(inst); + AddNode(new IfcProp(this, e, e[2])); + } + // Property Set (or element quantity) + else if (inst.Type.Equals("IFCPROPERTYSET")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcPropSet(this, e, (StepList)e[4])); + } + else if (inst.Type.Equals("IFCELEMENTQUANTITY")) + { + var e = d.GetInstanceWithData(inst); + AddNode(new IfcPropSet(this, e, (StepList)e[5])); + } + // Aggregate relation + else if (inst.Type.Equals("IFCRELAGGREGATES")) + { + var e = d.GetInstanceWithData(inst); + AddRelation(new IfcRelationAggregate(this, e, (StepId)e[4], (StepList)e[5])); + } + // Spatial relation + else if (inst.Type.Equals("IFCRELCONTAINEDINSPATIALSTRUCTURE")) + { + var e = d.GetInstanceWithData(inst); + AddRelation(new IfcRelationSpatial(this, e, (StepId)e[5], (StepList)e[4])); + } + // Property set relations + else if (inst.Type.Equals("IFCRELDEFINESBYPROPERTIES")) + { + var e = d.GetInstanceWithData(inst); + AddRelation(new IfcPropSetRelation(this, e, (StepId)e[5], (StepList)e[4])); + } + // Type relations + else if (inst.Type.Equals("IFCRELDEFINESBYTYPE")) + { + var e = d.GetInstanceWithData(inst); + AddRelation(new IfcRelationType(this, e, (StepId)e[5], (StepList)e[4])); + } + // Everything else + else + { + // Simple IFC node: without step entity data. + var e = d.GetInstanceWithData(inst); + AddNode(new IfcNode(this, e)); + } + } + + logger?.Log("Retrieving the roots of all of the spatial relationship"); + RootIds = GetSpatialRelations().Where(r => r.From != null).Select(r => r.From.Id).Distinct().ToList(); + + logger?.Log("Creating lookup of property sets"); + + foreach (var psr in Relations.OfType()) + { + var ps = psr.PropSet; + foreach (var id in psr.GetRelatedIds()) + { + PropertySetsByNode.Add(id, ps); + } + } + + logger?.Log("Completed creating model graph"); + } + + public IEnumerable GetNodes() => Nodes.Values; + + public IEnumerable GetNodes(IEnumerable ids) => ids.Select(GetNode); + + public IfcNode GetOrCreateNode(StepInstance lineData, int arg) + { + if (arg < 0 || arg >= lineData.AttributeValues.Count) + throw new SpeckleIfcException("Argument index out of range"); + return GetOrCreateNode(lineData.AttributeValues[arg]); + } + + public IfcNode GetOrCreateNode(StepValue o) => + GetOrCreateNode(o is StepId id ? id.Id : throw new SpeckleIfcException($"Expected a StepId value, not {o}")); + + public IfcNode GetOrCreateNode(uint id) + { + var r = Nodes.TryGetValue(id, out var node) ? node : AddNode(new IfcNode(this, Document.GetInstanceWithData(id))); + Debug.Assert(r.Id == id); + return r; + } + + public List GetOrCreateNodes(List list) => list.Select(GetOrCreateNode).ToList(); + + public List GetOrCreateNodes(StepInstance line, int arg) + { + if (arg < 0 || arg >= line.AttributeValues.Count) + throw new SpeckleIfcException("Argument out of range"); + if (line.AttributeValues[arg] is not StepList agg) + throw new SpeckleIfcException("Expected a list"); + return GetOrCreateNodes(agg.Values); + } + + public IfcNode GetNode(StepId id) => GetNode(id.Id); + + public IfcNode GetNode(uint id) + { + var r = Nodes[id]; + Debug.Assert(r.Id == id); + return r; + } + + public IEnumerable GetSources() => RootIds.Select(GetNode); + + public IEnumerable GetPropSets() => GetNodes().OfType(); + + public IEnumerable GetProps() => GetNodes().OfType(); + + public IEnumerable GetSpatialRelations() => Relations.OfType(); + + public IEnumerable GetAggregateRelations() => Relations.OfType(); + + public IReadOnlyList GetRelationsFrom(uint id) => + RelationsByNode.TryGetValue(id, out var list) ? list : Array.Empty(); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcNode.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcNode.cs new file mode 100644 index 000000000..36b333f61 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcNode.cs @@ -0,0 +1,9 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public class IfcNode : IfcEntity +{ + public IfcNode(IfcGraph graph, StepInstance lineData) + : base(graph, lineData) { } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcProp.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcProp.cs new file mode 100644 index 000000000..575c3894b --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcProp.cs @@ -0,0 +1,21 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public class IfcProp : IfcNode +{ + public readonly StepValue Value; + + public new string Name => this[0].AsString(); + public new string Description => this[1].AsString(); + + public IfcProp(IfcGraph graph, StepInstance lineData, StepValue value) + : base(graph, lineData) + { + if (lineData.Count < 2) + throw new SpeckleIfcException("Expected at least two values in the line data"); + if (lineData[0] is not StepString) + throw new SpeckleIfcException("Expected the first value to be a string (Name)"); + Value = value; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSet.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSet.cs new file mode 100644 index 000000000..cd388a77d --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSet.cs @@ -0,0 +1,42 @@ +using System.Diagnostics; +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +// This merges two separate entity types: IfcPropertySet and IfcElementQuantity. +// Both of which are derived from IfcPropertySetDefinition. +// This is something that can be referred to by a PropertySetRelation +// An IfcElementQuantity has an additional "method of measurement" property. +// https://standards.buildingsmart.org/IFC/RELEASE/IFC2x3/TC1/HTML/ifckernel/lexical/ifcpropertyset.htm +// https://standards.buildingsmart.org/IFC/RELEASE/IFC2x3/TC1/HTML/ifcproductextension/lexical/ifcelementquantity.htm +public class IfcPropSet : IfcNode +{ + public readonly StepList PropertyIdList; + + public IfcPropSet(IfcGraph graph, StepInstance lineData, StepList propertyIdList) + : base(graph, lineData) + { + Debug.Assert(IsIfcRoot); + Debug.Assert(lineData.AttributeValues.Count is 5 or 6); + Debug.Assert(Type is "IFCPROPERTYSET" or "IFCELEMENTQUANTITY"); + PropertyIdList = propertyIdList; + } + + public IEnumerable GetProperties() + { + for (var i = 0; i < NumProperties; ++i) + { + var id = PropertyId(i); + var node = Graph.GetNode(id); + if (node is not IfcProp prop) + throw new SpeckleIfcException($"Expected a property not {node} from id {id}"); + yield return prop; + } + } + + public bool IsQuantity => LineData.AttributeValues.Count == 6; + public string? MethodOfMeasurement => IsQuantity ? this[4]?.AsString() : null; + public int NumProperties => PropertyIdList.Values.Count; + + public uint PropertyId(int i) => PropertyIdList.Values[i].AsId(); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSetRelation.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSetRelation.cs new file mode 100644 index 000000000..13c30b0f5 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcPropSetRelation.cs @@ -0,0 +1,21 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +// https://standards.buildingsmart.org/IFC/RELEASE/IFC2x3/TC1/HTML/ifckernel/lexical/ifcreldefinesbyproperties.htm +public class IfcPropSetRelation : IfcRelation +{ + public IfcPropSetRelation(IfcGraph graph, StepInstance lineData, StepId from, StepList to) + : base(graph, lineData, from, to) { } + + public IfcPropSet PropSet + { + get + { + var node = Graph.GetNode(From); + if (node is not IfcPropSet r) + throw new SpeckleIfcException($"Expected a property set not {node} from id {From}"); + return r; + } + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelation.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelation.cs new file mode 100644 index 000000000..276b7cf97 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelation.cs @@ -0,0 +1,25 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +/// +/// Always express a 1-to-many relation +/// +public class IfcRelation : IfcEntity +{ + public StepId From { get; } + public StepList To { get; } + + public IfcRelation(IfcGraph graph, StepInstance lineData, StepId from, StepList to) + : base(graph, lineData) + { + if (!IsIfcRoot) + throw new SpeckleIfcException("Expected relation to be an IFC root entity"); + From = from; + To = to; + } + + public IEnumerable GetRelatedIds() => To.Values.Select(v => v.AsId()); + + public IEnumerable GetRelatedNodes() => Graph.GetNodes(GetRelatedIds()); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationAggregate.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationAggregate.cs new file mode 100644 index 000000000..5b826a1a0 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationAggregate.cs @@ -0,0 +1,9 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public class IfcRelationAggregate : IfcRelation +{ + public IfcRelationAggregate(IfcGraph graph, StepInstance lineData, StepId from, StepList to) + : base(graph, lineData, from, to) { } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationSpatial.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationSpatial.cs new file mode 100644 index 000000000..1509d0ae0 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationSpatial.cs @@ -0,0 +1,9 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public class IfcRelationSpatial : IfcRelation +{ + public IfcRelationSpatial(IfcGraph graph, StepInstance lineData, StepId from, StepList to) + : base(graph, lineData, from, to) { } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationType.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationType.cs new file mode 100644 index 000000000..f049e1b55 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.IfcParser/IfcRelationType.cs @@ -0,0 +1,9 @@ +using Speckle.Importers.Ifc.Ara3D.StepParser; + +namespace Speckle.Importers.Ifc.Ara3D.IfcParser; + +public class IfcRelationType : IfcRelation +{ + public IfcRelationType(IfcGraph graph, StepInstance lineData, StepId from, StepList to) + : base(graph, lineData, from, to) { } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/AlignedMemoryReader.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/AlignedMemoryReader.cs new file mode 100644 index 000000000..2d61b9a9f --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/AlignedMemoryReader.cs @@ -0,0 +1,31 @@ +using System.Diagnostics; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public static class AlignedMemoryReader +{ + public static unsafe AlignedMemory ReadAllBytes(string path, int bufferSize = 1024 * 1024) + { + using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, false); + var fileLength = fs.Length; + if (fileLength > int.MaxValue) + throw new IOException("File too big: > 2GB"); + + var count = (int)fileLength; + var r = new AlignedMemory(count); + var pBytes = r.BytePtr; + while (count > 0) + { + var span = new Span(pBytes, count); + var n = fs.Read(span); + if (n == 0) + break; + pBytes += n; + count -= n; + } + + Debug.Assert(count == 0); + return r; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/ByteSpanExtensions.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/ByteSpanExtensions.cs new file mode 100644 index 000000000..60bccc81a --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/ByteSpanExtensions.cs @@ -0,0 +1,13 @@ +using System.Runtime.CompilerServices; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public static class ByteSpanExtensions +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double ToDouble(this ByteSpan self) => double.Parse(self.ToSpan()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ToInt(this ByteSpan self) => int.Parse(self.ToSpan()); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepDocument.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepDocument.cs new file mode 100644 index 000000000..e56a490d3 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepDocument.cs @@ -0,0 +1,102 @@ +using System.Runtime.Intrinsics; +using Ara3D.Buffers; +using Ara3D.Logging; +using Ara3D.Utils; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public sealed unsafe class StepDocument : IDisposable +{ + public readonly FilePath FilePath; + public readonly byte* DataStart; + public readonly byte* DataEnd; + public readonly AlignedMemory Data; + + /// + /// This is a list of raw step instance information. + /// Each one has only a type and an ID. + /// + public readonly StepRawInstance[] RawInstances; + + /// + /// The number of raw instance + /// + public readonly int NumRawInstances; + + /// + /// This gives us a fast way to look up a StepInstance by their ID + /// + public readonly Dictionary InstanceIdToIndex = new(); + + /// + /// This tells us the byte offset of the start of each line in the file + /// + public readonly List LineOffsets; + + public StepDocument(FilePath filePath, ILogger? logger = null) + { + FilePath = filePath; + logger ??= Logger.Null; + + logger.Log($"Loading {filePath.GetFileSizeAsString()} of data from {filePath.GetFileName()}"); + Data = AlignedMemoryReader.ReadAllBytes(filePath); + DataStart = Data.BytePtr; + DataEnd = DataStart + Data.NumBytes; + + logger.Log($"Computing the start of each line"); + // NOTE: this estimates that the average line length is at least 32 characters. + // This minimize the number of allocations that happen + var cap = Data.NumBytes / 32; + LineOffsets = new List(cap); + + // We are going to report the beginning of the lines, while the "ComputeLines" function + // will compute the ends of lines. + var currentLine = 1; + for (var i = 0; i < Data.NumVectors; i++) + { + StepLineParser.ComputeOffsets(((Vector256*)Data.BytePtr)[i], ref currentLine, LineOffsets); + } + + logger.Log($"Found {LineOffsets.Count} lines"); + + logger.Log($"Creating instance records"); + RawInstances = new StepRawInstance[LineOffsets.Count]; + + for (var i = 0; i < LineOffsets.Count - 1; i++) + { + var lineStart = LineOffsets[i]; + var lineEnd = LineOffsets[i + 1]; + var inst = StepLineParser.ParseLine(DataStart + lineStart, DataStart + lineEnd); + if (inst.IsValid()) + { + InstanceIdToIndex.Add(inst.Id, NumRawInstances); + RawInstances[NumRawInstances++] = inst; + } + } + + logger.Log($"Completed creation of STEP document from {filePath.GetFileName()}"); + } + + public void Dispose() => Data.Dispose(); + + public StepInstance GetInstanceWithData(uint id) => GetInstanceWithDataFromIndex(InstanceIdToIndex[id]); + + public StepInstance GetInstanceWithDataFromIndex(int index) => GetInstanceWithData(RawInstances[index]); + + public StepInstance GetInstanceWithData(StepRawInstance inst) + { + var attr = inst.GetAttributes(DataEnd); + var se = new StepEntity(inst.Type, attr); + return new StepInstance(inst.Id, se); + } + + public static StepDocument Create(FilePath fp) => new(fp); + + public IEnumerable GetRawInstances(string typeCode) => + RawInstances.Where(inst => inst.Type.Equals(typeCode)); + + public IEnumerable GetInstances() => RawInstances.Select(GetInstanceWithData); + + public IEnumerable GetInstances(string typeCode) => + GetRawInstances(typeCode).Select(GetInstanceWithData); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepFactory.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepFactory.cs new file mode 100644 index 000000000..e7cb5bbab --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepFactory.cs @@ -0,0 +1,90 @@ +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public static unsafe class StepFactory +{ + public static StepList GetAttributes(this StepRawInstance inst, byte* lineEnd) + { + if (!inst.IsValid()) + return StepList.CreateDefault(); + var ptr = inst.Type.End(); + var token = StepTokenizer.ParseToken(ptr, lineEnd); + // TODO: there is a potential bug here when the line is split across multiple line + return CreateAggregate(ref token, lineEnd); + } + + public static StepValue Create(ref StepToken token, byte* end) + { + switch (token.Type) + { + case StepTokenType.String: + return StepString.Create(token); + + case StepTokenType.Symbol: + return StepSymbol.Create(token); + + case StepTokenType.Id: + return StepId.Create(token); + + case StepTokenType.Redeclared: + return StepRedeclared.Create(token); + + case StepTokenType.Unassigned: + return StepUnassigned.Create(token); + + case StepTokenType.Number: + return StepNumber.Create(token); + + case StepTokenType.Ident: + var span = token.Span; + StepTokenizer.ParseNextToken(ref token, end); + var attr = CreateAggregate(ref token, end); + return new StepEntity(span, attr); + + case StepTokenType.BeginGroup: + return CreateAggregate(ref token, end); + + case StepTokenType.None: + case StepTokenType.Whitespace: + case StepTokenType.Comment: + case StepTokenType.Unknown: + case StepTokenType.LineBreak: + case StepTokenType.EndOfLine: + case StepTokenType.Definition: + case StepTokenType.Separator: + case StepTokenType.EndGroup: + default: + throw new SpeckleIfcException($"Cannot convert token type {token.Type} to a StepValue"); + } + } + + public static StepList CreateAggregate(ref StepToken token, byte* end) + { + var values = new List(); + StepTokenizer.EatWSpace(ref token, end); + if (token.Type != StepTokenType.BeginGroup) + throw new SpeckleIfcException("Expected '('"); + + while (StepTokenizer.ParseNextToken(ref token, end)) + { + switch (token.Type) + { + // Advance past comments, whitespace, and commas + case StepTokenType.Comment: + case StepTokenType.Whitespace: + case StepTokenType.LineBreak: + case StepTokenType.Separator: + case StepTokenType.None: + continue; + + // Expected end of group + case StepTokenType.EndGroup: + return new StepList(values); + } + + var curValue = Create(ref token, end); + values.Add(curValue); + } + + throw new SpeckleIfcException("Unexpected end of input"); + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepGraph.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepGraph.cs new file mode 100644 index 000000000..dd45cba98 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepGraph.cs @@ -0,0 +1,59 @@ +using Ara3D.Utils; +using Speckle.Sdk.Common; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public class StepGraph +{ + public StepDocument Document { get; } + + public readonly Dictionary Lookup = new(); + + public StepNode GetNode(uint id) => Lookup[id]; + + public IEnumerable Nodes => Lookup.Values; + + public StepGraph(StepDocument doc) + { + Document = doc; + + foreach (var e in doc.GetInstances()) + { + var node = new StepNode(this, e); + Lookup.Add(node.Entity.Id, node); + } + + foreach (var n in Nodes) + n.Init(); + } + + public static StepGraph Create(StepDocument doc) => new(doc); + + public string ToValString(StepNode node, int depth) => ToValString(node.Entity.Entity, depth - 1); + + public string ToValString(StepValue value, int depth) + { + if (value == null) + return ""; + + switch (value) + { + case StepList stepAggregate: + return $"({stepAggregate.Values.Select(v => ToValString(v, depth)).JoinStringsWithComma()})"; + + case StepEntity stepEntity: + return $"{stepEntity.EntityType}{ToValString(stepEntity.Attributes, depth)}"; + + case StepId stepId: + return depth <= 0 ? "#" : ToValString(GetNode(stepId.Id), depth - 1); + + case StepNumber stepNumber: + case StepRedeclared stepRedeclared: + case StepString stepString: + case StepSymbol stepSymbol: + case StepUnassigned stepUnassigned: + default: + return value.ToString().NotNull(); + } + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepInstance.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepInstance.cs new file mode 100644 index 000000000..8d405acc5 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepInstance.cs @@ -0,0 +1,25 @@ +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public class StepInstance +{ + public readonly StepEntity Entity; + public readonly uint Id; + + public List AttributeValues => Entity.Attributes.Values; + + public string EntityType => Entity?.EntityType.ToString() ?? ""; + + public StepInstance(uint id, StepEntity entity) + { + Id = id; + Entity = entity; + } + + public bool IsEntityType(string str) => EntityType == str; + + public override string ToString() => $"#{Id}={Entity};"; + + public int Count => AttributeValues.Count; + + public StepValue this[int i] => AttributeValues[i]; +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepLineParser.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepLineParser.cs new file mode 100644 index 000000000..48316abfe --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepLineParser.cs @@ -0,0 +1,151 @@ +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public static class StepLineParser +{ + public static readonly Vector256 Comma = Vector256.Create((byte)','); + public static readonly Vector256 NewLine = Vector256.Create((byte)'\n'); + public static readonly Vector256 StartGroup = Vector256.Create((byte)'('); + public static readonly Vector256 EndGroup = Vector256.Create((byte)')'); + public static readonly Vector256 Definition = Vector256.Create((byte)'='); + public static readonly Vector256 Quote = Vector256.Create((byte)'\''); + public static readonly Vector256 Id = Vector256.Create((byte)'#'); + public static readonly Vector256 SemiColon = Vector256.Create((byte)';'); + public static readonly Vector256 Unassigned = Vector256.Create((byte)'*'); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ComputeOffsets(in Vector256 v, ref int index, List offsets) + { + var r = Avx2.CompareEqual(v, NewLine); + var mask = (uint)Avx2.MoveMask(r); + if (mask == 0) + { + index += 32; + return; + } + + // Fully unrolled handling of each bit + if ((mask & 0x00000001) != 0) + offsets.Add(index); + if ((mask & 0x00000002) != 0) + offsets.Add(index + 1); + if ((mask & 0x00000004) != 0) + offsets.Add(index + 2); + if ((mask & 0x00000008) != 0) + offsets.Add(index + 3); + if ((mask & 0x00000010) != 0) + offsets.Add(index + 4); + if ((mask & 0x00000020) != 0) + offsets.Add(index + 5); + if ((mask & 0x00000040) != 0) + offsets.Add(index + 6); + if ((mask & 0x00000080) != 0) + offsets.Add(index + 7); + if ((mask & 0x00000100) != 0) + offsets.Add(index + 8); + if ((mask & 0x00000200) != 0) + offsets.Add(index + 9); + if ((mask & 0x00000400) != 0) + offsets.Add(index + 10); + if ((mask & 0x00000800) != 0) + offsets.Add(index + 11); + if ((mask & 0x00001000) != 0) + offsets.Add(index + 12); + if ((mask & 0x00002000) != 0) + offsets.Add(index + 13); + if ((mask & 0x00004000) != 0) + offsets.Add(index + 14); + if ((mask & 0x00008000) != 0) + offsets.Add(index + 15); + if ((mask & 0x00010000) != 0) + offsets.Add(index + 16); + if ((mask & 0x00020000) != 0) + offsets.Add(index + 17); + if ((mask & 0x00040000) != 0) + offsets.Add(index + 18); + if ((mask & 0x00080000) != 0) + offsets.Add(index + 19); + if ((mask & 0x00100000) != 0) + offsets.Add(index + 20); + if ((mask & 0x00200000) != 0) + offsets.Add(index + 21); + if ((mask & 0x00400000) != 0) + offsets.Add(index + 22); + if ((mask & 0x00800000) != 0) + offsets.Add(index + 23); + if ((mask & 0x01000000) != 0) + offsets.Add(index + 24); + if ((mask & 0x02000000) != 0) + offsets.Add(index + 25); + if ((mask & 0x04000000) != 0) + offsets.Add(index + 26); + if ((mask & 0x08000000) != 0) + offsets.Add(index + 27); + if ((mask & 0x10000000) != 0) + offsets.Add(index + 28); + if ((mask & 0x20000000) != 0) + offsets.Add(index + 29); + if ((mask & 0x40000000) != 0) + offsets.Add(index + 30); + if ((mask & 0x80000000) != 0) + offsets.Add(index + 31); + + // Update lineIndex to the next starting position + index += 32; + } + + public static unsafe StepRawInstance ParseLine(byte* ptr, byte* end) + { + var start = ptr; + var cnt = end - ptr; + const int MIN_LINE_LENGTH = 5; + if (cnt < MIN_LINE_LENGTH) + return default; + + // Parse the ID + if (*ptr++ != '#') + return default; + + var id = 0u; + while (ptr < end) + { + if (*ptr < '0' || *ptr > '9') + break; + id = id * 10 + *ptr - '0'; + ptr++; + } + + var foundEquals = false; + while (ptr < end) + { + if (*ptr == '=') + foundEquals = true; + + if (*ptr != (byte)' ' && *ptr != (byte)'=') + break; + + ptr++; + } + + if (!foundEquals) + return default; + + // Parse the entity type name + var entityStart = ptr; + while (ptr < end) + { + if (!StepTokenizer.IsIdentLookup[*ptr]) + break; + ptr++; + } + if (ptr == entityStart) + return default; + + var entityType = new ByteSpan(entityStart, ptr); + return new(id, entityType, start); + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepNode.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepNode.cs new file mode 100644 index 000000000..c23188c7a --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepNode.cs @@ -0,0 +1,52 @@ +using Ara3D.Utils; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public class StepNode +{ + public readonly StepGraph Graph; + public readonly StepInstance Entity; + + public StepNode(StepGraph g, StepInstance e) + { + Graph = g; + Entity = e; + } + + public List Nodes { get; } = new(); + + private void AddNodes(StepValue value) + { + if (value is StepId id) + { + var n = Graph.GetNode(id.Id); + Nodes.Add(n); + } + else if (value is StepList agg) + { + foreach (var v in agg.Values) + AddNodes(v); + } + } + + public void Init() + { + foreach (var a in Entity.AttributeValues) + AddNodes(a); + } + + public override string ToString() => Entity.ToString(); + + public string ToGraph(HashSet? prev = null) + { + prev ??= new HashSet(); + if (prev.Contains(this)) + return "_"; + var nodeStr = Nodes.Select(n => n.ToGraph(prev)).JoinStringsWithComma(); + return $"{EntityType}({nodeStr})"; + } + + public string EntityType => Entity.EntityType; + + public string QuickHash() => $"{EntityType}:{Nodes.Count}"; +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepRawInstance.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepRawInstance.cs new file mode 100644 index 000000000..ee15dd920 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepRawInstance.cs @@ -0,0 +1,20 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +/// +/// Contains information about where an instance is within a file. +/// +[StructLayout(LayoutKind.Sequential, Pack = 1)] +[method: MethodImpl(MethodImplOptions.AggressiveInlining)] +public readonly unsafe struct StepRawInstance(uint id, ByteSpan type, byte* ptr) +{ + public readonly uint Id = id; + public readonly ByteSpan Type = type; + public readonly byte* Ptr = ptr; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsValid() => Id > 0; +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepToken.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepToken.cs new file mode 100644 index 000000000..19fc352ee --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepToken.cs @@ -0,0 +1,17 @@ +using System.Diagnostics; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public readonly struct StepToken +{ + public readonly ByteSpan Span; + public readonly StepTokenType Type; + + public StepToken(ByteSpan span, StepTokenType type) + { + Span = span; + Debug.Assert(span.Length > 0); + Type = type; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenType.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenType.cs new file mode 100644 index 000000000..f42e11b6b --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenType.cs @@ -0,0 +1,22 @@ +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public enum StepTokenType : byte +{ + None, + Ident, + String, + Whitespace, + Number, + Symbol, + Id, + Separator, + Unassigned, + Redeclared, + Comment, + Unknown, + BeginGroup, + EndGroup, + LineBreak, + EndOfLine, + Definition, +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenizer.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenizer.cs new file mode 100644 index 000000000..a23a2e949 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepTokenizer.cs @@ -0,0 +1,306 @@ +using System.Diagnostics; +using System.Runtime.CompilerServices; +using Ara3D.Buffers; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +public static class StepTokenizer +{ + public static readonly StepTokenType[] TokenLookup = CreateTokenLookup(); + + public static readonly bool[] IsNumberLookup = CreateNumberLookup(); + + public static readonly bool[] IsIdentLookup = CreateIdentLookup(); + + public static StepTokenType[] CreateTokenLookup() + { + var r = new StepTokenType[256]; + for (var i = 0; i < 256; i++) + r[i] = GetTokenType((byte)i); + return r; + } + + public static bool[] CreateNumberLookup() + { + var r = new bool[256]; + for (var i = 0; i < 256; i++) + r[i] = IsNumberChar((byte)i); + return r; + } + + public static bool[] CreateIdentLookup() + { + var r = new bool[256]; + for (var i = 0; i < 256; i++) + r[i] = IsIdentOrDigitChar((byte)i); + return r; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StepTokenType LookupToken(byte b) => TokenLookup[b]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumberChar(byte b) + { + switch (b) + { + case (byte)'0': + case (byte)'1': + case (byte)'2': + case (byte)'3': + case (byte)'4': + case (byte)'5': + case (byte)'6': + case (byte)'7': + case (byte)'8': + case (byte)'9': + case (byte)'E': + case (byte)'e': + case (byte)'+': + case (byte)'-': + case (byte)'.': + return true; + } + + return false; + } + + public static StepTokenType GetTokenType(byte b) + { + switch (b) + { + case (byte)'0': + case (byte)'1': + case (byte)'2': + case (byte)'3': + case (byte)'4': + case (byte)'5': + case (byte)'6': + case (byte)'7': + case (byte)'8': + case (byte)'9': + case (byte)'+': + case (byte)'-': + return StepTokenType.Number; + + case (byte)' ': + case (byte)'\t': + return StepTokenType.Whitespace; + + case (byte)'\n': + case (byte)'\r': + return StepTokenType.LineBreak; + + case (byte)'\'': + case (byte)'"': + return StepTokenType.String; + + case (byte)'.': + return StepTokenType.Symbol; + + case (byte)'#': + return StepTokenType.Id; + + case (byte)';': + return StepTokenType.EndOfLine; + + case (byte)'(': + return StepTokenType.BeginGroup; + + case (byte)'=': + return StepTokenType.Definition; + + case (byte)')': + return StepTokenType.EndGroup; + + case (byte)',': + return StepTokenType.Separator; + + case (byte)'$': + return StepTokenType.Unassigned; + + case (byte)'*': + return StepTokenType.Redeclared; + + case (byte)'/': + return StepTokenType.Comment; + + case (byte)'a': + case (byte)'b': + case (byte)'c': + case (byte)'d': + case (byte)'e': + case (byte)'f': + case (byte)'g': + case (byte)'h': + case (byte)'i': + case (byte)'j': + case (byte)'k': + case (byte)'l': + case (byte)'m': + case (byte)'n': + case (byte)'o': + case (byte)'p': + case (byte)'q': + case (byte)'r': + case (byte)'s': + case (byte)'t': + case (byte)'u': + case (byte)'v': + case (byte)'w': + case (byte)'x': + case (byte)'y': + case (byte)'z': + case (byte)'A': + case (byte)'B': + case (byte)'C': + case (byte)'D': + case (byte)'E': + case (byte)'F': + case (byte)'G': + case (byte)'H': + case (byte)'I': + case (byte)'J': + case (byte)'K': + case (byte)'L': + case (byte)'M': + case (byte)'N': + case (byte)'O': + case (byte)'P': + case (byte)'Q': + case (byte)'R': + case (byte)'S': + case (byte)'T': + case (byte)'U': + case (byte)'V': + case (byte)'W': + case (byte)'X': + case (byte)'Y': + case (byte)'Z': + case (byte)'_': + return StepTokenType.Ident; + + default: + return StepTokenType.Unknown; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsWhiteSpace(byte b) => b == ' ' || b == '\t'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsLineBreak(byte b) => b == '\n' || b == '\r'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsIdent(byte b) => b >= 'A' && b <= 'Z' || b >= 'a' && b <= 'z' || b == '_'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsDigit(byte b) => b >= '0' && b <= '9'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsIdentOrDigitChar(byte b) => IsIdent(b) || IsDigit(b); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe byte* AdvancePast(byte* begin, byte* end, string s) + { + if (end - begin < s.Length) + return null; + foreach (var c in s) + if (*begin++ != (byte)c) + return null; + return begin; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe StepToken ParseToken(byte* begin, byte* end) + { + var cur = begin; + var tt = InternalParseToken(ref cur, end); + Debug.Assert(cur < end); + var span = new ByteSpan(begin, cur); + return new StepToken(span, tt); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool EatWSpace(ref StepToken cur, byte* end) + { + while ( + cur.Type == StepTokenType.Comment || cur.Type == StepTokenType.Whitespace || cur.Type == StepTokenType.LineBreak + ) + { + if (!ParseNextToken(ref cur, end)) + return false; + } + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool ParseNextToken(ref StepToken prev, byte* end) + { + var cur = prev.Span.End(); + if (cur >= end) + return false; + prev = ParseToken(cur, end); + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe StepTokenType InternalParseToken(ref byte* cur, byte* end) + { + var type = TokenLookup[*cur++]; + + switch (type) + { + case StepTokenType.Ident: + while (IsIdentLookup[*cur]) + cur++; + break; + + case StepTokenType.String: + // usually it is as single quote, + // but in rare cases it could be a double quote + var quoteChar = *(cur - 1); + while (cur < end) + { + if (*cur++ == quoteChar) + { + if (*cur != quoteChar) + break; + else + cur++; + } + } + + break; + + case StepTokenType.LineBreak: + while (IsLineBreak(*cur)) + cur++; + break; + + case StepTokenType.Number: + while (IsNumberLookup[*cur]) + cur++; + break; + + case StepTokenType.Symbol: + while (*cur++ != '.') { } + + break; + + case StepTokenType.Id: + while (IsNumberLookup[*cur]) + cur++; + break; + + case StepTokenType.Comment: + var prev = *cur++; + while (cur < end && (prev != '*' || *cur != '/')) + prev = *cur++; + cur++; + break; + } + + return type; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepValue.cs b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepValue.cs new file mode 100644 index 000000000..6b1e93bf9 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Ara3D.StepParser/StepValue.cs @@ -0,0 +1,154 @@ +using System.Diagnostics; +using Ara3D.Buffers; +using Ara3D.Utils; + +namespace Speckle.Importers.Ifc.Ara3D.StepParser; + +/// +/// The base class of the different type of value items that can be found in a STEP file. +/// * Entity +/// * List +/// * String +/// * Symbol +/// * Unassigned token +/// * Redeclared token +/// * Number +/// +public class StepValue; + +public class StepEntity : StepValue +{ + public readonly ByteSpan EntityType; + public readonly StepList Attributes; + + public StepEntity(ByteSpan entityType, StepList attributes) + { + Debug.Assert(!entityType.IsNull()); + EntityType = entityType; + Attributes = attributes; + } + + public override string ToString() => $"{EntityType}{Attributes}"; +} + +public class StepList : StepValue +{ + public readonly List Values; + + public StepList(List values) => Values = values; + + public override string ToString() => $"({Values.JoinStringsWithComma()})"; + + public static StepList CreateDefault() => new(new List()); +} + +public class StepString : StepValue +{ + public readonly ByteSpan Value; + + public static StepString Create(StepToken token) + { + var span = token.Span; + Debug.Assert(token.Type == StepTokenType.String); + Debug.Assert(span.Length >= 2); + Debug.Assert(span.First() == '\'' || span.First() == '"'); + Debug.Assert(span.Last() == '\'' || span.Last() == '"'); + return new StepString(span.Trim(1, 1)); + } + + public StepString(ByteSpan value) => Value = value; + + public override string ToString() => $"'{Value}'"; +} + +public class StepSymbol : StepValue +{ + public readonly ByteSpan Name; + + public StepSymbol(ByteSpan name) => Name = name; + + public override string ToString() => $".{Name}."; + + public static StepSymbol Create(StepToken token) + { + Debug.Assert(token.Type == StepTokenType.Symbol); + var span = token.Span; + Debug.Assert(span.Length >= 2); + Debug.Assert(span.First() == '.'); + Debug.Assert(span.Last() == '.'); + return new StepSymbol(span.Trim(1, 1)); + } +} + +public class StepNumber : StepValue +{ + public readonly ByteSpan Span; + public double Value => Span.ToDouble(); + + public StepNumber(ByteSpan span) => Span = span; + + public override string ToString() => $"{Value}"; + + public static StepNumber Create(StepToken token) + { + Debug.Assert(token.Type == StepTokenType.Number); + var span = token.Span; + return new(span); + } +} + +public class StepId : StepValue +{ + public readonly uint Id; + + public StepId(uint id) => Id = id; + + public override string ToString() => $"#{Id}"; + + public static unsafe StepId Create(StepToken token) + { + Debug.Assert(token.Type == StepTokenType.Id); + var span = token.Span; + Debug.Assert(span.Length >= 2); + Debug.Assert(span.First() == '#'); + var id = 0u; + for (var i = 1; i < span.Length; ++i) + { + Debug.Assert(span.Ptr[i] >= '0' && span.Ptr[i] <= '9'); + id = id * 10 + span.Ptr[i] - '0'; + } + return new StepId(id); + } +} + +public class StepUnassigned : StepValue +{ + public static readonly StepUnassigned Default = new(); + + public override string ToString() => "$"; + + public static StepUnassigned Create(StepToken token) + { + Debug.Assert(token.Type == StepTokenType.Unassigned); + var span = token.Span; + Debug.Assert(span.Length == 1); + Debug.Assert(span.First() == '$'); + return Default; + } +} + +public class StepRedeclared : StepValue +{ + public static readonly StepRedeclared Default = new(); + + public override string ToString() => "*"; + + public static StepRedeclared Create(StepToken token) + { + Debug.Assert(token.Type == StepTokenType.Redeclared); + var span = token.Span; + Debug.Assert(span.Length == 1); + Debug.Assert(span.First() == '*'); + return Default; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Converters/GeometryConverter.cs b/Importers/Ifc/Speckle.Importers.Ifc/Converters/GeometryConverter.cs new file mode 100644 index 000000000..c59ad90b9 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Converters/GeometryConverter.cs @@ -0,0 +1,20 @@ +using Speckle.Importers.Ifc.Types; +using Speckle.InterfaceGenerator; +using Speckle.Sdk.Models.Collections; + +namespace Speckle.Importers.Ifc.Converters; + +[GenerateAutoInterface] +public class GeometryConverter(IMeshConverter meshConverter) : IGeometryConverter +{ + public Collection Convert(IfcGeometry geometry) + { + var c = new Collection(); + foreach (var mesh in geometry.GetMeshes()) + { + c.elements.Add(meshConverter.Convert(mesh)); + } + + return c; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Converters/GraphConverter.cs b/Importers/Ifc/Speckle.Importers.Ifc/Converters/GraphConverter.cs new file mode 100644 index 000000000..3c6c3f88d --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Converters/GraphConverter.cs @@ -0,0 +1,19 @@ +using Speckle.Importers.Ifc.Ara3D.IfcParser; +using Speckle.Importers.Ifc.Types; +using Speckle.InterfaceGenerator; +using Speckle.Sdk.Models; +using Speckle.Sdk.Models.Collections; + +namespace Speckle.Importers.Ifc.Converters; + +[GenerateAutoInterface] +public class GraphConverter(INodeConverter nodeConverter) : IGraphConverter +{ + public Base Convert(IfcModel model, IfcGraph graph) + { + var collection = new Collection(); + var children = graph.GetSources().Select(x => nodeConverter.Convert(model, x)).ToList(); + collection.elements = children; + return collection; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Converters/MeshConverter.cs b/Importers/Ifc/Speckle.Importers.Ifc/Converters/MeshConverter.cs new file mode 100644 index 000000000..961bc3297 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Converters/MeshConverter.cs @@ -0,0 +1,49 @@ +using Speckle.Importers.Ifc.Types; +using Speckle.InterfaceGenerator; +using Speckle.Objects.Geometry; + +namespace Speckle.Importers.Ifc.Converters; + +[GenerateAutoInterface] +public class MeshConverter : IMeshConverter +{ + public unsafe Mesh Convert(IfcMesh mesh) + { + var m = (double*)mesh.Transform; + var vp = mesh.GetVertices(); + var ip = mesh.GetIndexes(); + + var vertices = new List(mesh.VertexCount * 3); + for (var i = 0; i < mesh.VertexCount; i++) + { + var x = vp[i].PX; + var y = vp[i].PY; + var z = vp[i].PZ; + vertices.Add(m[0] * x + m[4] * y + m[8] * z + m[12]); + vertices.Add(-(m[2] * x + m[6] * y + m[10] * z + m[14])); + vertices.Add(m[1] * x + m[5] * y + m[9] * z + m[13]); + } + + var faces = new List(mesh.IndexCount * 4); + for (var i = 0; i < mesh.IndexCount; i += 3) + { + var a = ip[i]; + var b = ip[i + 1]; + var c = ip[i + 2]; + faces.Add(3); + faces.Add(a); + faces.Add(b); + faces.Add(c); + } + + var color = mesh.GetColor(); + List colors = [(int)(color->A * 255), (int)(color->R * 255), (int)(color->G * 255), (int)(color->B * 255),]; + return new Mesh() + { + colors = colors, + vertices = vertices, + faces = faces, + units = "m", + }; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Converters/NodeConverter.cs b/Importers/Ifc/Speckle.Importers.Ifc/Converters/NodeConverter.cs new file mode 100644 index 000000000..f9b246d27 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Converters/NodeConverter.cs @@ -0,0 +1,73 @@ +using System.Reflection; +using Speckle.Importers.Ifc.Ara3D.IfcParser; +using Speckle.Importers.Ifc.Types; +using Speckle.InterfaceGenerator; +using Speckle.Sdk.Models; + +namespace Speckle.Importers.Ifc.Converters; + +[GenerateAutoInterface] +public class NodeConverter(IGeometryConverter geometryConverter) : INodeConverter +{ + public Base Convert(IfcModel model, IfcNode node) + { + var b = new Base(); + if (node is IfcPropSet ps) + { + b["Name"] = ps.Name; + b["GlobalId"] = ps.Guid; + } + + // https://github.com/specklesystems/speckle-server/issues/1180 + b["ifc_type"] = node.Type; + + // This is required because "speckle_type" has no setter, but is backed by a private field. + var baseType = typeof(Base); + var typeField = baseType.GetField("_type", BindingFlags.Instance | BindingFlags.NonPublic); + typeField?.SetValue(b, node.Type); + + // Guid is null for property values, and other Ifc entities not derived from IfcRoot + b.applicationId = node.Guid; + + // This is the express ID used to identify an entity wihtin a file. + b["expressID"] = node.Id; + + // Even if there is no geometry, this will return an empty collection. + var geo = model.GetGeometry(node.Id); + if (geo != null) + { + var c = geometryConverter.Convert(geo); + if (c.elements.Count > 0) + b["@displayValue"] = c.elements; + } + + // Create the children + var children = node.GetChildren().Select(x => Convert(model, x)).ToList(); + b["@elements"] = children; + + // Add the properties + foreach (var p in node.GetPropSets()) + { + // Only when there are actually some properties. + if (p.NumProperties > 0) + { + var name = p.Name; + if (string.IsNullOrWhiteSpace(name)) + name = $"#{p.Id}"; + b[name] = ToSpeckleDictionary(p); + } + } + + // TODO: add the "type" properties + + return b; + } + + public static Dictionary ToSpeckleDictionary(IfcPropSet ps) + { + var d = new Dictionary(); + foreach (var p in ps.GetProperties()) + d[p.Name] = p.Value.ToJsonObject(); + return d; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Import.cs b/Importers/Ifc/Speckle.Importers.Ifc/Import.cs new file mode 100644 index 000000000..b32fa2c2e --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Import.cs @@ -0,0 +1,107 @@ +using System.Diagnostics; +using System.Reflection; +using Ara3D.Utils; +using Microsoft.Extensions.DependencyInjection; +using Speckle.Importers.Ifc.Ara3D.IfcParser; +using Speckle.Importers.Ifc.Converters; +using Speckle.Importers.Ifc.Types; +using Speckle.Objects.Geometry; +using Speckle.Sdk; +using Speckle.Sdk.Api; +using Speckle.Sdk.Api.GraphQL.Inputs; +using Speckle.Sdk.Api.GraphQL.Models; +using Speckle.Sdk.Credentials; +using Speckle.Sdk.Host; +using Speckle.Sdk.Models; +using Speckle.Sdk.Serialisation.V2; +using Speckle.Sdk.Serialisation.V2.Send; +using Speckle.Sdk.Transports; + +namespace Speckle.Importers.Ifc; + +public static class Import +{ + public static async Task Ifc( + string url, + string filePath, + string streamId, + string modelId, + string commitMessage, + string token, + IProgress? progress = null + ) + { + var serviceProvider = GetServiceProvider(); + return await Ifc(serviceProvider, url, filePath, streamId, modelId, commitMessage, token, progress); + } + + public static ServiceProvider GetServiceProvider() + { + TypeLoader.Initialize(typeof(Base).Assembly, typeof(Point).Assembly); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddSpeckleSdk(HostApplications.Other, HostAppVersion.v2024, "IFC-Importer"); + serviceCollection.AddSpeckleWebIfc(); + serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly()); + return serviceCollection.BuildServiceProvider(); + } + + public static async Task Ifc( + IServiceProvider serviceProvider, + string url, + string filePath, + string streamId, + string modelId, + string commitMessage, + string token, + IProgress? progress = null + ) + { + var ifcFactory = serviceProvider.GetRequiredService(); + var clientFactory = serviceProvider.GetRequiredService(); + var baseUri = new Uri(url); + var stopwatch = Stopwatch.StartNew(); + + var model = ifcFactory.Open(filePath); + var ms = stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Opened with WebIFC: {ms} ms"); + + var graph = IfcGraph.Load(new FilePath(filePath)); + var ms2 = stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Loaded with StepParser: {ms2 - ms} ms"); + + var converter = serviceProvider.GetRequiredService(); + var b = converter.Convert(model, graph); + ms = ms2; + ms2 = stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Converted to Speckle Bases: {ms2 - ms} ms"); + + var serializeProcessFactory = serviceProvider.GetRequiredService(); + var process = serializeProcessFactory.CreateSerializeProcess( + baseUri, + streamId, + token, + progress, + new SerializeProcessOptions(true, true, true, false) + ); + var (rootId, _) = await process.Serialize(b, default).ConfigureAwait(false); + Account account = + new() + { + token = token, + serverInfo = new ServerInfo { url = baseUri.ToString() }, + }; + ms = ms2; + ms2 = stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Uploaded to Speckle: {ms2 - ms} ms"); + + // 8 - Create the version (commit) + using var apiClient = clientFactory.Create(account); + var commitId = await apiClient.Version.Create( + new CreateVersionInput(rootId, modelId, streamId, message: commitMessage) + ); + ms = ms2; + ms2 = stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Committed to Speckle: {ms2 - ms} ms"); + return commitId; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Native/WebIfc.cs b/Importers/Ifc/Speckle.Importers.Ifc/Native/WebIfc.cs new file mode 100644 index 000000000..52f182185 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Native/WebIfc.cs @@ -0,0 +1,108 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace Speckle.Importers.Ifc.Native; + +[SuppressMessage("Globalization", "CA2101:Specify marshaling for P/Invoke string arguments")] +[SuppressMessage("Interoperability", "CA1401:P/Invokes should not be visible")] +[SuppressMessage("Security", "CA5393:Do not use unsafe DllImportSearchPath value")] +public static class WebIfc +{ +#if WINDOWS + private const string DllName = "web-ifc.dll"; + private const CharSet Set = CharSet.Ansi; +#else + private const string DllName = "libweb-ifc.so"; + private const CharSet Set = CharSet.Auto; +#endif + + private const DllImportSearchPath ImportSearchPath = DllImportSearchPath.AssemblyDirectory; + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr InitializeApi(); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern void FinalizeApi(IntPtr api); + + [DllImport(DllName, CharSet = Set)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr LoadModel(IntPtr api, string fileName); + + [DllImport(DllName, CharSet = Set)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern string GetVersion(); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetMesh(IntPtr geometry, int index); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern int GetNumMeshes(IntPtr geometry); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern uint GetGeometryType(IntPtr geometry); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern uint GetGeometryId(IntPtr geometry); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern uint GetLineId(IntPtr line); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern uint GetLineType(IntPtr line); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern string GetLineArguments(IntPtr line); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern int GetNumVertices(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetVertices(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetTransform(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern int GetNumIndices(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetIndices(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetColor(IntPtr mesh); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetGeometryFromId(IntPtr model, uint id); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern int GetNumGeometries(IntPtr model); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetGeometryFromIndex(IntPtr model, int index); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern uint GetMaxId(IntPtr model); + + [DllImport(DllName)] + [DefaultDllImportSearchPaths(ImportSearchPath)] + public static extern IntPtr GetLineFromModel(IntPtr model, uint id); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Native/libweb-ifc.so b/Importers/Ifc/Speckle.Importers.Ifc/Native/libweb-ifc.so new file mode 100644 index 000000000..b303c198d Binary files /dev/null and b/Importers/Ifc/Speckle.Importers.Ifc/Native/libweb-ifc.so differ diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Native/web-ifc.dll b/Importers/Ifc/Speckle.Importers.Ifc/Native/web-ifc.dll new file mode 100644 index 000000000..35808817c Binary files /dev/null and b/Importers/Ifc/Speckle.Importers.Ifc/Native/web-ifc.dll differ diff --git a/Importers/Ifc/Speckle.Importers.Ifc/ServiceRegistration.cs b/Importers/Ifc/Speckle.Importers.Ifc/ServiceRegistration.cs new file mode 100644 index 000000000..129d398d6 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/ServiceRegistration.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Speckle.Importers.Ifc.Types; +using Speckle.Sdk; + +namespace Speckle.Importers.Ifc; + +public static class ServiceRegistration +{ + public static void AddSpeckleWebIfc(this IServiceCollection services) + { + services.AddSingleton(); + } + + public static IServiceCollection AddMatchingInterfacesAsTransient( + this IServiceCollection serviceCollection, + Assembly assembly + ) + { + foreach (var type in assembly.ExportedTypes.Where(t => t.IsNonAbstractClass())) + { + foreach (var matchingInterface in type.FindMatchingInterface()) + { + serviceCollection.TryAddTransient(matchingInterface, type); + } + } + + return serviceCollection; + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Speckle.Importers.Ifc.csproj b/Importers/Ifc/Speckle.Importers.Ifc/Speckle.Importers.Ifc.csproj new file mode 100644 index 000000000..b2b80aa0f --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Speckle.Importers.Ifc.csproj @@ -0,0 +1,43 @@ + + + + net8.0 + true + Debug;Release;Local + WINDOWS + LINUX + + + + true + true + + + + + IDE1006;IDE0130;IDE0011;CA1051;CA1720;CA1002;CA1054;CA1028;CA1721;CA1502;CA1065;NU5104; + $(NoWarn) + + + + + + + + + + + + + + + + PreserveNewest + true + + + PreserveNewest + true + + + diff --git a/Importers/Ifc/Speckle.Importers.Ifc/SpeckleIfcException.cs b/Importers/Ifc/Speckle.Importers.Ifc/SpeckleIfcException.cs new file mode 100644 index 000000000..4ab39d11c --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/SpeckleIfcException.cs @@ -0,0 +1,14 @@ +using Speckle.Sdk; + +namespace Speckle.Importers.Ifc; + +public class SpeckleIfcException : SpeckleException +{ + public SpeckleIfcException() { } + + public SpeckleIfcException(string? message) + : base(message) { } + + public SpeckleIfcException(string? message, Exception? inner = null) + : base(message, inner) { } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcColor.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcColor.cs new file mode 100644 index 000000000..508a57d48 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcColor.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Speckle.Importers.Ifc.Types; + +[StructLayout(LayoutKind.Sequential, Pack = 1)] +public struct IfcColor +{ + public double R, + G, + B, + A; +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcFactory.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcFactory.cs new file mode 100644 index 000000000..567453924 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcFactory.cs @@ -0,0 +1,21 @@ +using Speckle.InterfaceGenerator; + +namespace Speckle.Importers.Ifc.Types; + +[GenerateAutoInterface] +public class IfcFactory : IIfcFactory +{ + //probably never disposing this + private static readonly IntPtr _ptr = Importers.Ifc.Native.WebIfc.InitializeApi(); + + public IfcModel Open(string fullPath) + { + if (!File.Exists(fullPath)) + { + throw new ArgumentException($"File does not exist: {fullPath}"); + } + return new(Importers.Ifc.Native.WebIfc.LoadModel(_ptr, fullPath)); + } + + public string Version => Importers.Ifc.Native.WebIfc.GetVersion(); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcGeometry.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcGeometry.cs new file mode 100644 index 000000000..099d94618 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcGeometry.cs @@ -0,0 +1,18 @@ +namespace Speckle.Importers.Ifc.Types; + +public class IfcGeometry(IntPtr geometry) +{ + public IfcMesh GetMesh(int i) => new(Importers.Ifc.Native.WebIfc.GetMesh(geometry, i)); + + public int MeshCount => Importers.Ifc.Native.WebIfc.GetNumMeshes(geometry); + + public IfcSchemaType Type => (IfcSchemaType)Importers.Ifc.Native.WebIfc.GetGeometryType(geometry); + + public IEnumerable GetMeshes() + { + for (int i = 0; i < MeshCount; ++i) + { + yield return GetMesh(i); + } + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcLine.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcLine.cs new file mode 100644 index 000000000..a3c2306f1 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcLine.cs @@ -0,0 +1,9 @@ +namespace Speckle.Importers.Ifc.Types; + +public class IfcLine(IntPtr line) +{ + public uint Id => Importers.Ifc.Native.WebIfc.GetLineId(line); + public IfcSchemaType Type => (IfcSchemaType)Importers.Ifc.Native.WebIfc.GetLineType(line); + + public string Arguments() => Importers.Ifc.Native.WebIfc.GetLineArguments(line); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcMesh.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcMesh.cs new file mode 100644 index 000000000..e0b34e73c --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcMesh.cs @@ -0,0 +1,15 @@ +namespace Speckle.Importers.Ifc.Types; + +public class IfcMesh(IntPtr mesh) +{ + public int VertexCount => Importers.Ifc.Native.WebIfc.GetNumVertices(mesh); + + public unsafe IfcVertex* GetVertices() => (IfcVertex*)Importers.Ifc.Native.WebIfc.GetVertices(mesh); + + public IntPtr Transform => Importers.Ifc.Native.WebIfc.GetTransform(mesh); + public int IndexCount => Importers.Ifc.Native.WebIfc.GetNumIndices(mesh); + + public unsafe int* GetIndexes() => (int*)Importers.Ifc.Native.WebIfc.GetIndices(mesh); + + public unsafe IfcColor* GetColor() => (IfcColor*)Importers.Ifc.Native.WebIfc.GetColor(mesh); +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcModel.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcModel.cs new file mode 100644 index 000000000..6da106e9b --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcModel.cs @@ -0,0 +1,33 @@ +namespace Speckle.Importers.Ifc.Types; + +public class IfcModel(IntPtr model) +{ + public int GetNumGeometries() => Importers.Ifc.Native.WebIfc.GetNumGeometries(model); + + public IfcGeometry? GetGeometry(uint id) + { + var geometry = Importers.Ifc.Native.WebIfc.GetGeometryFromId(model, id); + return geometry == IntPtr.Zero ? null : new IfcGeometry(geometry); + } + + public IEnumerable GetGeometries() + { + var numGeometries = Importers.Ifc.Native.WebIfc.GetNumGeometries(model); + for (int i = 0; i < numGeometries; ++i) + { + var gPtr = Importers.Ifc.Native.WebIfc.GetGeometryFromIndex(model, i); + if (gPtr != IntPtr.Zero) + { + yield return new IfcGeometry(gPtr); + } + } + } + + public uint GetMaxId() => Importers.Ifc.Native.WebIfc.GetMaxId(model); + + public IfcLine? GetLine(uint id) + { + var line = Importers.Ifc.Native.WebIfc.GetLineFromModel(model, id); + return line == IntPtr.Zero ? null : new IfcLine(line); + } +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcSchemaType.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcSchemaType.cs new file mode 100644 index 000000000..6c25971d8 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcSchemaType.cs @@ -0,0 +1,1149 @@ +namespace Speckle.Importers.Ifc.Types; + +#pragma warning disable CA1028 +#pragma warning disable CA1008 +public enum IfcSchemaType : uint +{ +#pragma warning restore CA1008 +#pragma warning restore CA1028 + FILE_SCHEMA = 1109904537, + FILE_NAME = 1390159747, + FILE_DESCRIPTION = 599546466, + IFCACTORROLE = 3630933823, + IFCADDRESS = 618182010, + IFCAPPLICATION = 639542469, + IFCAPPLIEDVALUE = 411424972, + IFCAPPLIEDVALUERELATIONSHIP = 1110488051, + IFCAPPROVAL = 130549933, + IFCAPPROVALACTORRELATIONSHIP = 2080292479, + IFCAPPROVALPROPERTYRELATIONSHIP = 390851274, + IFCAPPROVALRELATIONSHIP = 3869604511, + IFCBOUNDARYCONDITION = 4037036970, + IFCBOUNDARYEDGECONDITION = 1560379544, + IFCBOUNDARYFACECONDITION = 3367102660, + IFCBOUNDARYNODECONDITION = 1387855156, + IFCBOUNDARYNODECONDITIONWARPING = 2069777674, + IFCCALENDARDATE = 622194075, + IFCCLASSIFICATION = 747523909, + IFCCLASSIFICATIONITEM = 1767535486, + IFCCLASSIFICATIONITEMRELATIONSHIP = 1098599126, + IFCCLASSIFICATIONNOTATION = 938368621, + IFCCLASSIFICATIONNOTATIONFACET = 3639012971, + IFCCOLOURSPECIFICATION = 3264961684, + IFCCONNECTIONGEOMETRY = 2859738748, + IFCCONNECTIONPOINTGEOMETRY = 2614616156, + IFCCONNECTIONPORTGEOMETRY = 4257277454, + IFCCONNECTIONSURFACEGEOMETRY = 2732653382, + IFCCONSTRAINT = 1959218052, + IFCCONSTRAINTAGGREGATIONRELATIONSHIP = 1658513725, + IFCCONSTRAINTCLASSIFICATIONRELATIONSHIP = 613356794, + IFCCONSTRAINTRELATIONSHIP = 347226245, + IFCCOORDINATEDUNIVERSALTIMEOFFSET = 1065062679, + IFCCOSTVALUE = 602808272, + IFCCURRENCYRELATIONSHIP = 539742890, + IFCCURVESTYLEFONT = 1105321065, + IFCCURVESTYLEFONTANDSCALING = 2367409068, + IFCCURVESTYLEFONTPATTERN = 3510044353, + IFCDATEANDTIME = 1072939445, + IFCDERIVEDUNIT = 1765591967, + IFCDERIVEDUNITELEMENT = 1045800335, + IFCDIMENSIONALEXPONENTS = 2949456006, + IFCDOCUMENTELECTRONICFORMAT = 1376555844, + IFCDOCUMENTINFORMATION = 1154170062, + IFCDOCUMENTINFORMATIONRELATIONSHIP = 770865208, + IFCDRAUGHTINGCALLOUTRELATIONSHIP = 3796139169, + IFCENVIRONMENTALIMPACTVALUE = 1648886627, + IFCEXTERNALREFERENCE = 3200245327, + IFCEXTERNALLYDEFINEDHATCHSTYLE = 2242383968, + IFCEXTERNALLYDEFINEDSURFACESTYLE = 1040185647, + IFCEXTERNALLYDEFINEDSYMBOL = 3207319532, + IFCEXTERNALLYDEFINEDTEXTFONT = 3548104201, + IFCGRIDAXIS = 852622518, + IFCIRREGULARTIMESERIESVALUE = 3020489413, + IFCLIBRARYINFORMATION = 2655187982, + IFCLIBRARYREFERENCE = 3452421091, + IFCLIGHTDISTRIBUTIONDATA = 4162380809, + IFCLIGHTINTENSITYDISTRIBUTION = 1566485204, + IFCLOCALTIME = 30780891, + IFCMATERIAL = 1838606355, + IFCMATERIALCLASSIFICATIONRELATIONSHIP = 1847130766, + IFCMATERIALLAYER = 248100487, + IFCMATERIALLAYERSET = 3303938423, + IFCMATERIALLAYERSETUSAGE = 1303795690, + IFCMATERIALLIST = 2199411900, + IFCMATERIALPROPERTIES = 3265635763, + IFCMEASUREWITHUNIT = 2597039031, + IFCMECHANICALMATERIALPROPERTIES = 4256014907, + IFCMECHANICALSTEELMATERIALPROPERTIES = 677618848, + IFCMETRIC = 3368373690, + IFCMONETARYUNIT = 2706619895, + IFCNAMEDUNIT = 1918398963, + IFCOBJECTPLACEMENT = 3701648758, + IFCOBJECTIVE = 2251480897, + IFCOPTICALMATERIALPROPERTIES = 1227763645, + IFCORGANIZATION = 4251960020, + IFCORGANIZATIONRELATIONSHIP = 1411181986, + IFCOWNERHISTORY = 1207048766, + IFCPERSON = 2077209135, + IFCPERSONANDORGANIZATION = 101040310, + IFCPHYSICALQUANTITY = 2483315170, + IFCPHYSICALSIMPLEQUANTITY = 2226359599, + IFCPOSTALADDRESS = 3355820592, + IFCPREDEFINEDITEM = 3727388367, + IFCPREDEFINEDSYMBOL = 990879717, + IFCPREDEFINEDTERMINATORSYMBOL = 3213052703, + IFCPREDEFINEDTEXTFONT = 1775413392, + IFCPRESENTATIONLAYERASSIGNMENT = 2022622350, + IFCPRESENTATIONLAYERWITHSTYLE = 1304840413, + IFCPRESENTATIONSTYLE = 3119450353, + IFCPRESENTATIONSTYLEASSIGNMENT = 2417041796, + IFCPRODUCTREPRESENTATION = 2095639259, + IFCPRODUCTSOFCOMBUSTIONPROPERTIES = 2267347899, + IFCPROFILEDEF = 3958567839, + IFCPROFILEPROPERTIES = 2802850158, + IFCPROPERTY = 2598011224, + IFCPROPERTYCONSTRAINTRELATIONSHIP = 3896028662, + IFCPROPERTYDEPENDENCYRELATIONSHIP = 148025276, + IFCPROPERTYENUMERATION = 3710013099, + IFCQUANTITYAREA = 2044713172, + IFCQUANTITYCOUNT = 2093928680, + IFCQUANTITYLENGTH = 931644368, + IFCQUANTITYTIME = 3252649465, + IFCQUANTITYVOLUME = 2405470396, + IFCQUANTITYWEIGHT = 825690147, + IFCREFERENCESVALUEDOCUMENT = 2692823254, + IFCREINFORCEMENTBARPROPERTIES = 1580146022, + IFCRELAXATION = 1222501353, + IFCREPRESENTATION = 1076942058, + IFCREPRESENTATIONCONTEXT = 3377609919, + IFCREPRESENTATIONITEM = 3008791417, + IFCREPRESENTATIONMAP = 1660063152, + IFCRIBPLATEPROFILEPROPERTIES = 3679540991, + IFCROOT = 2341007311, + IFCSIUNIT = 448429030, + IFCSECTIONPROPERTIES = 2042790032, + IFCSECTIONREINFORCEMENTPROPERTIES = 4165799628, + IFCSHAPEASPECT = 867548509, + IFCSHAPEMODEL = 3982875396, + IFCSHAPEREPRESENTATION = 4240577450, + IFCSIMPLEPROPERTY = 3692461612, + IFCSTRUCTURALCONNECTIONCONDITION = 2273995522, + IFCSTRUCTURALLOAD = 2162789131, + IFCSTRUCTURALLOADSTATIC = 2525727697, + IFCSTRUCTURALLOADTEMPERATURE = 3408363356, + IFCSTYLEMODEL = 2830218821, + IFCSTYLEDITEM = 3958052878, + IFCSTYLEDREPRESENTATION = 3049322572, + IFCSURFACESTYLE = 1300840506, + IFCSURFACESTYLELIGHTING = 3303107099, + IFCSURFACESTYLEREFRACTION = 1607154358, + IFCSURFACESTYLESHADING = 846575682, + IFCSURFACESTYLEWITHTEXTURES = 1351298697, + IFCSURFACETEXTURE = 626085974, + IFCSYMBOLSTYLE = 1290481447, + IFCTABLE = 985171141, + IFCTABLEROW = 531007025, + IFCTELECOMADDRESS = 912023232, + IFCTEXTSTYLE = 1447204868, + IFCTEXTSTYLEFONTMODEL = 1983826977, + IFCTEXTSTYLEFORDEFINEDFONT = 2636378356, + IFCTEXTSTYLETEXTMODEL = 1640371178, + IFCTEXTSTYLEWITHBOXCHARACTERISTICS = 1484833681, + IFCTEXTURECOORDINATE = 280115917, + IFCTEXTURECOORDINATEGENERATOR = 1742049831, + IFCTEXTUREMAP = 2552916305, + IFCTEXTUREVERTEX = 1210645708, + IFCTHERMALMATERIALPROPERTIES = 3317419933, + IFCTIMESERIES = 3101149627, + IFCTIMESERIESREFERENCERELATIONSHIP = 1718945513, + IFCTIMESERIESVALUE = 581633288, + IFCTOPOLOGICALREPRESENTATIONITEM = 1377556343, + IFCTOPOLOGYREPRESENTATION = 1735638870, + IFCUNITASSIGNMENT = 180925521, + IFCVERTEX = 2799835756, + IFCVERTEXBASEDTEXTUREMAP = 3304826586, + IFCVERTEXPOINT = 1907098498, + IFCVIRTUALGRIDINTERSECTION = 891718957, + IFCWATERPROPERTIES = 1065908215, + IFCANNOTATIONOCCURRENCE = 2442683028, + IFCANNOTATIONSURFACEOCCURRENCE = 962685235, + IFCANNOTATIONSYMBOLOCCURRENCE = 3612888222, + IFCANNOTATIONTEXTOCCURRENCE = 2297822566, + IFCARBITRARYCLOSEDPROFILEDEF = 3798115385, + IFCARBITRARYOPENPROFILEDEF = 1310608509, + IFCARBITRARYPROFILEDEFWITHVOIDS = 2705031697, + IFCBLOBTEXTURE = 616511568, + IFCCENTERLINEPROFILEDEF = 3150382593, + IFCCLASSIFICATIONREFERENCE = 647927063, + IFCCOLOURRGB = 776857604, + IFCCOMPLEXPROPERTY = 2542286263, + IFCCOMPOSITEPROFILEDEF = 1485152156, + IFCCONNECTEDFACESET = 370225590, + IFCCONNECTIONCURVEGEOMETRY = 1981873012, + IFCCONNECTIONPOINTECCENTRICITY = 45288368, + IFCCONTEXTDEPENDENTUNIT = 3050246964, + IFCCONVERSIONBASEDUNIT = 2889183280, + IFCCURVESTYLE = 3800577675, + IFCDERIVEDPROFILEDEF = 3632507154, + IFCDIMENSIONCALLOUTRELATIONSHIP = 2273265877, + IFCDIMENSIONPAIR = 1694125774, + IFCDOCUMENTREFERENCE = 3732053477, + IFCDRAUGHTINGPREDEFINEDTEXTFONT = 4170525392, + IFCEDGE = 3900360178, + IFCEDGECURVE = 476780140, + IFCEXTENDEDMATERIALPROPERTIES = 1860660968, + IFCFACE = 2556980723, + IFCFACEBOUND = 1809719519, + IFCFACEOUTERBOUND = 803316827, + IFCFACESURFACE = 3008276851, + IFCFAILURECONNECTIONCONDITION = 4219587988, + IFCFILLAREASTYLE = 738692330, + IFCFUELPROPERTIES = 3857492461, + IFCGENERALMATERIALPROPERTIES = 803998398, + IFCGENERALPROFILEPROPERTIES = 1446786286, + IFCGEOMETRICREPRESENTATIONCONTEXT = 3448662350, + IFCGEOMETRICREPRESENTATIONITEM = 2453401579, + IFCGEOMETRICREPRESENTATIONSUBCONTEXT = 4142052618, + IFCGEOMETRICSET = 3590301190, + IFCGRIDPLACEMENT = 178086475, + IFCHALFSPACESOLID = 812098782, + IFCHYGROSCOPICMATERIALPROPERTIES = 2445078500, + IFCIMAGETEXTURE = 3905492369, + IFCIRREGULARTIMESERIES = 3741457305, + IFCLIGHTSOURCE = 1402838566, + IFCLIGHTSOURCEAMBIENT = 125510826, + IFCLIGHTSOURCEDIRECTIONAL = 2604431987, + IFCLIGHTSOURCEGONIOMETRIC = 4266656042, + IFCLIGHTSOURCEPOSITIONAL = 1520743889, + IFCLIGHTSOURCESPOT = 3422422726, + IFCLOCALPLACEMENT = 2624227202, + IFCLOOP = 1008929658, + IFCMAPPEDITEM = 2347385850, + IFCMATERIALDEFINITIONREPRESENTATION = 2022407955, + IFCMECHANICALCONCRETEMATERIALPROPERTIES = 1430189142, + IFCOBJECTDEFINITION = 219451334, + IFCONEDIRECTIONREPEATFACTOR = 2833995503, + IFCOPENSHELL = 2665983363, + IFCORIENTEDEDGE = 1029017970, + IFCPARAMETERIZEDPROFILEDEF = 2529465313, + IFCPATH = 2519244187, + IFCPHYSICALCOMPLEXQUANTITY = 3021840470, + IFCPIXELTEXTURE = 597895409, + IFCPLACEMENT = 2004835150, + IFCPLANAREXTENT = 1663979128, + IFCPOINT = 2067069095, + IFCPOINTONCURVE = 4022376103, + IFCPOINTONSURFACE = 1423911732, + IFCPOLYLOOP = 2924175390, + IFCPOLYGONALBOUNDEDHALFSPACE = 2775532180, + IFCPREDEFINEDCOLOUR = 759155922, + IFCPREDEFINEDCURVEFONT = 2559016684, + IFCPREDEFINEDDIMENSIONSYMBOL = 433424934, + IFCPREDEFINEDPOINTMARKERSYMBOL = 179317114, + IFCPRODUCTDEFINITIONSHAPE = 673634403, + IFCPROPERTYBOUNDEDVALUE = 871118103, + IFCPROPERTYDEFINITION = 1680319473, + IFCPROPERTYENUMERATEDVALUE = 4166981789, + IFCPROPERTYLISTVALUE = 2752243245, + IFCPROPERTYREFERENCEVALUE = 941946838, + IFCPROPERTYSETDEFINITION = 3357820518, + IFCPROPERTYSINGLEVALUE = 3650150729, + IFCPROPERTYTABLEVALUE = 110355661, + IFCRECTANGLEPROFILEDEF = 3615266464, + IFCREGULARTIMESERIES = 3413951693, + IFCREINFORCEMENTDEFINITIONPROPERTIES = 3765753017, + IFCRELATIONSHIP = 478536968, + IFCROUNDEDRECTANGLEPROFILEDEF = 2778083089, + IFCSECTIONEDSPINE = 1509187699, + IFCSERVICELIFEFACTOR = 2411513650, + IFCSHELLBASEDSURFACEMODEL = 4124623270, + IFCSLIPPAGECONNECTIONCONDITION = 2609359061, + IFCSOLIDMODEL = 723233188, + IFCSOUNDPROPERTIES = 2485662743, + IFCSOUNDVALUE = 1202362311, + IFCSPACETHERMALLOADPROPERTIES = 390701378, + IFCSTRUCTURALLOADLINEARFORCE = 1595516126, + IFCSTRUCTURALLOADPLANARFORCE = 2668620305, + IFCSTRUCTURALLOADSINGLEDISPLACEMENT = 2473145415, + IFCSTRUCTURALLOADSINGLEDISPLACEMENTDISTORTION = 1973038258, + IFCSTRUCTURALLOADSINGLEFORCE = 1597423693, + IFCSTRUCTURALLOADSINGLEFORCEWARPING = 1190533807, + IFCSTRUCTURALPROFILEPROPERTIES = 3843319758, + IFCSTRUCTURALSTEELPROFILEPROPERTIES = 3653947884, + IFCSUBEDGE = 2233826070, + IFCSURFACE = 2513912981, + IFCSURFACESTYLERENDERING = 1878645084, + IFCSWEPTAREASOLID = 2247615214, + IFCSWEPTDISKSOLID = 1260650574, + IFCSWEPTSURFACE = 230924584, + IFCTSHAPEPROFILEDEF = 3071757647, + IFCTERMINATORSYMBOL = 3028897424, + IFCTEXTLITERAL = 4282788508, + IFCTEXTLITERALWITHEXTENT = 3124975700, + IFCTRAPEZIUMPROFILEDEF = 2715220739, + IFCTWODIRECTIONREPEATFACTOR = 1345879162, + IFCTYPEOBJECT = 1628702193, + IFCTYPEPRODUCT = 2347495698, + IFCUSHAPEPROFILEDEF = 427810014, + IFCVECTOR = 1417489154, + IFCVERTEXLOOP = 2759199220, + IFCWINDOWLININGPROPERTIES = 336235671, + IFCWINDOWPANELPROPERTIES = 512836454, + IFCWINDOWSTYLE = 1299126871, + IFCZSHAPEPROFILEDEF = 2543172580, + IFCANNOTATIONCURVEOCCURRENCE = 3288037868, + IFCANNOTATIONFILLAREA = 669184980, + IFCANNOTATIONFILLAREAOCCURRENCE = 2265737646, + IFCANNOTATIONSURFACE = 1302238472, + IFCAXIS1PLACEMENT = 4261334040, + IFCAXIS2PLACEMENT2D = 3125803723, + IFCAXIS2PLACEMENT3D = 2740243338, + IFCBOOLEANRESULT = 2736907675, + IFCBOUNDEDSURFACE = 4182860854, + IFCBOUNDINGBOX = 2581212453, + IFCBOXEDHALFSPACE = 2713105998, + IFCCSHAPEPROFILEDEF = 2898889636, + IFCCARTESIANPOINT = 1123145078, + IFCCARTESIANTRANSFORMATIONOPERATOR = 59481748, + IFCCARTESIANTRANSFORMATIONOPERATOR2D = 3749851601, + IFCCARTESIANTRANSFORMATIONOPERATOR2DNONUNIFORM = 3486308946, + IFCCARTESIANTRANSFORMATIONOPERATOR3D = 3331915920, + IFCCARTESIANTRANSFORMATIONOPERATOR3DNONUNIFORM = 1416205885, + IFCCIRCLEPROFILEDEF = 1383045692, + IFCCLOSEDSHELL = 2205249479, + IFCCOMPOSITECURVESEGMENT = 2485617015, + IFCCRANERAILASHAPEPROFILEDEF = 4133800736, + IFCCRANERAILFSHAPEPROFILEDEF = 194851669, + IFCCSGPRIMITIVE3D = 2506170314, + IFCCSGSOLID = 2147822146, + IFCCURVE = 2601014836, + IFCCURVEBOUNDEDPLANE = 2827736869, + IFCDEFINEDSYMBOL = 693772133, + IFCDIMENSIONCURVE = 606661476, + IFCDIMENSIONCURVETERMINATOR = 4054601972, + IFCDIRECTION = 32440307, + IFCDOORLININGPROPERTIES = 2963535650, + IFCDOORPANELPROPERTIES = 1714330368, + IFCDOORSTYLE = 526551008, + IFCDRAUGHTINGCALLOUT = 3073041342, + IFCDRAUGHTINGPREDEFINEDCOLOUR = 445594917, + IFCDRAUGHTINGPREDEFINEDCURVEFONT = 4006246654, + IFCEDGELOOP = 1472233963, + IFCELEMENTQUANTITY = 1883228015, + IFCELEMENTTYPE = 339256511, + IFCELEMENTARYSURFACE = 2777663545, + IFCELLIPSEPROFILEDEF = 2835456948, + IFCENERGYPROPERTIES = 80994333, + IFCEXTRUDEDAREASOLID = 477187591, + IFCFACEBASEDSURFACEMODEL = 2047409740, + IFCFILLAREASTYLEHATCHING = 374418227, + IFCFILLAREASTYLETILESYMBOLWITHSTYLE = 4203026998, + IFCFILLAREASTYLETILES = 315944413, + IFCFLUIDFLOWPROPERTIES = 3455213021, + IFCFURNISHINGELEMENTTYPE = 4238390223, + IFCFURNITURETYPE = 1268542332, + IFCGEOMETRICCURVESET = 987898635, + IFCISHAPEPROFILEDEF = 1484403080, + IFCLSHAPEPROFILEDEF = 572779678, + IFCLINE = 1281925730, + IFCMANIFOLDSOLIDBREP = 1425443689, + IFCOBJECT = 3888040117, + IFCOFFSETCURVE2D = 3388369263, + IFCOFFSETCURVE3D = 3505215534, + IFCPERMEABLECOVERINGPROPERTIES = 3566463478, + IFCPLANARBOX = 603570806, + IFCPLANE = 220341763, + IFCPROCESS = 2945172077, + IFCPRODUCT = 4208778838, + IFCPROJECT = 103090709, + IFCPROJECTIONCURVE = 4194566429, + IFCPROPERTYSET = 1451395588, + IFCPROXY = 3219374653, + IFCRECTANGLEHOLLOWPROFILEDEF = 2770003689, + IFCRECTANGULARPYRAMID = 2798486643, + IFCRECTANGULARTRIMMEDSURFACE = 3454111270, + IFCRELASSIGNS = 3939117080, + IFCRELASSIGNSTOACTOR = 1683148259, + IFCRELASSIGNSTOCONTROL = 2495723537, + IFCRELASSIGNSTOGROUP = 1307041759, + IFCRELASSIGNSTOPROCESS = 4278684876, + IFCRELASSIGNSTOPRODUCT = 2857406711, + IFCRELASSIGNSTOPROJECTORDER = 3372526763, + IFCRELASSIGNSTORESOURCE = 205026976, + IFCRELASSOCIATES = 1865459582, + IFCRELASSOCIATESAPPLIEDVALUE = 1327628568, + IFCRELASSOCIATESAPPROVAL = 4095574036, + IFCRELASSOCIATESCLASSIFICATION = 919958153, + IFCRELASSOCIATESCONSTRAINT = 2728634034, + IFCRELASSOCIATESDOCUMENT = 982818633, + IFCRELASSOCIATESLIBRARY = 3840914261, + IFCRELASSOCIATESMATERIAL = 2655215786, + IFCRELASSOCIATESPROFILEPROPERTIES = 2851387026, + IFCRELCONNECTS = 826625072, + IFCRELCONNECTSELEMENTS = 1204542856, + IFCRELCONNECTSPATHELEMENTS = 3945020480, + IFCRELCONNECTSPORTTOELEMENT = 4201705270, + IFCRELCONNECTSPORTS = 3190031847, + IFCRELCONNECTSSTRUCTURALACTIVITY = 2127690289, + IFCRELCONNECTSSTRUCTURALELEMENT = 3912681535, + IFCRELCONNECTSSTRUCTURALMEMBER = 1638771189, + IFCRELCONNECTSWITHECCENTRICITY = 504942748, + IFCRELCONNECTSWITHREALIZINGELEMENTS = 3678494232, + IFCRELCONTAINEDINSPATIALSTRUCTURE = 3242617779, + IFCRELCOVERSBLDGELEMENTS = 886880790, + IFCRELCOVERSSPACES = 2802773753, + IFCRELDECOMPOSES = 2551354335, + IFCRELDEFINES = 693640335, + IFCRELDEFINESBYPROPERTIES = 4186316022, + IFCRELDEFINESBYTYPE = 781010003, + IFCRELFILLSELEMENT = 3940055652, + IFCRELFLOWCONTROLELEMENTS = 279856033, + IFCRELINTERACTIONREQUIREMENTS = 4189434867, + IFCRELNESTS = 3268803585, + IFCRELOCCUPIESSPACES = 2051452291, + IFCRELOVERRIDESPROPERTIES = 202636808, + IFCRELPROJECTSELEMENT = 750771296, + IFCRELREFERENCEDINSPATIALSTRUCTURE = 1245217292, + IFCRELSCHEDULESCOSTITEMS = 1058617721, + IFCRELSEQUENCE = 4122056220, + IFCRELSERVICESBUILDINGS = 366585022, + IFCRELSPACEBOUNDARY = 3451746338, + IFCRELVOIDSELEMENT = 1401173127, + IFCRESOURCE = 2914609552, + IFCREVOLVEDAREASOLID = 1856042241, + IFCRIGHTCIRCULARCONE = 4158566097, + IFCRIGHTCIRCULARCYLINDER = 3626867408, + IFCSPATIALSTRUCTUREELEMENT = 2706606064, + IFCSPATIALSTRUCTUREELEMENTTYPE = 3893378262, + IFCSPHERE = 451544542, + IFCSTRUCTURALACTIVITY = 3544373492, + IFCSTRUCTURALITEM = 3136571912, + IFCSTRUCTURALMEMBER = 530289379, + IFCSTRUCTURALREACTION = 3689010777, + IFCSTRUCTURALSURFACEMEMBER = 3979015343, + IFCSTRUCTURALSURFACEMEMBERVARYING = 2218152070, + IFCSTRUCTUREDDIMENSIONCALLOUT = 4070609034, + IFCSURFACECURVESWEPTAREASOLID = 2028607225, + IFCSURFACEOFLINEAREXTRUSION = 2809605785, + IFCSURFACEOFREVOLUTION = 4124788165, + IFCSYSTEMFURNITUREELEMENTTYPE = 1580310250, + IFCTASK = 3473067441, + IFCTRANSPORTELEMENTTYPE = 2097647324, + IFCACTOR = 2296667514, + IFCANNOTATION = 1674181508, + IFCASYMMETRICISHAPEPROFILEDEF = 3207858831, + IFCBLOCK = 1334484129, + IFCBOOLEANCLIPPINGRESULT = 3649129432, + IFCBOUNDEDCURVE = 1260505505, + IFCBUILDING = 4031249490, + IFCBUILDINGELEMENTTYPE = 1950629157, + IFCBUILDINGSTOREY = 3124254112, + IFCCIRCLEHOLLOWPROFILEDEF = 2937912522, + IFCCOLUMNTYPE = 300633059, + IFCCOMPOSITECURVE = 3732776249, + IFCCONIC = 2510884976, + IFCCONSTRUCTIONRESOURCE = 2559216714, + IFCCONTROL = 3293443760, + IFCCOSTITEM = 3895139033, + IFCCOSTSCHEDULE = 1419761937, + IFCCOVERINGTYPE = 1916426348, + IFCCREWRESOURCE = 3295246426, + IFCCURTAINWALLTYPE = 1457835157, + IFCDIMENSIONCURVEDIRECTEDCALLOUT = 681481545, + IFCDISTRIBUTIONELEMENTTYPE = 3256556792, + IFCDISTRIBUTIONFLOWELEMENTTYPE = 3849074793, + IFCELECTRICALBASEPROPERTIES = 360485395, + IFCELEMENT = 1758889154, + IFCELEMENTASSEMBLY = 4123344466, + IFCELEMENTCOMPONENT = 1623761950, + IFCELEMENTCOMPONENTTYPE = 2590856083, + IFCELLIPSE = 1704287377, + IFCENERGYCONVERSIONDEVICETYPE = 2107101300, + IFCEQUIPMENTELEMENT = 1962604670, + IFCEQUIPMENTSTANDARD = 3272907226, + IFCEVAPORATIVECOOLERTYPE = 3174744832, + IFCEVAPORATORTYPE = 3390157468, + IFCFACETEDBREP = 807026263, + IFCFACETEDBREPWITHVOIDS = 3737207727, + IFCFASTENER = 647756555, + IFCFASTENERTYPE = 2489546625, + IFCFEATUREELEMENT = 2827207264, + IFCFEATUREELEMENTADDITION = 2143335405, + IFCFEATUREELEMENTSUBTRACTION = 1287392070, + IFCFLOWCONTROLLERTYPE = 3907093117, + IFCFLOWFITTINGTYPE = 3198132628, + IFCFLOWMETERTYPE = 3815607619, + IFCFLOWMOVINGDEVICETYPE = 1482959167, + IFCFLOWSEGMENTTYPE = 1834744321, + IFCFLOWSTORAGEDEVICETYPE = 1339347760, + IFCFLOWTERMINALTYPE = 2297155007, + IFCFLOWTREATMENTDEVICETYPE = 3009222698, + IFCFURNISHINGELEMENT = 263784265, + IFCFURNITURESTANDARD = 814719939, + IFCGASTERMINALTYPE = 200128114, + IFCGRID = 3009204131, + IFCGROUP = 2706460486, + IFCHEATEXCHANGERTYPE = 1251058090, + IFCHUMIDIFIERTYPE = 1806887404, + IFCINVENTORY = 2391368822, + IFCJUNCTIONBOXTYPE = 4288270099, + IFCLABORRESOURCE = 3827777499, + IFCLAMPTYPE = 1051575348, + IFCLIGHTFIXTURETYPE = 1161773419, + IFCLINEARDIMENSION = 2506943328, + IFCMECHANICALFASTENER = 377706215, + IFCMECHANICALFASTENERTYPE = 2108223431, + IFCMEMBERTYPE = 3181161470, + IFCMOTORCONNECTIONTYPE = 977012517, + IFCMOVE = 1916936684, + IFCOCCUPANT = 4143007308, + IFCOPENINGELEMENT = 3588315303, + IFCORDERACTION = 3425660407, + IFCOUTLETTYPE = 2837617999, + IFCPERFORMANCEHISTORY = 2382730787, + IFCPERMIT = 3327091369, + IFCPIPEFITTINGTYPE = 804291784, + IFCPIPESEGMENTTYPE = 4231323485, + IFCPLATETYPE = 4017108033, + IFCPOLYLINE = 3724593414, + IFCPORT = 3740093272, + IFCPROCEDURE = 2744685151, + IFCPROJECTORDER = 2904328755, + IFCPROJECTORDERRECORD = 3642467123, + IFCPROJECTIONELEMENT = 3651124850, + IFCPROTECTIVEDEVICETYPE = 1842657554, + IFCPUMPTYPE = 2250791053, + IFCRADIUSDIMENSION = 3248260540, + IFCRAILINGTYPE = 2893384427, + IFCRAMPFLIGHTTYPE = 2324767716, + IFCRELAGGREGATES = 160246688, + IFCRELASSIGNSTASKS = 2863920197, + IFCSANITARYTERMINALTYPE = 1768891740, + IFCSCHEDULETIMECONTROL = 3517283431, + IFCSERVICELIFE = 4105383287, + IFCSITE = 4097777520, + IFCSLABTYPE = 2533589738, + IFCSPACE = 3856911033, + IFCSPACEHEATERTYPE = 1305183839, + IFCSPACEPROGRAM = 652456506, + IFCSPACETYPE = 3812236995, + IFCSTACKTERMINALTYPE = 3112655638, + IFCSTAIRFLIGHTTYPE = 1039846685, + IFCSTRUCTURALACTION = 682877961, + IFCSTRUCTURALCONNECTION = 1179482911, + IFCSTRUCTURALCURVECONNECTION = 4243806635, + IFCSTRUCTURALCURVEMEMBER = 214636428, + IFCSTRUCTURALCURVEMEMBERVARYING = 2445595289, + IFCSTRUCTURALLINEARACTION = 1807405624, + IFCSTRUCTURALLINEARACTIONVARYING = 1721250024, + IFCSTRUCTURALLOADGROUP = 1252848954, + IFCSTRUCTURALPLANARACTION = 1621171031, + IFCSTRUCTURALPLANARACTIONVARYING = 3987759626, + IFCSTRUCTURALPOINTACTION = 2082059205, + IFCSTRUCTURALPOINTCONNECTION = 734778138, + IFCSTRUCTURALPOINTREACTION = 1235345126, + IFCSTRUCTURALRESULTGROUP = 2986769608, + IFCSTRUCTURALSURFACECONNECTION = 1975003073, + IFCSUBCONTRACTRESOURCE = 148013059, + IFCSWITCHINGDEVICETYPE = 2315554128, + IFCSYSTEM = 2254336722, + IFCTANKTYPE = 5716631, + IFCTIMESERIESSCHEDULE = 1637806684, + IFCTRANSFORMERTYPE = 1692211062, + IFCTRANSPORTELEMENT = 1620046519, + IFCTRIMMEDCURVE = 3593883385, + IFCTUBEBUNDLETYPE = 1600972822, + IFCUNITARYEQUIPMENTTYPE = 1911125066, + IFCVALVETYPE = 728799441, + IFCVIRTUALELEMENT = 2769231204, + IFCWALLTYPE = 1898987631, + IFCWASTETERMINALTYPE = 1133259667, + IFCWORKCONTROL = 1028945134, + IFCWORKPLAN = 4218914973, + IFCWORKSCHEDULE = 3342526732, + IFCZONE = 1033361043, + IFC2DCOMPOSITECURVE = 1213861670, + IFCACTIONREQUEST = 3821786052, + IFCAIRTERMINALBOXTYPE = 1411407467, + IFCAIRTERMINALTYPE = 3352864051, + IFCAIRTOAIRHEATRECOVERYTYPE = 1871374353, + IFCANGULARDIMENSION = 2470393545, + IFCASSET = 3460190687, + IFCBSPLINECURVE = 1967976161, + IFCBEAMTYPE = 819618141, + IFCBEZIERCURVE = 1916977116, + IFCBOILERTYPE = 231477066, + IFCBUILDINGELEMENT = 3299480353, + IFCBUILDINGELEMENTCOMPONENT = 52481810, + IFCBUILDINGELEMENTPART = 2979338954, + IFCBUILDINGELEMENTPROXY = 1095909175, + IFCBUILDINGELEMENTPROXYTYPE = 1909888760, + IFCCABLECARRIERFITTINGTYPE = 395041908, + IFCCABLECARRIERSEGMENTTYPE = 3293546465, + IFCCABLESEGMENTTYPE = 1285652485, + IFCCHILLERTYPE = 2951183804, + IFCCIRCLE = 2611217952, + IFCCOILTYPE = 2301859152, + IFCCOLUMN = 843113511, + IFCCOMPRESSORTYPE = 3850581409, + IFCCONDENSERTYPE = 2816379211, + IFCCONDITION = 2188551683, + IFCCONDITIONCRITERION = 1163958913, + IFCCONSTRUCTIONEQUIPMENTRESOURCE = 3898045240, + IFCCONSTRUCTIONMATERIALRESOURCE = 1060000209, + IFCCONSTRUCTIONPRODUCTRESOURCE = 488727124, + IFCCOOLEDBEAMTYPE = 335055490, + IFCCOOLINGTOWERTYPE = 2954562838, + IFCCOVERING = 1973544240, + IFCCURTAINWALL = 3495092785, + IFCDAMPERTYPE = 3961806047, + IFCDIAMETERDIMENSION = 4147604152, + IFCDISCRETEACCESSORY = 1335981549, + IFCDISCRETEACCESSORYTYPE = 2635815018, + IFCDISTRIBUTIONCHAMBERELEMENTTYPE = 1599208980, + IFCDISTRIBUTIONCONTROLELEMENTTYPE = 2063403501, + IFCDISTRIBUTIONELEMENT = 1945004755, + IFCDISTRIBUTIONFLOWELEMENT = 3040386961, + IFCDISTRIBUTIONPORT = 3041715199, + IFCDOOR = 395920057, + IFCDUCTFITTINGTYPE = 869906466, + IFCDUCTSEGMENTTYPE = 3760055223, + IFCDUCTSILENCERTYPE = 2030761528, + IFCEDGEFEATURE = 855621170, + IFCELECTRICAPPLIANCETYPE = 663422040, + IFCELECTRICFLOWSTORAGEDEVICETYPE = 3277789161, + IFCELECTRICGENERATORTYPE = 1534661035, + IFCELECTRICHEATERTYPE = 1365060375, + IFCELECTRICMOTORTYPE = 1217240411, + IFCELECTRICTIMECONTROLTYPE = 712377611, + IFCELECTRICALCIRCUIT = 1634875225, + IFCELECTRICALELEMENT = 857184966, + IFCENERGYCONVERSIONDEVICE = 1658829314, + IFCFANTYPE = 346874300, + IFCFILTERTYPE = 1810631287, + IFCFIRESUPPRESSIONTERMINALTYPE = 4222183408, + IFCFLOWCONTROLLER = 2058353004, + IFCFLOWFITTING = 4278956645, + IFCFLOWINSTRUMENTTYPE = 4037862832, + IFCFLOWMOVINGDEVICE = 3132237377, + IFCFLOWSEGMENT = 987401354, + IFCFLOWSTORAGEDEVICE = 707683696, + IFCFLOWTERMINAL = 2223149337, + IFCFLOWTREATMENTDEVICE = 3508470533, + IFCFOOTING = 900683007, + IFCMEMBER = 1073191201, + IFCPILE = 1687234759, + IFCPLATE = 3171933400, + IFCRAILING = 2262370178, + IFCRAMP = 3024970846, + IFCRAMPFLIGHT = 3283111854, + IFCRATIONALBEZIERCURVE = 3055160366, + IFCREINFORCINGELEMENT = 3027567501, + IFCREINFORCINGMESH = 2320036040, + IFCROOF = 2016517767, + IFCROUNDEDEDGEFEATURE = 1376911519, + IFCSENSORTYPE = 1783015770, + IFCSLAB = 1529196076, + IFCSTAIR = 331165859, + IFCSTAIRFLIGHT = 4252922144, + IFCSTRUCTURALANALYSISMODEL = 2515109513, + IFCTENDON = 3824725483, + IFCTENDONANCHOR = 2347447852, + IFCVIBRATIONISOLATORTYPE = 3313531582, + IFCWALL = 2391406946, + IFCWALLSTANDARDCASE = 3512223829, + IFCWINDOW = 3304561284, + IFCACTUATORTYPE = 2874132201, + IFCALARMTYPE = 3001207471, + IFCBEAM = 753842376, + IFCCHAMFEREDGEFEATURE = 2454782716, + IFCCONTROLLERTYPE = 578613899, + IFCDISTRIBUTIONCHAMBERELEMENT = 1052013943, + IFCDISTRIBUTIONCONTROLELEMENT = 1062813311, + IFCELECTRICDISTRIBUTIONPOINT = 3700593921, + IFCREINFORCINGBAR = 979691226, + IFCCONNECTIONVOLUMEGEOMETRY = 775493141, + IFCCOORDINATEOPERATION = 1785450214, + IFCCOORDINATEREFERENCESYSTEM = 1466758467, + IFCEXTERNALINFORMATION = 4294318154, + IFCMAPCONVERSION = 3057273783, + IFCMATERIALDEFINITION = 760658860, + IFCMATERIALLAYERWITHOFFSETS = 1847252529, + IFCMATERIALPROFILE = 2235152071, + IFCMATERIALPROFILESET = 164193824, + IFCMATERIALPROFILEWITHOFFSETS = 552965576, + IFCMATERIALUSAGEDEFINITION = 1507914824, + IFCPRESENTATIONITEM = 677532197, + IFCPROJECTEDCRS = 3843373140, + IFCPROPERTYABSTRACTION = 986844984, + IFCRECURRENCEPATTERN = 3915482550, + IFCREFERENCE = 2433181523, + IFCRESOURCELEVELRELATIONSHIP = 2439245199, + IFCSCHEDULINGTIME = 1054537805, + IFCSTRUCTURALLOADCONFIGURATION = 3478079324, + IFCSTRUCTURALLOADORRESULT = 609421318, + IFCSURFACEREINFORCEMENTAREA = 2934153892, + IFCTABLECOLUMN = 2043862942, + IFCTASKTIME = 1549132990, + IFCTASKTIMERECURRING = 2771591690, + IFCTEXTUREVERTEXLIST = 3611470254, + IFCTIMEPERIOD = 1199560280, + IFCWORKTIME = 1236880293, + IFCCOLOURRGBLIST = 3285139300, + IFCCONVERSIONBASEDUNITWITHOFFSET = 2713554722, + IFCEVENTTIME = 211053100, + IFCEXTENDEDPROPERTIES = 297599258, + IFCEXTERNALREFERENCERELATIONSHIP = 1437805879, + IFCINDEXEDCOLOURMAP = 3570813810, + IFCINDEXEDTEXTUREMAP = 1437953363, + IFCINDEXEDTRIANGLETEXTUREMAP = 2133299955, + IFCLAGTIME = 1585845231, + IFCMATERIALCONSTITUENT = 3708119000, + IFCMATERIALCONSTITUENTSET = 2852063980, + IFCMATERIALPROFILESETUSAGE = 3079605661, + IFCMATERIALPROFILESETUSAGETAPERING = 3404854881, + IFCMATERIALRELATIONSHIP = 853536259, + IFCMIRROREDPROFILEDEF = 2998442950, + IFCPREDEFINEDPROPERTIES = 3778827333, + IFCPROPERTYTEMPLATEDEFINITION = 1482703590, + IFCQUANTITYSET = 2090586900, + IFCRESOURCEAPPROVALRELATIONSHIP = 2943643501, + IFCRESOURCECONSTRAINTRELATIONSHIP = 1608871552, + IFCRESOURCETIME = 1042787934, + IFCSWEPTDISKSOLIDPOLYGONAL = 1096409881, + IFCTESSELLATEDITEM = 901063453, + IFCTYPEPROCESS = 3736923433, + IFCTYPERESOURCE = 3698973494, + IFCADVANCEDFACE = 3406155212, + IFCCARTESIANPOINTLIST = 574549367, + IFCCARTESIANPOINTLIST2D = 1675464909, + IFCCARTESIANPOINTLIST3D = 2059837836, + IFCCONSTRUCTIONRESOURCETYPE = 2574617495, + IFCCONTEXT = 3419103109, + IFCCREWRESOURCETYPE = 1815067380, + IFCCURVEBOUNDEDSURFACE = 2629017746, + IFCEVENTTYPE = 4024345920, + IFCEXTRUDEDAREASOLIDTAPERED = 2804161546, + IFCFIXEDREFERENCESWEPTAREASOLID = 2652556860, + IFCGEOGRAPHICELEMENTTYPE = 4095422895, + IFCINDEXEDPOLYGONALFACE = 178912537, + IFCINDEXEDPOLYGONALFACEWITHVOIDS = 2294589976, + IFCLABORRESOURCETYPE = 428585644, + IFCPCURVE = 1682466193, + IFCPREDEFINEDPROPERTYSET = 3967405729, + IFCPROCEDURETYPE = 569719735, + IFCPROJECTLIBRARY = 653396225, + IFCPROPERTYSETTEMPLATE = 492091185, + IFCPROPERTYTEMPLATE = 3521284610, + IFCRELASSIGNSTOGROUPBYFACTOR = 1027710054, + IFCRELDECLARES = 2565941209, + IFCRELDEFINESBYOBJECT = 1462361463, + IFCRELDEFINESBYTEMPLATE = 307848117, + IFCRELINTERFERESELEMENTS = 427948657, + IFCRELSPACEBOUNDARY1STLEVEL = 3523091289, + IFCRELSPACEBOUNDARY2NDLEVEL = 1521410863, + IFCREPARAMETRISEDCOMPOSITECURVESEGMENT = 816062949, + IFCREVOLVEDAREASOLIDTAPERED = 3243963512, + IFCSIMPLEPROPERTYTEMPLATE = 3663146110, + IFCSPATIALELEMENT = 1412071761, + IFCSPATIALELEMENTTYPE = 710998568, + IFCSPATIALZONE = 463610769, + IFCSPATIALZONETYPE = 2481509218, + IFCSPHERICALSURFACE = 4015995234, + IFCSTRUCTURALSURFACEREACTION = 603775116, + IFCSUBCONTRACTRESOURCETYPE = 4095615324, + IFCSURFACECURVE = 699246055, + IFCTASKTYPE = 3206491090, + IFCTESSELLATEDFACESET = 2387106220, + IFCTOROIDALSURFACE = 1935646853, + IFCTRIANGULATEDFACESET = 2916149573, + IFCADVANCEDBREP = 1635779807, + IFCADVANCEDBREPWITHVOIDS = 2603310189, + IFCBSPLINESURFACE = 2887950389, + IFCBSPLINESURFACEWITHKNOTS = 167062518, + IFCCHIMNEYTYPE = 2197970202, + IFCCIVILELEMENTTYPE = 3893394355, + IFCCOMPLEXPROPERTYTEMPLATE = 3875453745, + IFCCOMPOSITECURVEONSURFACE = 15328376, + IFCCONSTRUCTIONEQUIPMENTRESOURCETYPE = 2185764099, + IFCCONSTRUCTIONMATERIALRESOURCETYPE = 4105962743, + IFCCONSTRUCTIONPRODUCTRESOURCETYPE = 1525564444, + IFCCYLINDRICALSURFACE = 1213902940, + IFCDOORTYPE = 2323601079, + IFCELEMENTASSEMBLYTYPE = 2397081782, + IFCENGINETYPE = 132023988, + IFCEVENT = 4148101412, + IFCEXTERNALSPATIALSTRUCTUREELEMENT = 2853485674, + IFCFOOTINGTYPE = 1893162501, + IFCFURNITURE = 1509553395, + IFCGEOGRAPHICELEMENT = 3493046030, + IFCINDEXEDPOLYCURVE = 2571569899, + IFCINTERCEPTORTYPE = 3946677679, + IFCINTERSECTIONCURVE = 3113134337, + IFCMEDICALDEVICETYPE = 1114901282, + IFCOPENINGSTANDARDCASE = 3079942009, + IFCPILETYPE = 1158309216, + IFCPOLYGONALFACESET = 2839578677, + IFCRAMPTYPE = 1469900589, + IFCRATIONALBSPLINESURFACEWITHKNOTS = 683857671, + IFCREINFORCINGELEMENTTYPE = 964333572, + IFCREINFORCINGMESHTYPE = 2310774935, + IFCROOFTYPE = 2781568857, + IFCSEAMCURVE = 2157484638, + IFCSHADINGDEVICETYPE = 4074543187, + IFCSOLARDEVICETYPE = 1072016465, + IFCSTAIRTYPE = 338393293, + IFCSTRUCTURALCURVEACTION = 1004757350, + IFCSTRUCTURALCURVEREACTION = 2757150158, + IFCSTRUCTURALSURFACEACTION = 3657597509, + IFCSURFACEFEATURE = 3101698114, + IFCSYSTEMFURNITUREELEMENT = 413509423, + IFCTENDONANCHORTYPE = 3081323446, + IFCTENDONTYPE = 2415094496, + IFCVIBRATIONISOLATOR = 2391383451, + IFCVOIDINGFEATURE = 926996030, + IFCWINDOWTYPE = 4009809668, + IFCWORKCALENDAR = 4088093105, + IFCAUDIOVISUALAPPLIANCETYPE = 1532957894, + IFCBSPLINECURVEWITHKNOTS = 2461110595, + IFCBOUNDARYCURVE = 1136057603, + IFCBUILDINGELEMENTPARTTYPE = 39481116, + IFCBUILDINGSYSTEM = 1177604601, + IFCBURNERTYPE = 2188180465, + IFCCABLEFITTINGTYPE = 2674252688, + IFCCHIMNEY = 3296154744, + IFCCIVILELEMENT = 1677625105, + IFCCOLUMNSTANDARDCASE = 905975707, + IFCCOMMUNICATIONSAPPLIANCETYPE = 400855858, + IFCDISTRIBUTIONSYSTEM = 3205830791, + IFCDOORSTANDARDCASE = 3242481149, + IFCELECTRICDISTRIBUTIONBOARDTYPE = 2417008758, + IFCENGINE = 2814081492, + IFCEVAPORATIVECOOLER = 3747195512, + IFCEVAPORATOR = 484807127, + IFCEXTERNALSPATIALELEMENT = 1209101575, + IFCFLOWMETER = 2188021234, + IFCHEATEXCHANGER = 3319311131, + IFCHUMIDIFIER = 2068733104, + IFCINTERCEPTOR = 4175244083, + IFCJUNCTIONBOX = 2176052936, + IFCLAMP = 76236018, + IFCLIGHTFIXTURE = 629592764, + IFCMEDICALDEVICE = 1437502449, + IFCMEMBERSTANDARDCASE = 1911478936, + IFCMOTORCONNECTION = 2474470126, + IFCOUTERBOUNDARYCURVE = 144952367, + IFCOUTLET = 3694346114, + IFCPIPEFITTING = 310824031, + IFCPIPESEGMENT = 3612865200, + IFCPLATESTANDARDCASE = 1156407060, + IFCPROTECTIVEDEVICE = 738039164, + IFCPROTECTIVEDEVICETRIPPINGUNITTYPE = 655969474, + IFCPUMP = 90941305, + IFCRATIONALBSPLINECURVEWITHKNOTS = 1232101972, + IFCREINFORCINGBARTYPE = 2572171363, + IFCSANITARYTERMINAL = 3053780830, + IFCSHADINGDEVICE = 1329646415, + IFCSLABELEMENTEDCASE = 3127900445, + IFCSLABSTANDARDCASE = 3027962421, + IFCSOLARDEVICE = 3420628829, + IFCSPACEHEATER = 1999602285, + IFCSTACKTERMINAL = 1404847402, + IFCSTRUCTURALLOADCASE = 385403989, + IFCSWITCHINGDEVICE = 1162798199, + IFCTANK = 812556717, + IFCTRANSFORMER = 3825984169, + IFCTUBEBUNDLE = 3026737570, + IFCUNITARYCONTROLELEMENTTYPE = 3179687236, + IFCUNITARYEQUIPMENT = 4292641817, + IFCVALVE = 4207607924, + IFCWALLELEMENTEDCASE = 4156078855, + IFCWASTETERMINAL = 4237592921, + IFCWINDOWSTANDARDCASE = 486154966, + IFCAIRTERMINAL = 1634111441, + IFCAIRTERMINALBOX = 177149247, + IFCAIRTOAIRHEATRECOVERY = 2056796094, + IFCAUDIOVISUALAPPLIANCE = 277319702, + IFCBEAMSTANDARDCASE = 2906023776, + IFCBOILER = 32344328, + IFCBURNER = 2938176219, + IFCCABLECARRIERFITTING = 635142910, + IFCCABLECARRIERSEGMENT = 3758799889, + IFCCABLEFITTING = 1051757585, + IFCCABLESEGMENT = 4217484030, + IFCCHILLER = 3902619387, + IFCCOIL = 639361253, + IFCCOMMUNICATIONSAPPLIANCE = 3221913625, + IFCCOMPRESSOR = 3571504051, + IFCCONDENSER = 2272882330, + IFCCOOLEDBEAM = 4136498852, + IFCCOOLINGTOWER = 3640358203, + IFCDAMPER = 4074379575, + IFCDISTRIBUTIONCIRCUIT = 562808652, + IFCDUCTFITTING = 342316401, + IFCDUCTSEGMENT = 3518393246, + IFCDUCTSILENCER = 1360408905, + IFCELECTRICAPPLIANCE = 1904799276, + IFCELECTRICDISTRIBUTIONBOARD = 862014818, + IFCELECTRICFLOWSTORAGEDEVICE = 3310460725, + IFCELECTRICGENERATOR = 264262732, + IFCELECTRICMOTOR = 402227799, + IFCELECTRICTIMECONTROL = 1003880860, + IFCFAN = 3415622556, + IFCFILTER = 819412036, + IFCFIRESUPPRESSIONTERMINAL = 1426591983, + IFCFLOWINSTRUMENT = 182646315, + IFCPROTECTIVEDEVICETRIPPINGUNIT = 2295281155, + IFCSENSOR = 4086658281, + IFCUNITARYCONTROLELEMENT = 630975310, + IFCACTUATOR = 4288193352, + IFCALARM = 3087945054, + IFCCONTROLLER = 25142252, + IFCALIGNMENTPARAMETERSEGMENT = 2879124712, + IFCALIGNMENTVERTICALSEGMENT = 3633395639, + IFCQUANTITYNUMBER = 2691318326, + IFCTEXTURECOORDINATEINDICES = 222769930, + IFCTEXTURECOORDINATEINDICESWITHVOIDS = 1010789467, + IFCALIGNMENTCANTSEGMENT = 3752311538, + IFCALIGNMENTHORIZONTALSEGMENT = 536804194, + IFCLINEARPLACEMENT = 388784114, + IFCOPENCROSSPROFILEDEF = 182550632, + IFCPOINTBYDISTANCEEXPRESSION = 2165702409, + IFCSEGMENT = 823603102, + IFCAXIS2PLACEMENTLINEAR = 3425423356, + IFCCURVESEGMENT = 4212018352, + IFCDIRECTRIXCURVESWEPTAREASOLID = 593015953, + IFCINDEXEDPOLYGONALTEXTUREMAP = 3465909080, + IFCOFFSETCURVE = 590820931, + IFCOFFSETCURVEBYDISTANCES = 2485787929, + IFCPOLYNOMIALCURVE = 3381221214, + IFCRELASSOCIATESPROFILEDEF = 1033248425, + IFCRELPOSITIONS = 1441486842, + IFCSECTIONEDSOLID = 1862484736, + IFCSECTIONEDSOLIDHORIZONTAL = 1290935644, + IFCSECTIONEDSURFACE = 1356537516, + IFCSPIRAL = 2735484536, + IFCTHIRDORDERPOLYNOMIALSPIRAL = 782932809, + IFCTRANSPORTATIONDEVICETYPE = 3665877780, + IFCTRIANGULATEDIRREGULARNETWORK = 1229763772, + IFCVEHICLETYPE = 3651464721, + IFCBUILTELEMENTTYPE = 1626504194, + IFCCLOTHOID = 3497074424, + IFCCOSINESPIRAL = 2000195564, + IFCCOURSETYPE = 4189326743, + IFCDEEPFOUNDATIONTYPE = 1306400036, + IFCDIRECTRIXDERIVEDREFERENCESWEPTAREASOLID = 4234616927, + IFCFACILITY = 24185140, + IFCFACILITYPART = 1310830890, + IFCFACILITYPARTCOMMON = 4228831410, + IFCGEOTECHNICALELEMENT = 4230923436, + IFCGEOTECHNICALSTRATUM = 1594536857, + IFCGRADIENTCURVE = 2898700619, + IFCIMPACTPROTECTIONDEVICE = 2568555532, + IFCIMPACTPROTECTIONDEVICETYPE = 3948183225, + IFCKERBTYPE = 679976338, + IFCLINEARELEMENT = 2176059722, + IFCLIQUIDTERMINALTYPE = 1770583370, + IFCMARINEFACILITY = 525669439, + IFCMARINEPART = 976884017, + IFCMOBILETELECOMMUNICATIONSAPPLIANCETYPE = 1950438474, + IFCMOORINGDEVICETYPE = 710110818, + IFCNAVIGATIONELEMENTTYPE = 506776471, + IFCPAVEMENTTYPE = 514975943, + IFCPOSITIONINGELEMENT = 1946335990, + IFCRAILTYPE = 1763565496, + IFCRAILWAY = 3992365140, + IFCRAILWAYPART = 1891881377, + IFCREFERENT = 4021432810, + IFCRELADHERESTOELEMENT = 3818125796, + IFCROAD = 146592293, + IFCROADPART = 550521510, + IFCSECONDORDERPOLYNOMIALSPIRAL = 3649235739, + IFCSEGMENTEDREFERENCECURVE = 544395925, + IFCSEVENTHORDERPOLYNOMIALSPIRAL = 1027922057, + IFCSIGN = 33720170, + IFCSIGNTYPE = 3599934289, + IFCSIGNALTYPE = 1894708472, + IFCSINESPIRAL = 42703149, + IFCTENDONCONDUIT = 3663046924, + IFCTENDONCONDUITTYPE = 2281632017, + IFCTRACKELEMENTTYPE = 618700268, + IFCTRANSPORTATIONDEVICE = 1953115116, + IFCVEHICLE = 840318589, + IFCVIBRATIONDAMPER = 1530820697, + IFCVIBRATIONDAMPERTYPE = 3956297820, + IFCALIGNMENTCANT = 4266260250, + IFCALIGNMENTHORIZONTAL = 1545765605, + IFCALIGNMENTSEGMENT = 317615605, + IFCALIGNMENTVERTICAL = 1662888072, + IFCBEARINGTYPE = 3649138523, + IFCBRIDGE = 644574406, + IFCBRIDGEPART = 963979645, + IFCBUILTELEMENT = 1876633798, + IFCBUILTSYSTEM = 3862327254, + IFCCAISSONFOUNDATIONTYPE = 3203706013, + IFCCONVEYORSEGMENTTYPE = 2940368186, + IFCCOURSE = 1502416096, + IFCDEEPFOUNDATION = 3426335179, + IFCDISTRIBUTIONBOARDTYPE = 479945903, + IFCEARTHWORKSCUT = 3071239417, + IFCEARTHWORKSELEMENT = 1077100507, + IFCEARTHWORKSFILL = 3376911765, + IFCELECTRICFLOWTREATMENTDEVICETYPE = 2142170206, + IFCGEOTECHNICALASSEMBLY = 2713699986, + IFCKERB = 2696325953, + IFCLINEARPOSITIONINGELEMENT = 1154579445, + IFCLIQUIDTERMINAL = 1638804497, + IFCMOBILETELECOMMUNICATIONSAPPLIANCE = 2078563270, + IFCMOORINGDEVICE = 234836483, + IFCNAVIGATIONELEMENT = 2182337498, + IFCPAVEMENT = 1383356374, + IFCRAIL = 3290496277, + IFCREINFORCEDSOIL = 3798194928, + IFCSIGNAL = 991950508, + IFCTRACKELEMENT = 3425753595, + IFCALIGNMENT = 325726236, + IFCBEARING = 4196446775, + IFCBOREHOLE = 3314249567, + IFCCAISSONFOUNDATION = 3999819293, + IFCCONVEYORSEGMENT = 3460952963, + IFCDISTRIBUTIONBOARD = 3693000487, + IFCELECTRICFLOWTREATMENTDEVICE = 24726584, + IFCGEOMODEL = 2680139844, + IFCGEOSLICE = 1971632696, + IFCABSORBEDDOSEMEASURE = 3699917729, + IFCACCELERATIONMEASURE = 4182062534, + IFCAMOUNTOFSUBSTANCEMEASURE = 360377573, + IFCANGULARVELOCITYMEASURE = 632304761, + IFCAREAMEASURE = 2650437152, + IFCBOOLEAN = 2735952531, + IFCBOXALIGNMENT = 1867003952, + IFCCOMPLEXNUMBER = 2991860651, + IFCCOMPOUNDPLANEANGLEMEASURE = 3812528620, + IFCCONTEXTDEPENDENTMEASURE = 3238673880, + IFCCOUNTMEASURE = 1778710042, + IFCCURVATUREMEASURE = 94842927, + IFCDAYINMONTHNUMBER = 86635668, + IFCDAYLIGHTSAVINGHOUR = 300323983, + IFCDESCRIPTIVEMEASURE = 1514641115, + IFCDIMENSIONCOUNT = 4134073009, + IFCDOSEEQUIVALENTMEASURE = 524656162, + IFCDYNAMICVISCOSITYMEASURE = 69416015, + IFCELECTRICCAPACITANCEMEASURE = 1827137117, + IFCELECTRICCHARGEMEASURE = 3818826038, + IFCELECTRICCONDUCTANCEMEASURE = 2093906313, + IFCELECTRICCURRENTMEASURE = 3790457270, + IFCELECTRICRESISTANCEMEASURE = 2951915441, + IFCELECTRICVOLTAGEMEASURE = 2506197118, + IFCENERGYMEASURE = 2078135608, + IFCFONTSTYLE = 1102727119, + IFCFONTVARIANT = 2715512545, + IFCFONTWEIGHT = 2590844177, + IFCFORCEMEASURE = 1361398929, + IFCFREQUENCYMEASURE = 3044325142, + IFCGLOBALLYUNIQUEID = 3064340077, + IFCHEATFLUXDENSITYMEASURE = 3113092358, + IFCHEATINGVALUEMEASURE = 1158859006, + IFCHOURINDAY = 2589826445, + IFCIDENTIFIER = 983778844, + IFCILLUMINANCEMEASURE = 3358199106, + IFCINDUCTANCEMEASURE = 2679005408, + IFCINTEGER = 1939436016, + IFCINTEGERCOUNTRATEMEASURE = 3809634241, + IFCIONCONCENTRATIONMEASURE = 3686016028, + IFCISOTHERMALMOISTURECAPACITYMEASURE = 3192672207, + IFCKINEMATICVISCOSITYMEASURE = 2054016361, + IFCLABEL = 3258342251, + IFCLENGTHMEASURE = 1243674935, + IFCLINEARFORCEMEASURE = 191860431, + IFCLINEARMOMENTMEASURE = 2128979029, + IFCLINEARSTIFFNESSMEASURE = 1307019551, + IFCLINEARVELOCITYMEASURE = 3086160713, + IFCLOGICAL = 503418787, + IFCLUMINOUSFLUXMEASURE = 2095003142, + IFCLUMINOUSINTENSITYDISTRIBUTIONMEASURE = 2755797622, + IFCLUMINOUSINTENSITYMEASURE = 151039812, + IFCMAGNETICFLUXDENSITYMEASURE = 286949696, + IFCMAGNETICFLUXMEASURE = 2486716878, + IFCMASSDENSITYMEASURE = 1477762836, + IFCMASSFLOWRATEMEASURE = 4017473158, + IFCMASSMEASURE = 3124614049, + IFCMASSPERLENGTHMEASURE = 3531705166, + IFCMINUTEINHOUR = 102610177, + IFCMODULUSOFELASTICITYMEASURE = 3341486342, + IFCMODULUSOFLINEARSUBGRADEREACTIONMEASURE = 2173214787, + IFCMODULUSOFROTATIONALSUBGRADEREACTIONMEASURE = 1052454078, + IFCMODULUSOFSUBGRADEREACTIONMEASURE = 1753493141, + IFCMOISTUREDIFFUSIVITYMEASURE = 3177669450, + IFCMOLECULARWEIGHTMEASURE = 1648970520, + IFCMOMENTOFINERTIAMEASURE = 3114022597, + IFCMONETARYMEASURE = 2615040989, + IFCMONTHINYEARNUMBER = 765770214, + IFCNORMALISEDRATIOMEASURE = 2095195183, + IFCNUMERICMEASURE = 2395907400, + IFCPHMEASURE = 929793134, + IFCPARAMETERVALUE = 2260317790, + IFCPLANARFORCEMEASURE = 2642773653, + IFCPLANEANGLEMEASURE = 4042175685, + IFCPOSITIVELENGTHMEASURE = 2815919920, + IFCPOSITIVEPLANEANGLEMEASURE = 3054510233, + IFCPOSITIVERATIOMEASURE = 1245737093, + IFCPOWERMEASURE = 1364037233, + IFCPRESENTABLETEXT = 2169031380, + IFCPRESSUREMEASURE = 3665567075, + IFCRADIOACTIVITYMEASURE = 3972513137, + IFCRATIOMEASURE = 96294661, + IFCREAL = 200335297, + IFCROTATIONALFREQUENCYMEASURE = 2133746277, + IFCROTATIONALMASSMEASURE = 1755127002, + IFCROTATIONALSTIFFNESSMEASURE = 3211557302, + IFCSECONDINMINUTE = 2766185779, + IFCSECTIONMODULUSMEASURE = 3467162246, + IFCSECTIONALAREAINTEGRALMEASURE = 2190458107, + IFCSHEARMODULUSMEASURE = 408310005, + IFCSOLIDANGLEMEASURE = 3471399674, + IFCSOUNDPOWERMEASURE = 846465480, + IFCSOUNDPRESSUREMEASURE = 993287707, + IFCSPECIFICHEATCAPACITYMEASURE = 3477203348, + IFCSPECULAREXPONENT = 2757832317, + IFCSPECULARROUGHNESS = 361837227, + IFCTEMPERATUREGRADIENTMEASURE = 58845555, + IFCTEXT = 2801250643, + IFCTEXTALIGNMENT = 1460886941, + IFCTEXTDECORATION = 3490877962, + IFCTEXTFONTNAME = 603696268, + IFCTEXTTRANSFORMATION = 296282323, + IFCTHERMALADMITTANCEMEASURE = 232962298, + IFCTHERMALCONDUCTIVITYMEASURE = 2645777649, + IFCTHERMALEXPANSIONCOEFFICIENTMEASURE = 2281867870, + IFCTHERMALRESISTANCEMEASURE = 857959152, + IFCTHERMALTRANSMITTANCEMEASURE = 2016195849, + IFCTHERMODYNAMICTEMPERATUREMEASURE = 743184107, + IFCTIMEMEASURE = 2726807636, + IFCTIMESTAMP = 2591213694, + IFCTORQUEMEASURE = 1278329552, + IFCVAPORPERMEABILITYMEASURE = 3345633955, + IFCVOLUMEMEASURE = 3458127941, + IFCVOLUMETRICFLOWRATEMEASURE = 2593997549, + IFCWARPINGCONSTANTMEASURE = 51269191, + IFCWARPINGMOMENTMEASURE = 1718600412, + IFCYEARNUMBER = 4065007721, + IFCARCINDEX = 3683503648, + IFCAREADENSITYMEASURE = 1500781891, + IFCBINARY = 2314439260, + IFCCARDINALPOINTREFERENCE = 1683019596, + IFCDATE = 937566702, + IFCDATETIME = 2195413836, + IFCDAYINWEEKNUMBER = 3701338814, + IFCDURATION = 2541165894, + IFCLANGUAGEID = 1275358634, + IFCLINEINDEX = 1774176899, + IFCNONNEGATIVELENGTHMEASURE = 525895558, + IFCPOSITIVEINTEGER = 1790229001, + IFCPROPERTYSETDEFINITIONSET = 2798247006, + IFCSOUNDPOWERLEVELMEASURE = 4157543285, + IFCSOUNDPRESSURELEVELMEASURE = 3457685358, + IFCTEMPERATURERATEOFCHANGEMEASURE = 1209108979, + IFCTIME = 4075327185, + IFCURIREFERENCE = 950732822, +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcVertex.cs b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcVertex.cs new file mode 100644 index 000000000..c4b28722e --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/Types/IfcVertex.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Speckle.Importers.Ifc.Types; + +[StructLayout(LayoutKind.Sequential, Pack = 1)] +public struct IfcVertex +{ + public double PX, + PY, + PZ; + public double NX, + NY, + NZ; +} diff --git a/Importers/Ifc/Speckle.Importers.Ifc/packages.lock.json b/Importers/Ifc/Speckle.Importers.Ifc/packages.lock.json new file mode 100644 index 000000000..5c6d2f6a8 --- /dev/null +++ b/Importers/Ifc/Speckle.Importers.Ifc/packages.lock.json @@ -0,0 +1,296 @@ +{ + "version": 2, + "dependencies": { + "net8.0": { + "Ara3D.Buffers": { + "type": "Direct", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "SKcQqgtXukyHTlTKFPCaUW4spSkue3XfBU/GmoA7KhH6H995v6TbJxtqjs0EfSgnXEkajL8U7X1NqktScRozXw==", + "dependencies": { + "System.Memory": "4.5.5" + } + }, + "Ara3D.Logging": { + "type": "Direct", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "7HPCe5Dq21JoOBF1iclk9H37XFCoB2ZzCPqTMNgdg4PWFvuRsofNbiuMdiE/HKgMHCVhy1C5opB2KwDKcO7Axw==", + "dependencies": { + "Ara3D.Utils": "1.4.5" + } + }, + "Ara3D.Utils": { + "type": "Direct", + "requested": "[1.4.5, )", + "resolved": "1.4.5", + "contentHash": "yba/E7PpbWP0+RDp+KbKw/vBXnXBSIheScdpVKuDnr8ytRg8pZ2Jd6nwKES+G0FcVEB9PeOVmEW7SGrFvAwRCg==" + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Direct", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.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.InterfaceGenerator": { + "type": "Direct", + "requested": "[0.9.6, )", + "resolved": "0.9.6", + "contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w==" + }, + "Speckle.Objects": { + "type": "Direct", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "BxtORgyOorKHmvBUldyL7t747g3wgXPhkjIKi6qVWxhPxZqzswGf9jQD1GZL57dcWkZPgdQ/vmDsowq6K89T/w==", + "dependencies": { + "Speckle.Sdk": "3.1.0-dev.228" + } + }, + "Speckle.Sdk": { + "type": "Direct", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "2jb3t9KoYEeqGsGLuzR/O3GefG5cs+Zxcpq6dGmHuYLa3cw3nanGJ1X0UkiKFv1CcvZ+aNHPT36QoDVtNvWfow==", + "dependencies": { + "GraphQL.Client": "6.0.0", + "Microsoft.CSharp": "4.7.0", + "Microsoft.Data.Sqlite": "7.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging": "2.2.0", + "Speckle.DoubleNumerics": "4.0.1", + "Speckle.Newtonsoft.Json": "13.0.2", + "Speckle.Sdk.Dependencies": "3.1.0-dev.228" + } + }, + "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.CSharp": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==" + }, + "Microsoft.Data.Sqlite": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", + "dependencies": { + "Microsoft.Data.Sqlite.Core": "7.0.5", + "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4" + } + }, + "Microsoft.Data.Sqlite.Core": { + "type": "Transitive", + "resolved": "7.0.5", + "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "2.2.0" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Primitives": "2.2.0", + "System.ComponentModel.Annotations": "4.5.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==", + "dependencies": { + "System.Memory": "4.5.1", + "System.Runtime.CompilerServices.Unsafe": "4.5.1" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net461": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Speckle.DoubleNumerics": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + }, + "Speckle.Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.2", + "contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA==" + }, + "SQLitePCLRaw.bundle_e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==", + "dependencies": { + "SQLitePCLRaw.lib.e_sqlite3": "2.1.4", + "SQLitePCLRaw.provider.e_sqlite3": "2.1.4" + } + }, + "SQLitePCLRaw.core": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==", + "dependencies": { + "System.Memory": "4.5.3" + } + }, + "SQLitePCLRaw.lib.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg==" + }, + "SQLitePCLRaw.provider.e_sqlite3": { + "type": "Transitive", + "resolved": "2.1.4", + "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==", + "dependencies": { + "SQLitePCLRaw.core": "2.1.4" + } + }, + "System.ComponentModel.Annotations": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==" + }, + "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==" + }, + "Microsoft.Extensions.Logging": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "2.2.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "CentralTransitive", + "requested": "[2.2.0, )", + "resolved": "2.2.0", + "contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A==" + }, + "Speckle.Sdk.Dependencies": { + "type": "CentralTransitive", + "requested": "[3.1.0-dev.228, )", + "resolved": "3.1.0-dev.228", + "contentHash": "Ul2flG1qAnpXYESNB2W4o3x7jxW3BFT2L/jdyO7lgsSVGiNhhVskaXVZXHvqGYwlu0y1J/fhFGANsc+1xnCoQA==" + } + } + } +} \ No newline at end of file diff --git a/Local.sln b/Local.sln index f8d9e93d0..bb623c542 100644 --- a/Local.sln +++ b/Local.sln @@ -262,6 +262,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Naviswor EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Converters.Navisworks2024", "Converters\Navisworks\Speckle.Converters.Navisworks2024\Speckle.Converters.Navisworks2024.csproj", "{52D789C2-5B3C-4225-9F84-C54B3AB4F1B5}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Importers", "Importers", "{24750B06-C90D-43B1-B2E4-088D531D6748}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ifc", "Ifc", "{0EF6C4D6-AC76-408F-8D32-2F9DA8006077}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Importers.Ifc", "Importers\Ifc\Speckle.Importers.Ifc\Speckle.Importers.Ifc.csproj", "{9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Importers.Ifc.Tester", "Importers\Ifc\Speckle.Importers.Ifc.Tester\Speckle.Importers.Ifc.Tester.csproj", "{B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -671,6 +679,18 @@ Global {52D789C2-5B3C-4225-9F84-C54B3AB4F1B5}.Local|Any CPU.Build.0 = Local|Any CPU {52D789C2-5B3C-4225-9F84-C54B3AB4F1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU {52D789C2-5B3C-4225-9F84-C54B3AB4F1B5}.Release|Any CPU.Build.0 = Release|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Local|Any CPU.ActiveCfg = Debug|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Local|Any CPU.Build.0 = Debug|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B}.Release|Any CPU.Build.0 = Release|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Local|Any CPU.ActiveCfg = Debug|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Local|Any CPU.Build.0 = Debug|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -791,6 +811,9 @@ Global {FD44E1F0-D20A-49B6-ADC9-482D911A74FB} = {91DCAFB0-283B-4B07-9F6F-7335DECEEB08} {7791806E-7531-41D8-9C9D-4A1249D9F99C} = {A88CFA1F-B2D5-4DBE-8496-68D0AFA46F2D} {52D789C2-5B3C-4225-9F84-C54B3AB4F1B5} = {AE58C92C-DBF3-4248-8614-8F283B8CB5F8} + {0EF6C4D6-AC76-408F-8D32-2F9DA8006077} = {24750B06-C90D-43B1-B2E4-088D531D6748} + {9FD99F9B-8D50-4C7A-B3A6-22E28AB5F26B} = {0EF6C4D6-AC76-408F-8D32-2F9DA8006077} + {B3B126CA-A419-48D1-B117-6DEE1DE1AFAD} = {0EF6C4D6-AC76-408F-8D32-2F9DA8006077} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8} diff --git a/Speckle.Connectors.sln b/Speckle.Connectors.sln index 0eaa82b03..a767365d0 100644 --- a/Speckle.Connectors.sln +++ b/Speckle.Connectors.sln @@ -69,7 +69,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.DUI.WebV EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "Build\Build.csproj", "{C50AA3E3-8C31-4131-9DEC-1D8B377D5A89}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HostApps", "HostApps", "{42826721-9A18-4762-8BA9-F1429DD5C5B1}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Connectors", "Connectors", "{42826721-9A18-4762-8BA9-F1429DD5C5B1}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{59E8E8F3-4E42-4E92-83B3-B1C2AB901D18}" ProjectSection(SolutionItems) = preProject @@ -271,6 +271,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Naviswor EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Navisworks2025", "Connectors\Navisworks\Speckle.Connectors.Navisworks2025\Speckle.Connectors.Navisworks2025.csproj", "{7791806E-7531-41D8-9C9D-4A1249D9F99C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Importers.Ifc", "Importers\Ifc\Speckle.Importers.Ifc\Speckle.Importers.Ifc.csproj", "{E6B7A640-F85C-41C9-8226-B5310A98822D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ifc", "Ifc", "{F93052A6-6937-443F-8F1F-4A967A8A2BEF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Importers", "Importers", "{336F0341-5C39-40F7-9377-122FED4E4549}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Importers.Ifc.Tester", "Importers\Ifc\Speckle.Importers.Ifc.Tester\Speckle.Importers.Ifc.Tester.csproj", "{FCD6CB79-6B41-4448-99E1-787408AD24B0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -662,6 +670,18 @@ Global {7791806E-7531-41D8-9C9D-4A1249D9F99C}.Local|Any CPU.Build.0 = Debug|Any CPU {7791806E-7531-41D8-9C9D-4A1249D9F99C}.Release|Any CPU.ActiveCfg = Release|Any CPU {7791806E-7531-41D8-9C9D-4A1249D9F99C}.Release|Any CPU.Build.0 = Release|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Local|Any CPU.ActiveCfg = Debug|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Local|Any CPU.Build.0 = Debug|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6B7A640-F85C-41C9-8226-B5310A98822D}.Release|Any CPU.Build.0 = Release|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Local|Any CPU.ActiveCfg = Debug|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Local|Any CPU.Build.0 = Debug|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCD6CB79-6B41-4448-99E1-787408AD24B0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -782,6 +802,9 @@ Global {04FC86A3-2E25-41A1-98C5-10898616CD78} = {19F15419-F493-4D53-83EA-F90869D97D6E} {FD44E1F0-D20A-49B6-ADC9-482D911A74FB} = {91DCAFB0-283B-4B07-9F6F-7335DECEEB08} {7791806E-7531-41D8-9C9D-4A1249D9F99C} = {A88CFA1F-B2D5-4DBE-8496-68D0AFA46F2D} + {E6B7A640-F85C-41C9-8226-B5310A98822D} = {F93052A6-6937-443F-8F1F-4A967A8A2BEF} + {F93052A6-6937-443F-8F1F-4A967A8A2BEF} = {336F0341-5C39-40F7-9377-122FED4E4549} + {FCD6CB79-6B41-4448-99E1-787408AD24B0} = {F93052A6-6937-443F-8F1F-4A967A8A2BEF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8}