diff --git a/.circleci/scripts/config-template.yml b/.circleci/scripts/config-template.yml index 1cf8ab1e64..63b0916c24 100644 --- a/.circleci/scripts/config-template.yml +++ b/.circleci/scripts/config-template.yml @@ -60,7 +60,7 @@ commands: SEMVER=$(echo "$NOPREFIX" | sed -e 's/\/[a-zA-Z-]*//') VER=$(echo "$SEMVER" | sed -e 's/-.*//') VERSION=$(echo $VER.$WORKFLOW_NUM) - $HOME/.dotnet/dotnet pack All.sln -p:Version=$SEMVER -p:FileVersion=$VERSION -c Release -p:WarningLevel=0 -p:IsDesktopBuild=false + $HOME/.dotnet/dotnet pack All.sln -p:Version=$SEMVER -p:FileVersion=$VERSION -c Release -p:IsDesktopBuild=false environment: WORKFLOW_NUM: << pipeline.number >> - run: @@ -92,9 +92,9 @@ jobs: # Each project will have individual jobs for each specific task it has to - run: name: Install dotnet command: | - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel sts $HOME/.dotnet/dotnet --version - - run: + - run: name: Enforce formatting command: | $HOME/.dotnet/dotnet tool restore @@ -107,15 +107,15 @@ jobs: # Each project will have individual jobs for each specific task it has to SEMVER=$(echo "$NOPREFIX" | sed -e 's/\/[a-zA-Z-]*//') VER=$(echo "$SEMVER" | sed -e 's/-.*//') VERSION=$(echo $VER.$WORKFLOW_NUM) - $HOME/.dotnet/dotnet build SDK.slnf -c Release -p:WarningLevel=0 -p:IsDesktopBuild=false -p:Version=$SEMVER -p:FileVersion=$VERSION + $HOME/.dotnet/dotnet build SDK.slnf -c Release -p:IsDesktopBuild=false -p:Version=$SEMVER -p:FileVersion=$VERSION environment: WORKFLOW_NUM: << pipeline.number >> - run-tests: title: Core Unit Tests - project: Core/Tests/TestsUnit.csproj + project: Core/Tests/Speckle.Core.Tests.Unit/Speckle.Core.Tests.Unit.csproj - run-tests: title: Objects Unit Tests - project: Objects/Tests/Tests.csproj + project: Objects/Tests/Objects.Tests.Unit/Objects.Tests.Unit.csproj - store_test_results: path: TestResults @@ -128,14 +128,14 @@ jobs: # Each project will have individual jobs for each specific task it has to - run: name: Install dotnet command: | - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel sts $HOME/.dotnet/dotnet --version - run: name: Startup the Speckle Server command: docker compose -f Core/docker-compose.yml up -d - run-tests: title: Core Integration Tests - project: Core/IntegrationTests/TestsIntegration.csproj + project: Core/Tests/Speckle.Core.Tests.Integration/Speckle.Core.Tests.Integration.csproj - run-tests: title: Automate Integration Tests project: Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/Speckle.Automate.Sdk.Tests.Integration.csproj @@ -163,6 +163,8 @@ jobs: # Each project will have individual jobs for each specific task it has to installer: type: boolean default: false + environment: + SSM: 'C:\Program Files\DigiCert\DigiCert One Signing Manager Tools' steps: - cached-checkout - attach_workspace: @@ -180,7 +182,7 @@ jobs: # Each project will have individual jobs for each specific task it has to $semver = if($tag.Contains('/')) {$tag.Split("/")[0] } else { $tag } $ver = if($semver.Contains('-')) {$semver.Split("-")[0] } else { $semver } $version = "$($ver).$($env:WORKFLOW_NUM)" - msbuild << parameters.slnname >>/<< parameters.slnname >>.sln /p:Configuration=Release /p:WarningLevel=0 /p:IsDesktopBuild=false /p:Version=$semver /p:FileVersion=$version + msbuild << parameters.slnname >>/<< parameters.slnname >>.sln /p:Configuration=Release /p:IsDesktopBuild=false /p:Version=$semver /p:FileVersion=$version environment: WORKFLOW_NUM: << pipeline.number >> - unless: @@ -193,27 +195,48 @@ jobs: # Each project will have individual jobs for each specific task it has to $semver = if($tag.Contains('/')) {$tag.Split("/")[0] } else { $tag } $ver = if($semver.Contains('-')) {$semver.Split("-")[0] } else { $semver } $version = "$($ver).$($env:WORKFLOW_NUM)" - dotnet publish << parameters.slnname >>/<< parameters.slnname >>/<< parameters.projname >>.csproj -c Release -r win-x64 --self-contained /p:WarningLevel=0 /p:Version=$semver /p:FileVersion=$version + dotnet publish << parameters.slnname >>/<< parameters.slnname >>/<< parameters.projname >>.csproj -c Release -r win-x64 --self-contained /p:IsDesktopBuild=false /p:Version=$semver /p:FileVersion=$version environment: WORKFLOW_NUM: << pipeline.number >> - run: name: Exit if External PR shell: bash.exe command: if [ "$CIRCLE_PR_REPONAME" ]; then circleci-agent step halt; fi - - run: - name: Create Innosetup signing cert - command: | - echo $env:PFX_B64 > "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt" - certutil -decode "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt" "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.pfx" - - run: - name: Build Installer - command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\%SLUG%.iss /Sbyparam=$p - shell: cmd.exe #does not work in powershell - environment: - SLUG: << parameters.slug >> - - when: + - unless: # Build installers unsigned on non-tagged builds + condition: << pipeline.git.tag >> + steps: + - run: + name: Build Installer + command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\%SLUG%.iss /Sbyparam=$p + shell: cmd.exe #does not work in powershell + environment: + SLUG: << parameters.slug >> + - when: # Setup certificates and build installers signed for tagged builds condition: << pipeline.git.tag >> steps: + - run: + name: "Digicert Signing Manager Setup" + command: | + cd C:\ + curl.exe -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:$env:SM_API_KEY" -o smtools-windows-x64.msi + msiexec.exe /i smtools-windows-x64.msi /quiet /qn | Wait-Process + - run: + name: Create Auth & OV Signing Cert + command: | + cd C:\ + echo $env:SM_CLIENT_CERT_FILE_B64 > certificate.txt + certutil -decode certificate.txt certificate.p12 + echo $env:SM_OV_PEM_CERT > SpeckleOVCertificate-2024.pem + - run: + name: Sync Certs + command: | + & $env:SSM\smksp_cert_sync.exe + - run: + name: Build Installer + command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\%SLUG%.iss /Sbyparam=$p /DSIGN_INSTALLER + shell: cmd.exe #does not work in powershell + environment: + SLUG: << parameters.slug >> - persist_to_workspace: root: ./ paths: @@ -286,7 +309,7 @@ jobs: # Each project will have individual jobs for each specific task it has to - run: name: Install dotnet command: | - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel sts $HOME/.dotnet/dotnet --version $HOME/.dotnet/dotnet --list-runtimes @@ -312,7 +335,7 @@ jobs: # Each project will have individual jobs for each specific task it has to SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//') VER=$(echo "$SEMVER" | sed -e 's/-.*//') VERSION=$(echo $VER.$WORKFLOW_NUM) - msbuild << parameters.slnname >>/<< parameters.slnname >>.sln /r /p:Configuration='<< parameters.build-config >>' /p:WarningLevel=0 /p:IsDesktopBuild=false /p:Version=$SEMVER /p:FileVersion=$VERSION + msbuild << parameters.slnname >>/<< parameters.slnname >>.sln /r /p:Configuration='<< parameters.build-config >>' /p:IsDesktopBuild=false /p:Version=$SEMVER /p:FileVersion=$VERSION environment: WORKFLOW_NUM: << pipeline.number >> # Compress build files @@ -342,20 +365,24 @@ jobs: # Each project will have individual jobs for each specific task it has to SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//') VER=$(echo "$SEMVER" | sed -e 's/-.*//') VERSION=$(echo $VER.$WORKFLOW_NUM) - $HOME/.dotnet/dotnet publish << parameters.slnname >>/<< parameters.projname >>/<< parameters.projname >>.csproj -c Release -r osx-x64 --self-contained /p:WarningLevel=0 /p:Version=$SEMVER /p:FileVersion=$VERSION + $HOME/.dotnet/dotnet publish << parameters.slnname >>/<< parameters.projname >>/<< parameters.projname >>.csproj -c Release -r osx-arm64 --self-contained /p:IsDesktopBuild=false /p:Version=$SEMVER /p:FileVersion=$VERSION + $HOME/.dotnet/dotnet publish << parameters.slnname >>/<< parameters.projname >>/<< parameters.projname >>.csproj -c Release -r osx-x64 --self-contained /p:IsDesktopBuild=false /p:Version=$SEMVER /p:FileVersion=$VERSION environment: WORKFLOW_NUM: << pipeline.number >> - run: name: Zip Connector files command: | - cd "<< parameters.slnname >>/<< parameters.slnname >>/bin/Release/net6.0/osx-x64/publish" - zip -r << parameters.slug >>-mac.zip "./" + cd "<< parameters.slnname >>/<< parameters.slnname >>/bin/Release/net6.0/osx-arm64/publish" + zip -r << parameters.slug >>-mac-arm64.zip "./" + cd "../../osx-x64/publish" + zip -r << parameters.slug >>-mac-x64.zip "./" # Copy installer files - run: name: Copy files to installer command: | mkdir -p speckle-sharp-ci-tools/Mac/<< parameters.installername >>/.installationFiles/ - cp << parameters.slnname >>/<< parameters.slnname >>/bin/Release/net6.0/osx-x64/publish/<< parameters.slug >>-mac.zip speckle-sharp-ci-tools/Mac/<>/.installationFiles + cp << parameters.slnname >>/<< parameters.slnname >>/bin/Release/net6.0/osx-arm64/publish/<< parameters.slug >>-mac-arm64.zip speckle-sharp-ci-tools/Mac/<>/.installationFiles + cp << parameters.slnname >>/<< parameters.slnname >>/bin/Release/net6.0/osx-x64/publish/<< parameters.slug >>-mac-x64.zip speckle-sharp-ci-tools/Mac/<>/.installationFiles # Create installer - run: name: Exit if External PR @@ -424,7 +451,7 @@ jobs: # Each project will have individual jobs for each specific task it has to SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//') VER=$(echo "$SEMVER" | sed -e 's/-.*//') VERSION=$(echo $VER.$WORKFLOW_NUM) - dotnet build << parameters.slnname >>/<< parameters.slnname >>.slnf -c "<< parameters.build-config >>" -p:WarningLevel=0 -p:Version=$SEMVER -p:FileVersion=$VERSION -p:IsDesktopBuild=false + dotnet build << parameters.slnname >>/<< parameters.slnname >>.slnf -c "<< parameters.build-config >>" -p:Version=$SEMVER -p:FileVersion=$VERSION -p:IsDesktopBuild=false environment: WORKFLOW_NUM: << pipeline.number >> - run: diff --git a/.circleci/scripts/connector-jobs.yml b/.circleci/scripts/connector-jobs.yml index 3c711e5a1e..1d717136ca 100644 --- a/.circleci/scripts/connector-jobs.yml +++ b/.circleci/scripts/connector-jobs.yml @@ -8,12 +8,14 @@ rhino: slnname: ConnectorRhino dllname: SpeckleConnectorRhino.rhp slug: rhino - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorRhino dllname: SpeckleConnectorRhino.rhp slug: grasshopper - context: innosetup + context: + - digicert-signing-connectors-test - build-connector-dotnet-mac: name: rhino-build-mac slnname: ConnectorRhino @@ -47,80 +49,94 @@ dynamo: slnname: ConnectorDynamo dllname: SpeckleConnectorDynamo.dll slug: dynamo - context: innosetup + context: + - digicert-signing-connectors-test revit: - build-connector: slnname: ConnectorRevit dllname: SpeckleConnectorRevit.dll slug: revit - context: innosetup + context: + - digicert-signing-connectors-test autocadcivil: - build-connector: slnname: ConnectorAutocadCivil dllname: SpeckleConnectorAutocad.dll slug: autocad - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorAutocadCivil dllname: SpeckleConnectorAutocad.dll slug: civil3d - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorAutocadCivil dllname: SpeckleConnectorAutocad.dll slug: advancesteel - context: innosetup + context: + - digicert-signing-connectors-test bentley: - build-connector: slnname: ConnectorBentley dllname: SpeckleConnectorMicroStation.dll slug: microstation - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorBentley dllname: SpeckleConnectorOpenBuildings.dll slug: openbuildings - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorBentley dllname: SpeckleConnectorOpenRail.dll slug: openrail - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorBentley dllname: SpeckleConnectorOpenRoads.dll slug: openroads - context: innosetup + context: + - digicert-signing-connectors-test teklastructures: - build-connector: slnname: ConnectorTeklaStructures dllname: SpeckleConnectorTeklaStructures.dll slug: teklastructures - context: innosetup + context: + - digicert-signing-connectors-test csi: - build-connector: slnname: ConnectorCSI dllname: SpeckleConnectorCSI.dll slug: etabs - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorCSI dllname: SpeckleConnectorCSI.dll slug: sap2000 - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorCSI dllname: SpeckleConnectorCSI.dll slug: safe - context: innosetup + context: + - digicert-signing-connectors-test - build-connector: slnname: ConnectorCSI dllname: SpeckleConnectorCSI.dll slug: csibridge - context: innosetup + context: + - digicert-signing-connectors-test archicad: - build-archicad-add-on: @@ -133,16 +149,23 @@ archicad: requires: - get-ci-tools name: build-archicad-add-on-26 + - build-archicad-add-on: + archicadversion: "27" + requires: + - get-ci-tools + name: build-archicad-add-on-27 - build-connector: requires: - build-archicad-add-on-25 - build-archicad-add-on-26 + - build-archicad-add-on-27 slnname: ConnectorArchicad projname: ConnectorArchicad dllname: ConnectorArchicad.dll slug: archicad build-with-msbuild: false - context: innosetup + context: + - digicert-signing-connectors-test - build-archicad-add-on-mac: archicadversion: "25" requires: @@ -157,11 +180,19 @@ archicad: name: build-archicad-add-on-26-mac slug: archicad installername: SpeckleArchicadInstall + - build-archicad-add-on-mac: + archicadversion: "27" + requires: + - get-ci-tools + name: build-archicad-add-on-27-mac + slug: archicad + installername: SpeckleArchicadInstall - build-connector-mac: name: archicad-build-mac requires: - build-archicad-add-on-25-mac - build-archicad-add-on-26-mac + - build-archicad-add-on-27-mac slnname: ConnectorArchicad projname: ConnectorArchicad slug: archicad @@ -173,4 +204,5 @@ navisworks: slnname: ConnectorNavisworks dllname: SpeckleConnectorNavisworks.dll slug: navisworks - context: innosetup + context: + - digicert-signing-connectors-test diff --git a/.editorconfig b/.editorconfig index 607ace1242..a226d40036 100644 --- a/.editorconfig +++ b/.editorconfig @@ -207,12 +207,29 @@ dotnet_analyzer_diagnostic.category-Style.severity = warning # All rules will us dotnet_diagnostic.ide0055.severity = none # Formatting rule: Incompatible with CSharpier dotnet_diagnostic.ide0007.severity = none # Use var instead of explicit type: Preference dotnet_diagnostic.ide0009.severity = none # Add this or Me qualification: Preference +dotnet_diagnostic.ide0200.severity = none # Remove unnecessary lambda expression: may be performance reasons not to +dotnet_diagnostic.ide0058.severity = none # Remove unnecessary expression value: Subjective +dotnet_diagnostic.ide0010.severity = none # Add missing cases to switch statement: Too verbose +dotnet_diagnostic.ide0200.severity = none # Remove unnecessary lambda expression: may be performance reasons not to +dotnet_diagnostic.ide0058.severity = none # Remove unnecessary expression value: Subjective dotnet_diagnostic.ide0001.severity = suggestion # Name can be simplified: Non enforceable in build -dotnet_diagnostic.ide0046.severity = suggestion # Use conditional expression for return: Preference +dotnet_diagnostic.ide0046.severity = suggestion # Use conditional expression for return: Subjective +dotnet_diagnostic.ide0045.severity = suggestion # Use conditional expression for assignment: Subjective dotnet_diagnostic.ide0078.severity = suggestion # Use pattern matching: Subjective dotnet_diagnostic.ide0260.severity = suggestion # Use pattern matching: Subjective -dotnet_diagnostic.ide0058.severity = suggestion # Remove unnecessary expression value: Subjective dotnet_diagnostic.ide0022.severity = suggestion # Use expression body for method: Subjective +dotnet_diagnostic.ide0061.severity = suggestion # Use expression body for local functions: Subjective +dotnet_diagnostic.ide0029.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0030.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0270.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0042.severity = suggestion # Deconstruct variable declaration: Subjective +dotnet_diagnostic.ide0039.severity = suggestion # Use local function instead of lambda: Subjective +dotnet_diagnostic.ide0029.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0030.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0270.severity = suggestion # Null check can be simplified: Subjective +dotnet_diagnostic.ide0042.severity = suggestion # Deconstruct variable declaration: Subjective +dotnet_diagnostic.ide0028.severity = suggestion # Use collection initializers: Subjective +dotnet_diagnostic.ide0074.severity = suggestion # Use compound assignment: Subjective # Maintainability rules dotnet_diagnostic.ca1501.severity = warning # Avoid excessive inheritance @@ -223,17 +240,60 @@ dotnet_diagnostic.ca1507.severity = warning # Use nameof in place of string dotnet_diagnostic.ca1508.severity = warning # Avoid dead conditional code dotnet_diagnostic.ca1509.severity = warning # Invalid entry in code metrics configuration file -dotnet_diagnostic.ca1002.severity = suggestion # Do not expose generic lists -# Misc +# Performance rules +dotnet_diagnostic.ca1849.severity = suggestion # Call async methods when in an async method: May decrease performance +dotnet_diagnostic.ca1822.severity = suggestion # Mark member as static +dotnet_diagnostic.ca1859.severity = suggestion # Use concrete types when possible for improved performance + +# Design rule +dotnet_diagnostic.ca1002.severity = suggestion # Do not expose generic lists dotnet_diagnostic.ca1051.severity = warning # Do not declare visible instance fields dotnet_diagnostic.ca1056.severity = suggestion # URI properties should not be strings dotnet_diagnostic.ca1062.severity = none # Public method must check all parameters for null + +# Naming dotnet_diagnostic.ca1707.severity = none # Remove underscores in names -dotnet_diagnostic.ca1822.severity = suggestion # Mark member as static + +# Usage dotnet_diagnostic.ca2227.severity = suggestion # Collection props should be read-only dotnet_code_quality.ca1051.exclude_structs = true # CA1051 is excluded in structs +dotnet_code_quality.dispose_ownership_transfer_at_constructor = true # CA2000 has a lot of false positives without this +dotnet_code_quality.dispose_ownership_transfer_at_method_call = true # CA2000 has a lot of false positives without this +dotnet_code_quality.dispose_analysis_kind = NonExceptionPathsOnlyNotDisposed # CA2000 has a lot of false positives without this + +# NUnit +dotnet_diagnostic.NUnit2001.severity = warning # Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +dotnet_diagnostic.NUnit2002.severity = warning # Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +dotnet_diagnostic.NUnit2003.severity = warning # Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +dotnet_diagnostic.NUnit2004.severity = warning # Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +dotnet_diagnostic.NUnit2005.severity = warning # Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +dotnet_diagnostic.NUnit2006.severity = warning # Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) + +dotnet_diagnostic.NUnit2010.severity = warning # Use EqualConstraint for better assertion messages in case of failure +dotnet_diagnostic.NUnit2011.severity = warning # Use ContainsConstraint for better assertion messages in case of failure +dotnet_diagnostic.NUnit2011.severity = warning # Use StartsWithConstraint for better assertion messages in case of failure +dotnet_diagnostic.NUnit2011.severity = warning # Use EndsWithConstraint for better assertion messages in case of failure +dotnet_diagnostic.NUnit2014.severity = warning # Use SomeItemsConstraint for better assertion messages in case of failure + +dotnet_diagnostic.NUnit2015.severity = warning # Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +dotnet_diagnostic.NUnit2016.severity = warning # Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +dotnet_diagnostic.NUnit2017.severity = warning # Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +dotnet_diagnostic.NUnit2018.severity = warning # Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +dotnet_diagnostic.NUnit2028.severity = warning # Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +dotnet_diagnostic.NUnit2027.severity = warning # Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +dotnet_diagnostic.NUnit2029.severity = warning # Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +dotnet_diagnostic.NUnit2030.severity = warning # Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +dotnet_diagnostic.NUnit2031.severity = warning # Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +dotnet_diagnostic.NUnit2032.severity = warning # Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +dotnet_diagnostic.NUnit2033.severity = warning # Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +dotnet_diagnostic.NUnit2034.severity = warning # Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +dotnet_diagnostic.NUnit2035.severity = warning # Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +dotnet_diagnostic.NUnit2036.severity = warning # Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +dotnet_diagnostic.NUnit2037.severity = warning # Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +dotnet_diagnostic.NUnit2038.severity = warning # Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +dotnet_diagnostic.NUnit2039.severity = warning # Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) [*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}] indent_style = space diff --git a/.gitignore b/.gitignore index f1fe44c38f..86ceee4974 100644 --- a/.gitignore +++ b/.gitignore @@ -146,6 +146,9 @@ _TeamCity* *.coverage *.coveragexml +# Visual Studio code settings folder +ConnectorArchicad/.vscode/ + # NCrunch _NCrunch_* .*crunch*.local.xml diff --git a/All.sln b/All.sln index 2ad59e31d7..83ebd163a9 100644 --- a/All.sln +++ b/All.sln @@ -139,8 +139,14 @@ EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ConnectorTeklaStructuresShared", "ConnectorTeklaStructures\ConnectorTeklaStructuresShared\ConnectorTeklaStructuresShared.shproj", "{28E2EA7F-FFD1-4E13-9165-0243B5AC82F5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorTeklaStructures2021", "ConnectorTeklaStructures\ConnectorTeklaStructures2021\ConnectorTeklaStructures2021.csproj", "{3AF1EF30-0906-4926-A02C-4E3AD666352A}" + ProjectSection(ProjectDependencies) = postProject + {C1D53822-B11F-4772-996E-1E6D485E0702} = {C1D53822-B11F-4772-996E-1E6D485E0702} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorTeklaStructures2020", "ConnectorTeklaStructures\ConnectorTeklaStructures2020\ConnectorTeklaStructures2020.csproj", "{67157264-AAA5-46A8-A38B-16254B49B892}" + ProjectSection(ProjectDependencies) = postProject + {02A24DD8-E0CA-4657-BAA7-B033A4563709} = {02A24DD8-E0CA-4657-BAA7-B033A4563709} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConverterTeklaStructures", "ConverterTeklaStructures", "{5D988C50-8E85-402A-9020-A4AB0565F0C9}" EndProject @@ -232,8 +238,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterDynamoRevit2023", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRevit2023", "Objects\Converters\ConverterRevit\ConverterRevit2023\ConverterRevit2023.csproj", "{CC790553-8088-41A9-83CD-B29F7141F408}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Objects\Tests\Tests.csproj", "{4BED69F3-5835-4224-BD2C-50FA65C11395}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConverterNavisworks", "ConverterNavisworks", "{B6C38DB9-7B20-4B7E-BC90-6A8CAFC16807}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterNavisworks2023", "Objects\Converters\ConverterNavisworks\ConverterNavisworks2023\ConverterNavisworks2023.csproj", "{EC2436DB-B7F4-4D78-807B-8D91D7D5165C}" @@ -243,14 +247,26 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Navisworks", "Navisworks", "{B6887DDC-B9B9-4B00-95DC-1DD930A1E901}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorNavisworks2023", "ConnectorNavisworks\ConnectorNavisworks2023\ConnectorNavisworks2023.csproj", "{74E39841-B2FA-494D-AC40-A6E505DE6B33}" + ProjectSection(ProjectDependencies) = postProject + {EC2436DB-B7F4-4D78-807B-8D91D7D5165C} = {EC2436DB-B7F4-4D78-807B-8D91D7D5165C} + EndProjectSection EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ConnectorNavisworks", "ConnectorNavisworks\ConnectorNavisworks\ConnectorNavisworks.shproj", "{A517A609-CAB1-4B33-B83C-1B13B34E4560}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorNavisworks2022", "ConnectorNavisworks\ConnectorNavisworks2022\ConnectorNavisworks2022.csproj", "{77D4F346-ACA5-42C8-8522-5EF176F3ADF1}" + ProjectSection(ProjectDependencies) = postProject + {CD334556-BA2B-4272-A1EB-628E8152204A} = {CD334556-BA2B-4272-A1EB-628E8152204A} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorNavisworks2021", "ConnectorNavisworks\ConnectorNavisworks2021\ConnectorNavisworks2021.csproj", "{DEBC2174-5E31-4B6E-8680-690D75E50E2D}" + ProjectSection(ProjectDependencies) = postProject + {CAFD4EAC-75A8-4FC8-94E5-91CADC39F5B3} = {CAFD4EAC-75A8-4FC8-94E5-91CADC39F5B3} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorNavisworks2020", "ConnectorNavisworks\ConnectorNavisworks2020\ConnectorNavisworks2020.csproj", "{9A7D7F9A-4FE1-4053-950B-50B43BC81087}" + ProjectSection(ProjectDependencies) = postProject + {8B467FF4-6A6C-4071-87A7-0DD7B9822251} = {8B467FF4-6A6C-4071-87A7-0DD7B9822251} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterNavisworks2020", "Objects\Converters\ConverterNavisworks\ConverterNavisworks2020\ConverterNavisworks2020.csproj", "{8B467FF4-6A6C-4071-87A7-0DD7B9822251}" EndProject @@ -259,17 +275,19 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterNavisworks2022", "Objects\Converters\ConverterNavisworks\ConverterNavisworks2022\ConverterNavisworks2022.csproj", "{CD334556-BA2B-4272-A1EB-628E8152204A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorGrasshopper7", "ConnectorGrasshopper\ConnectorGrasshopper7\ConnectorGrasshopper7.csproj", "{B81E0F77-1ABD-4941-9D76-C0DC6B1B6B82}" + ProjectSection(ProjectDependencies) = postProject + {EA81F83C-1485-49C8-AB05-9DF2798D70EC} = {EA81F83C-1485-49C8-AB05-9DF2798D70EC} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorGrasshopper6", "ConnectorGrasshopper\ConnectorGrasshopper6\ConnectorGrasshopper6.csproj", "{86920221-416E-4A66-A601-3418207E2401}" + ProjectSection(ProjectDependencies) = postProject + {A8607330-1B23-43CC-8B9B-25818D9C1D64} = {A8607330-1B23-43CC-8B9B-25818D9C1D64} + EndProjectSection EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ConnectorGrasshopperShared", "ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.shproj", "{0F1FD0C3-875F-4689-9C4A-C56E9AB31102}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{8AA78EE8-C33B-4BC5-992A-E5DE7AB0BEC7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsUnit", "Core\Tests\TestsUnit.csproj", "{11E854FA-0001-40C7-AF46-36522CD96296}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsIntegration", "Core\IntegrationTests\TestsIntegration.csproj", "{CFB71500-2CE5-4242-A477-7FC5E6AC05B8}" -EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ConverterBentleyShared", "Objects\Converters\ConverterBentley\ConverterBentleyShared\ConverterBentleyShared.shproj", "{425F0D00-6608-4BD2-A1E0-2730C9F2BFD3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterMicroStation", "Objects\Converters\ConverterBentley\ConverterMicroStation\ConverterMicroStation.csproj", "{F2146143-C240-4920-A01B-2BD7E076AD11}" @@ -291,6 +309,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorOpenRoads", "ConnectorBentley\ConnectorOpenRoads\ConnectorOpenRoads.csproj", "{57BF94A8-8F73-4D1A-91D2-B10CC64178B6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorAdvanceSteel2023", "ConnectorAutocadCivil\ConnectorAdvanceSteel2023\ConnectorAdvanceSteel2023.csproj", "{F4AA033F-4F85-4990-AFE9-86BE00ABE973}" + ProjectSection(ProjectDependencies) = postProject + {F1311789-37DC-47FD-ACEC-75B9B97EDFED} = {F1311789-37DC-47FD-ACEC-75B9B97EDFED} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterAdvanceSteel2023", "Objects\Converters\ConverterAutocadCivil\ConverterAdvanceSteel2023\ConverterAdvanceSteel2023.csproj", "{F1311789-37DC-47FD-ACEC-75B9B97EDFED}" EndProject @@ -301,6 +322,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterGrasshopper6", "Objects\Converters\ConverterRhinoGh\ConverterGrasshopper6\ConverterGrasshopper6.csproj", "{A8607330-1B23-43CC-8B9B-25818D9C1D64}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorTeklaStructures2022", "ConnectorTeklaStructures\ConnectorTeklaStructures2022\ConnectorTeklaStructures2022.csproj", "{48C44A7A-122F-4A1F-B3BA-613CB432A7BC}" + ProjectSection(ProjectDependencies) = postProject + {05F993A6-8651-4801-A732-9A30D1472EEF} = {05F993A6-8651-4801-A732-9A30D1472EEF} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterTeklaStructures2022", "Objects\Converters\ConverterTeklaStructures\ConverterTeklaStructures2022\ConverterTeklaStructures2022.csproj", "{05F993A6-8651-4801-A732-9A30D1472EEF}" EndProject @@ -313,6 +337,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterNavisworks2024", "Objects\Converters\ConverterNavisworks\ConverterNavisworks2024\ConverterNavisworks2024.csproj", "{5F8E5DD7-386E-46A6-85E4-1318CBCC4BA1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorNavisworks2024", "ConnectorNavisworks\ConnectorNavisworks2024\ConnectorNavisworks2024.csproj", "{2568500E-F1BC-440E-9150-DB4820B3FAD6}" + ProjectSection(ProjectDependencies) = postProject + {5F8E5DD7-386E-46A6-85E4-1318CBCC4BA1} = {5F8E5DD7-386E-46A6-85E4-1318CBCC4BA1} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8FE29045-C85E-4374-A1EF-75B9958D341D}" ProjectSection(SolutionItems) = preProject @@ -339,6 +366,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRevit2024", "Objects\Converters\ConverterRevit\ConverterRevit2024\ConverterRevit2024.csproj", "{4C6B5FC0-37E2-442C-B647-2D6A544EFD64}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorRevit2024", "ConnectorRevit\ConnectorRevit2024\ConnectorRevit2024.csproj", "{9A1E899A-F821-4519-AAD1-0789A4E9CCB3}" + ProjectSection(ProjectDependencies) = postProject + {4C6B5FC0-37E2-442C-B647-2D6A544EFD64} = {4C6B5FC0-37E2-442C-B647-2D6A544EFD64} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RevitSharedResources2020", "ConnectorRevit\RevitSharedResources2020\RevitSharedResources2020.csproj", "{8AD2EA4F-14FB-4BB6-94CD-932630DFED9C}" EndProject @@ -371,30 +401,57 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterCivil2024", "Objects\Converters\ConverterAutocadCivil\ConverterCivil2024\ConverterCivil2024.csproj", "{B4D6F6DC-0712-4F9F-A24F-6B76DAE84B6F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorTeklaStructures2023", "ConnectorTeklaStructures\ConnectorTeklaStructures2023\ConnectorTeklaStructures2023.csproj", "{511C2FB0-9C73-4AC9-BA59-C8A84C089C59}" + ProjectSection(ProjectDependencies) = postProject + {EB52E451-9ED8-460E-9EE4-6717BFB12EAB} = {EB52E451-9ED8-460E-9EE4-6717BFB12EAB} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterTeklaStructures2023", "Objects\Converters\ConverterTeklaStructures\ConverterTeklaStructures2023\ConverterTeklaStructures2023.csproj", "{EB52E451-9ED8-460E-9EE4-6717BFB12EAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsPerformance", "Core\TestsPerformance\TestsPerformance.csproj", "{4D1C70D7-FFD5-4518-A374-2A23E020D416}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorAdvanceSteel2024", "ConnectorAutocadCivil\ConnectorAdvanceSteel2024\ConnectorAdvanceSteel2024.csproj", "{3B9189B9-E485-448A-8793-9B9587A36791}" + ProjectSection(ProjectDependencies) = postProject + {737D5567-7B1F-410D-9B7B-BAE8065ED15B} = {737D5567-7B1F-410D-9B7B-BAE8065ED15B} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterAdvanceSteel2024", "Objects\Converters\ConverterAutocadCivil\ConverterAdvanceSteel2024\ConverterAdvanceSteel2024.csproj", "{737D5567-7B1F-410D-9B7B-BAE8065ED15B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterDynamoRevit2024", "Objects\Converters\ConverterDynamo\ConverterDynamoRevit2024\ConverterDynamoRevit2024.csproj", "{75144587-6F51-46C8-8E40-DA652FBC53F4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Automate.Sdk", "Automate\Speckle.Automate.Sdk\Speckle.Automate.Sdk.csproj", "{AF51DD10-C0D5-4209-AF55-8F6476EA8A99}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Automate.Sdk", "Automate\Speckle.Automate.Sdk\Speckle.Automate.Sdk.csproj", "{AF51DD10-C0D5-4209-AF55-8F6476EA8A99}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Automate", "Automate", "{F7399C6A-0EA4-4212-A49E-0342BED82F98}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C6FF0E4F-38A3-4464-98E9-AB71D74B06F4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Automate.Sdk.Tests.Integration", "Automate\Tests\Speckle.Automate.Sdk.Tests.Integration\Speckle.Automate.Sdk.Tests.Integration.csproj", "{A0C9EBE0-A56A-4D07-B6EF-2EEAEC45D6C4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Automate.Sdk.Tests.Integration", "Automate\Tests\Speckle.Automate.Sdk.Tests.Integration\Speckle.Automate.Sdk.Tests.Integration.csproj", "{A0C9EBE0-A56A-4D07-B6EF-2EEAEC45D6C4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConnectorCore", "ConnectorCore", "{DA9DFC36-C53F-4B19-8911-BF7605230BA7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BatchUploader.OperationDriver", "ConnectorCore\BatchUploader.OperationDriver\BatchUploader.OperationDriver.csproj", "{7F0206A9-61D4-4D3A-9B43-789DABA7C143}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BatchUploader.OperationDriver", "ConnectorCore\BatchUploader.OperationDriver\BatchUploader.OperationDriver.csproj", "{7F0206A9-61D4-4D3A-9B43-789DABA7C143}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BatchUploader.Sdk", "ConnectorCore\BatchUploader.Sdk\BatchUploader.Sdk.csproj", "{2CC777EB-BD63-4FAB-BC3A-68A640D2E639}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorRhino8", "ConnectorRhino\ConnectorRhino8\ConnectorRhino8.csproj", "{D22A887D-976C-4DBF-AE5B-9039F169E61C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRhino8", "Objects\Converters\ConverterRhinoGh\ConverterRhino8\ConverterRhino8.csproj", "{89996067-3233-410A-A6A1-39E2F11F0626}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{5009BB59-0F77-4202-8FD2-DECC07E93146}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Core.Tests.Unit", "Core\Tests\Speckle.Core.Tests.Unit\Speckle.Core.Tests.Unit.csproj", "{2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Tests.Performance", "Core\Tests\Speckle.Core.Tests.Performance\Speckle.Core.Tests.Performance.csproj", "{1DE6EF69-0782-4FD7-A2A7-9F697426882D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Tests.Integration", "Core\Tests\Speckle.Core.Tests.Integration\Speckle.Core.Tests.Integration.csproj", "{FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorGrasshopper8", "ConnectorGrasshopper\ConnectorGrasshopper8\ConnectorGrasshopper8.csproj", "{FDBC3082-1FAD-4701-A121-802F591D2D35}" + ProjectSection(ProjectDependencies) = postProject + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F} = {15C4FF29-0370-4860-B80A-06CC5E0E8D5F} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterGrasshopper8", "Objects\Converters\ConverterRhinoGh\ConverterGrasshopper8\ConverterGrasshopper8.csproj", "{15C4FF29-0370-4860-B80A-06CC5E0E8D5F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8A909E95-7A39-4B21-A04A-E168478E71F0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BatchUploader.Sdk", "ConnectorCore\BatchUploader.Sdk\BatchUploader.Sdk.csproj", "{2CC777EB-BD63-4FAB-BC3A-68A640D2E639}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Objects.Tests.Unit", "Objects\Tests\Objects.Tests.Unit\Objects.Tests.Unit.csproj", "{9E74F0E6-94B4-46BD-B1CA-DD874B459399}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -721,7 +778,6 @@ Global {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Debug|x64.ActiveCfg = Debug|Any CPU {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Debug|x64.Build.0 = Debug|Any CPU {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU - {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Release Mac|Any CPU.Build.0 = Release|Any CPU {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Release Mac|x64.ActiveCfg = Release|Any CPU {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Release Mac|x64.Build.0 = Release|Any CPU {3CDEF4CC-2CFA-4939-8427-3ED00FA9DB55}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -752,7 +808,6 @@ Global {D648BB69-B992-4D34-906E-7A547374B86C}.Debug|x64.ActiveCfg = Debug|Any CPU {D648BB69-B992-4D34-906E-7A547374B86C}.Debug|x64.Build.0 = Debug|Any CPU {D648BB69-B992-4D34-906E-7A547374B86C}.Release Mac|Any CPU.ActiveCfg = Release Mac|Any CPU - {D648BB69-B992-4D34-906E-7A547374B86C}.Release Mac|Any CPU.Build.0 = Release Mac|Any CPU {D648BB69-B992-4D34-906E-7A547374B86C}.Release Mac|x64.ActiveCfg = Release Mac|Any CPU {D648BB69-B992-4D34-906E-7A547374B86C}.Release Mac|x64.Build.0 = Release Mac|Any CPU {D648BB69-B992-4D34-906E-7A547374B86C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1259,22 +1314,6 @@ Global {CC790553-8088-41A9-83CD-B29F7141F408}.Release|Any CPU.Build.0 = Release|Any CPU {CC790553-8088-41A9-83CD-B29F7141F408}.Release|x64.ActiveCfg = Release|Any CPU {CC790553-8088-41A9-83CD-B29F7141F408}.Release|x64.Build.0 = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug Mac|x64.ActiveCfg = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug Mac|x64.Build.0 = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug|x64.ActiveCfg = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Debug|x64.Build.0 = Debug|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release Mac|Any CPU.Build.0 = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release Mac|x64.ActiveCfg = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release Mac|x64.Build.0 = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release|Any CPU.Build.0 = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release|x64.ActiveCfg = Release|Any CPU - {4BED69F3-5835-4224-BD2C-50FA65C11395}.Release|x64.Build.0 = Release|Any CPU {EC2436DB-B7F4-4D78-807B-8D91D7D5165C}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU {EC2436DB-B7F4-4D78-807B-8D91D7D5165C}.Debug Mac|x64.ActiveCfg = Debug|x64 {EC2436DB-B7F4-4D78-807B-8D91D7D5165C}.Debug Mac|x64.Build.0 = Debug|x64 @@ -1426,38 +1465,6 @@ Global {86920221-416E-4A66-A601-3418207E2401}.Release|Any CPU.Build.0 = Release|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Release|x64.ActiveCfg = Release|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Release|x64.Build.0 = Release|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug Mac|x64.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug Mac|x64.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug|Any CPU.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug|x64.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Debug|x64.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release Mac|Any CPU.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release Mac|x64.ActiveCfg = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release Mac|x64.Build.0 = Debug|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release|Any CPU.ActiveCfg = Release|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release|Any CPU.Build.0 = Release|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release|x64.ActiveCfg = Release|Any CPU - {11E854FA-0001-40C7-AF46-36522CD96296}.Release|x64.Build.0 = Release|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug Mac|x64.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug Mac|x64.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug|x64.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Debug|x64.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release Mac|Any CPU.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release Mac|x64.ActiveCfg = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release Mac|x64.Build.0 = Debug|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release|Any CPU.Build.0 = Release|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release|x64.ActiveCfg = Release|Any CPU - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8}.Release|x64.Build.0 = Release|Any CPU {F2146143-C240-4920-A01B-2BD7E076AD11}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU {F2146143-C240-4920-A01B-2BD7E076AD11}.Debug Mac|x64.ActiveCfg = Debug|Any CPU {F2146143-C240-4920-A01B-2BD7E076AD11}.Debug Mac|x64.Build.0 = Debug|Any CPU @@ -1647,7 +1654,6 @@ Global {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Debug|x64.ActiveCfg = Debug|Any CPU {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Debug|x64.Build.0 = Debug|Any CPU {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU - {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Release Mac|Any CPU.Build.0 = Release|Any CPU {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Release Mac|x64.ActiveCfg = Debug|Any CPU {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Release Mac|x64.Build.0 = Debug|Any CPU {A8607330-1B23-43CC-8B9B-25818D9C1D64}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -2017,22 +2023,6 @@ Global {EB52E451-9ED8-460E-9EE4-6717BFB12EAB}.Release|Any CPU.Build.0 = Release|Any CPU {EB52E451-9ED8-460E-9EE4-6717BFB12EAB}.Release|x64.ActiveCfg = Release|Any CPU {EB52E451-9ED8-460E-9EE4-6717BFB12EAB}.Release|x64.Build.0 = Release|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug Mac|x64.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug Mac|x64.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug|x64.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Debug|x64.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release Mac|Any CPU.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release Mac|x64.ActiveCfg = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release Mac|x64.Build.0 = Debug|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release|Any CPU.Build.0 = Release|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release|x64.ActiveCfg = Release|Any CPU - {4D1C70D7-FFD5-4518-A374-2A23E020D416}.Release|x64.Build.0 = Release|Any CPU {3B9189B9-E485-448A-8793-9B9587A36791}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU {3B9189B9-E485-448A-8793-9B9587A36791}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU {3B9189B9-E485-448A-8793-9B9587A36791}.Debug Mac|x64.ActiveCfg = Debug|Any CPU @@ -2145,6 +2135,126 @@ Global {2CC777EB-BD63-4FAB-BC3A-68A640D2E639}.Release|Any CPU.Build.0 = Release|Any CPU {2CC777EB-BD63-4FAB-BC3A-68A640D2E639}.Release|x64.ActiveCfg = Release|Any CPU {2CC777EB-BD63-4FAB-BC3A-68A640D2E639}.Release|x64.Build.0 = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug Mac|x64.Build.0 = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug|x64.ActiveCfg = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Debug|x64.Build.0 = Debug|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release Mac|x64.ActiveCfg = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release Mac|x64.Build.0 = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release|Any CPU.Build.0 = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release|x64.ActiveCfg = Release|Any CPU + {D22A887D-976C-4DBF-AE5B-9039F169E61C}.Release|x64.Build.0 = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug Mac|x64.Build.0 = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug|x64.ActiveCfg = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Debug|x64.Build.0 = Debug|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release Mac|x64.ActiveCfg = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release Mac|x64.Build.0 = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release|Any CPU.Build.0 = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release|x64.ActiveCfg = Release|Any CPU + {89996067-3233-410A-A6A1-39E2F11F0626}.Release|x64.Build.0 = Release|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug Mac|x64.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug|x64.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Debug|x64.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release Mac|Any CPU.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release Mac|x64.Build.0 = Debug|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release|Any CPU.Build.0 = Release|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release|x64.ActiveCfg = Release|Any CPU + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D}.Release|x64.Build.0 = Release|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug Mac|x64.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug|x64.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Debug|x64.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release Mac|Any CPU.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release Mac|x64.Build.0 = Debug|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release|Any CPU.Build.0 = Release|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release|x64.ActiveCfg = Release|Any CPU + {1DE6EF69-0782-4FD7-A2A7-9F697426882D}.Release|x64.Build.0 = Release|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug Mac|x64.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug|x64.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Debug|x64.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release Mac|Any CPU.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release Mac|x64.Build.0 = Debug|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release|Any CPU.Build.0 = Release|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release|x64.ActiveCfg = Release|Any CPU + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37}.Release|x64.Build.0 = Release|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug Mac|x64.Build.0 = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug|x64.ActiveCfg = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Debug|x64.Build.0 = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release Mac|x64.Build.0 = Debug|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release|Any CPU.Build.0 = Release|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release|x64.ActiveCfg = Release|Any CPU + {FDBC3082-1FAD-4701-A121-802F591D2D35}.Release|x64.Build.0 = Release|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug Mac|x64.Build.0 = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug|x64.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Debug|x64.Build.0 = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release Mac|x64.Build.0 = Debug|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release|Any CPU.Build.0 = Release|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release|x64.ActiveCfg = Release|Any CPU + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F}.Release|x64.Build.0 = Release|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug Mac|x64.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug Mac|x64.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Debug|x64.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release Mac|Any CPU.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release Mac|x64.ActiveCfg = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release Mac|x64.Build.0 = Debug|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release|Any CPU.Build.0 = Release|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release|x64.ActiveCfg = Release|Any CPU + {9E74F0E6-94B4-46BD-B1CA-DD874B459399}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2235,7 +2345,6 @@ Global {AAA05C3D-856D-4F22-971E-5E3F066D0EAE} = {F0DD5C38-083B-43EA-8654-96247028D8AC} {67A463D3-E98B-4B16-B069-D7BBB05386A1} = {F0DD5C38-083B-43EA-8654-96247028D8AC} {CC790553-8088-41A9-83CD-B29F7141F408} = {925C0BF6-A0B1-4699-9C4B-078E01D652CC} - {4BED69F3-5835-4224-BD2C-50FA65C11395} = {E3916A0F-68D5-4C84-ACAE-41547F75E454} {B6C38DB9-7B20-4B7E-BC90-6A8CAFC16807} = {4DE5ED81-2A55-4C23-A05F-3C9B9B06F85D} {EC2436DB-B7F4-4D78-807B-8D91D7D5165C} = {B6C38DB9-7B20-4B7E-BC90-6A8CAFC16807} {C3232EF3-2000-44C6-A330-B94531C9CC83} = {B6C38DB9-7B20-4B7E-BC90-6A8CAFC16807} @@ -2251,8 +2360,6 @@ Global {B81E0F77-1ABD-4941-9D76-C0DC6B1B6B82} = {9461B162-AD2F-4F60-BCE4-E72DCEFD4608} {86920221-416E-4A66-A601-3418207E2401} = {9461B162-AD2F-4F60-BCE4-E72DCEFD4608} {0F1FD0C3-875F-4689-9C4A-C56E9AB31102} = {9461B162-AD2F-4F60-BCE4-E72DCEFD4608} - {11E854FA-0001-40C7-AF46-36522CD96296} = {8AA78EE8-C33B-4BC5-992A-E5DE7AB0BEC7} - {CFB71500-2CE5-4242-A477-7FC5E6AC05B8} = {8AA78EE8-C33B-4BC5-992A-E5DE7AB0BEC7} {425F0D00-6608-4BD2-A1E0-2730C9F2BFD3} = {B9D189AE-B0AE-49BC-A0A5-ACF87C849615} {F2146143-C240-4920-A01B-2BD7E076AD11} = {B9D189AE-B0AE-49BC-A0A5-ACF87C849615} {931FC9A8-18B4-4AC5-81D9-14C48499BFB5} = {B9D189AE-B0AE-49BC-A0A5-ACF87C849615} @@ -2298,7 +2405,6 @@ Global {B4D6F6DC-0712-4F9F-A24F-6B76DAE84B6F} = {BE521908-7944-46F3-98BF-B47D34509934} {511C2FB0-9C73-4AC9-BA59-C8A84C089C59} = {18C8730C-0173-4987-9416-46F86EC20541} {EB52E451-9ED8-460E-9EE4-6717BFB12EAB} = {5D988C50-8E85-402A-9020-A4AB0565F0C9} - {4D1C70D7-FFD5-4518-A374-2A23E020D416} = {8AA78EE8-C33B-4BC5-992A-E5DE7AB0BEC7} {3B9189B9-E485-448A-8793-9B9587A36791} = {7B7C4CB1-3D60-4A5B-9902-C812521A24B3} {737D5567-7B1F-410D-9B7B-BAE8065ED15B} = {BE521908-7944-46F3-98BF-B47D34509934} {75144587-6F51-46C8-8E40-DA652FBC53F4} = {F0DD5C38-083B-43EA-8654-96247028D8AC} @@ -2307,6 +2413,16 @@ Global {A0C9EBE0-A56A-4D07-B6EF-2EEAEC45D6C4} = {C6FF0E4F-38A3-4464-98E9-AB71D74B06F4} {7F0206A9-61D4-4D3A-9B43-789DABA7C143} = {DA9DFC36-C53F-4B19-8911-BF7605230BA7} {2CC777EB-BD63-4FAB-BC3A-68A640D2E639} = {DA9DFC36-C53F-4B19-8911-BF7605230BA7} + {D22A887D-976C-4DBF-AE5B-9039F169E61C} = {E94E7327-5A9B-48EE-93CC-E9E9A5B980F1} + {89996067-3233-410A-A6A1-39E2F11F0626} = {1FD850CA-A8D7-41DC-9316-B315800437E1} + {5009BB59-0F77-4202-8FD2-DECC07E93146} = {8AA78EE8-C33B-4BC5-992A-E5DE7AB0BEC7} + {2A88A9EA-EB11-49FD-BE95-DA6FC8F6CB3D} = {5009BB59-0F77-4202-8FD2-DECC07E93146} + {1DE6EF69-0782-4FD7-A2A7-9F697426882D} = {5009BB59-0F77-4202-8FD2-DECC07E93146} + {FB2DEE1D-788B-45B6-B80C-D8F7C8390C37} = {5009BB59-0F77-4202-8FD2-DECC07E93146} + {FDBC3082-1FAD-4701-A121-802F591D2D35} = {9461B162-AD2F-4F60-BCE4-E72DCEFD4608} + {15C4FF29-0370-4860-B80A-06CC5E0E8D5F} = {1FD850CA-A8D7-41DC-9316-B315800437E1} + {8A909E95-7A39-4B21-A04A-E168478E71F0} = {E3916A0F-68D5-4C84-ACAE-41547F75E454} + {9E74F0E6-94B4-46BD-B1CA-DD874B459399} = {8A909E95-7A39-4B21-A04A-E168478E71F0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1D43D91B-4F01-4A78-8250-CC6F9BD93A14} @@ -2318,6 +2434,7 @@ Global ConnectorRevit\RevitSharedResources\RevitSharedResources.projitems*{071f914c-f473-4fb2-9faf-98632afb164b}*SharedItemsImports = 13 ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{0f1fd0c3-875f-4689-9c4a-c56e9ab31102}*SharedItemsImports = 13 Objects\Converters\ConverterRevit\ConverterRevitTests\ConverterRevitTestsShared\ConverterRevitTestsShared.projitems*{1085f4b5-fdad-4ff8-b144-dddbd9454f55}*SharedItemsImports = 13 + Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{15c4ff29-0370-4860-b80a-06cc5e0e8d5f}*SharedItemsImports = 5 Objects\Converters\ConverterRevit\ConverterRevitTests\ConverterRevitTestsShared\ConverterRevitTestsShared.projitems*{1d1b6eda-8fd9-4758-9195-c3476db31f4e}*SharedItemsImports = 5 Objects\Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{1f21e740-6b05-47bd-8d2a-c9ed5e91c577}*SharedItemsImports = 5 Objects\Converters\ConverterCSI\ConverterCSIShared\ConverterCSIShared.projitems*{21223ba5-c6e8-405d-b581-106c4726edc0}*SharedItemsImports = 5 @@ -2370,6 +2487,7 @@ Global Objects\Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{8581b4bb-a8bc-4328-99fe-d18615af2554}*SharedItemsImports = 5 ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{86920221-416e-4a66-a601-3418207e2401}*SharedItemsImports = 5 Objects\Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{88a24c40-74c8-4e20-9051-6be9e6adecfd}*SharedItemsImports = 5 + Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{89996067-3233-410a-a6a1-39e2f11f0626}*SharedItemsImports = 5 ConnectorRevit\ConnectorRevit\ConnectorRevit.projitems*{8a53b084-20d8-48f6-9591-9d53cfa74130}*SharedItemsImports = 5 ConnectorRevit\RevitSharedResources\RevitSharedResources.projitems*{8ad2ea4f-14fb-4bb6-94cd-932630dfed9c}*SharedItemsImports = 5 Objects\Converters\ConverterNavisworks\ConverterNavisworks\ConverterNavisworksShared.projitems*{8b467ff4-6a6c-4071-87a7-0dd7b9822251}*SharedItemsImports = 5 @@ -2404,6 +2522,7 @@ Global Objects\Converters\ConverterNavisworks\ConverterNavisworks\ConverterNavisworksShared.projitems*{cd334556-ba2b-4272-a1eb-628e8152204a}*SharedItemsImports = 5 Objects\Converters\ConverterCSI\ConverterCSIShared\ConverterCSIShared.projitems*{d06f557c-452a-4bbe-9b79-a10db03f3832}*SharedItemsImports = 5 Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{d1d0f986-12be-4fd5-8925-c96b1f86427d}*SharedItemsImports = 5 + ConnectorRhino\ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{d22a887d-976c-4dbf-ae5b-9039f169e61c}*SharedItemsImports = 5 Objects\Converters\ConverterRevit\ConverterRevitTests\ConverterRevitTestsShared\ConverterRevitTestsShared.projitems*{d296722d-0798-4110-9c6e-dfb0824a7251}*SharedItemsImports = 5 ConnectorRhino\ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{d648bb69-b992-4d34-906e-7a547374b86c}*SharedItemsImports = 5 Objects\Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{d9f443b5-c55b-4ad8-9c70-bc3d2be781be}*SharedItemsImports = 5 @@ -2419,6 +2538,7 @@ Global ConnectorAutocadCivil\ConnectorAutocadCivil\ConnectorAutocadCivilShared.projitems*{f4aa033f-4f85-4990-afe9-86be00abe973}*SharedItemsImports = 5 ConnectorAutocadCivil\ConnectorAutocadCivil\ConnectorAutocadCivilShared.projitems*{f4bfb155-7ba9-4e46-8240-9c825060c904}*SharedItemsImports = 5 ConnectorBentley\ConnectorBentleyShared\ConnectorBentleyShared.projitems*{fc044d89-0ff3-441d-b35d-87454a693c16}*SharedItemsImports = 5 + ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{fdbc3082-1fad-4701-a121-802f591d2d35}*SharedItemsImports = 5 ConnectorAutocadCivil\ConnectorAutocadCivil\ConnectorAutocadCivilShared.projitems*{ff1793e1-77f5-4a92-b3f2-6d8b104e479b}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/All.sln.DotSettings b/All.sln.DotSettings index b2c1dde104..1170e1aa0a 100644 --- a/All.sln.DotSettings +++ b/All.sln.DotSettings @@ -11,6 +11,8 @@ SUGGESTION HINT HINT + DO_NOT_SHOW + HINT SUGGESTION SUGGESTION @@ -420,6 +422,8 @@ WARNING SUGGESTION SUGGESTION + DO_NOT_SHOW + DO_NOT_SHOW SUGGESTION DO_NOT_SHOW HINT @@ -609,12 +613,19 @@ Speckle:Cleanup + CCW CSI + DUI GQL + GUID QL SQ UI True ExternalToolData|CSharpier|csharpier||csharpier|$FILE$ CamelCase - True \ No newline at end of file + True + True + True + True + True diff --git a/Automate/Speckle.Automate.Sdk/AutomationContext.cs b/Automate/Speckle.Automate.Sdk/AutomationContext.cs index 0ce6eceaaf..9277158e44 100644 --- a/Automate/Speckle.Automate.Sdk/AutomationContext.cs +++ b/Automate/Speckle.Automate.Sdk/AutomationContext.cs @@ -1,10 +1,9 @@ -# nullable enable using System.Diagnostics; using GraphQL; -using Serilog.Debugging; using Speckle.Automate.Sdk.Schema; using Speckle.Core.Api; using Speckle.Core.Credentials; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Transports; using Speckle.Newtonsoft.Json; @@ -16,40 +15,41 @@ public class AutomationContext { public AutomationRunData AutomationRunData { get; set; } public string? ContextView => AutomationResult.ResultView; - public Client SpeckleClient { get; set; } + public Client SpeckleClient { get; private set; } - private ServerTransport serverTransport; - private string speckleToken; + private ServerTransport _serverTransport; + private string _speckleToken; // keep a memory transport at hand, to speed up things if needed - private MemoryTransport memoryTransport; + private MemoryTransport _memoryTransport; // added for performance measuring - private Stopwatch initTime; + private Stopwatch _initTime; - internal AutomationResult AutomationResult { get; set; } + internal AutomationResult AutomationResult { get; private set; } public static async Task Initialize(AutomationRunData automationRunData, string speckleToken) { - var account = new Account - { - token = speckleToken, - serverInfo = new ServerInfo { url = automationRunData.SpeckleServerUrl } - }; + Account account = + new() + { + token = speckleToken, + serverInfo = new ServerInfo { url = automationRunData.SpeckleServerUrl } + }; await account.Validate().ConfigureAwait(false); - var client = new Client(account); - var serverTransport = new ServerTransport(account, automationRunData.ProjectId); - var initTime = new Stopwatch(); + Client client = new(account); + ServerTransport serverTransport = new(account, automationRunData.ProjectId); + Stopwatch initTime = new(); initTime.Start(); return new AutomationContext { AutomationRunData = automationRunData, SpeckleClient = client, - serverTransport = serverTransport, - speckleToken = speckleToken, - memoryTransport = new MemoryTransport(), - initTime = initTime, + _serverTransport = serverTransport, + _speckleToken = speckleToken, + _memoryTransport = new MemoryTransport(), + _initTime = initTime, AutomationResult = new AutomationResult(), }; } @@ -66,19 +66,24 @@ public static async Task Initialize(string automationRunData, public string RunStatus => AutomationResult.RunStatus; public string? StatusMessage => AutomationResult.StatusMessage; - public TimeSpan Elapsed => initTime.Elapsed; + public TimeSpan Elapsed => _initTime.Elapsed; + /// + /// Receive version for automation. + /// + /// Commit object. + /// Throws if commit object is null. public async Task ReceiveVersion() { - var commit = await SpeckleClient + Commit? commit = await SpeckleClient .CommitGet(AutomationRunData.ProjectId, AutomationRunData.VersionId) .ConfigureAwait(false); - var commitRootObject = await Operations - .Receive(commit.referencedObject, serverTransport, memoryTransport) + Base? commitRootObject = await Operations + .Receive(commit.referencedObject, _serverTransport, _memoryTransport) .ConfigureAwait(false); if (commitRootObject == null) { - throw new Exception("Commit root object was null"); + throw new SpeckleException("Commit root object was null"); } Console.WriteLine( @@ -87,34 +92,43 @@ public async Task ReceiveVersion() return commitRootObject; } - public async Task CreateNewVersionInProject(Base rootObject, string branchName, string versionMessage = "") + /// + /// Creates new version in the project. + /// + /// Object to send to project. + /// Model name to create version in it. + /// Version message. + /// Version id. + /// Throws if given model name is as same as with model name in automation run data. + /// The reason is to prevent circular run loop in automation. + public async Task CreateNewVersionInProject(Base rootObject, string modelName, string versionMessage = "") { - if (branchName == AutomationRunData.BranchName) + if (modelName == AutomationRunData.BranchName) { throw new ArgumentException( - $"The target model: {branchName} cannot match the model that triggered this automation: {AutomationRunData.ModelId}/{AutomationRunData.BranchName}", - nameof(branchName) + $"The target model: {modelName} cannot match the model that triggered this automation: {AutomationRunData.ModelId}/{AutomationRunData.BranchName}", + nameof(modelName) ); } - var rootObjectId = await Operations - .Send(rootObject, new List { serverTransport, memoryTransport }, useDefaultCache: false) + string rootObjectId = await Operations + .Send(rootObject, new List { _serverTransport, _memoryTransport }) .ConfigureAwait(false); - var branch = await SpeckleClient.BranchGet(AutomationRunData.ProjectId, branchName).ConfigureAwait(false); + Branch branch = await SpeckleClient.BranchGet(AutomationRunData.ProjectId, modelName).ConfigureAwait(false); if (branch is null) { // Create the branch with the specified name await SpeckleClient - .BranchCreate(new BranchCreateInput() { streamId = AutomationRunData.ProjectId, name = branchName }) + .BranchCreate(new BranchCreateInput() { streamId = AutomationRunData.ProjectId, name = modelName }) .ConfigureAwait(false); } - var versionId = await SpeckleClient + string versionId = await SpeckleClient .CommitCreate( new CommitCreateInput { streamId = AutomationRunData.ProjectId, - branchName = branchName, + branchName = modelName, objectId = rootObjectId, message = versionMessage, } @@ -123,9 +137,15 @@ await SpeckleClient return versionId; } + /// + /// Set context view for automation result view. + /// + /// Resource contexts to bind into view. + /// Whether bind source version into result view or not. + /// Throws if there is no context to create result view. public void SetContextView(List? resourceIds = null, bool includeSourceModelVersion = true) { - var linkResources = new List(); + List linkResources = new(); if (includeSourceModelVersion) { linkResources.Add($@"{AutomationRunData.ModelId}@{AutomationRunData.VersionId}"); @@ -138,7 +158,7 @@ public void SetContextView(List? resourceIds = null, bool includeSourceM if (linkResources.Count == 0) { - throw new Exception("We do not have enough resource ids to compose a context view"); + throw new SpeckleException("We do not have enough resource ids to compose a context view"); } AutomationResult.ResultView = $"/projects/{AutomationRunData.ProjectId}/models/{string.Join(",", linkResources)}"; @@ -158,10 +178,11 @@ public async Task ReportRunStatus() } }; } - var request = new GraphQLRequest - { - Query = - @" + GraphQLRequest request = + new() + { + Query = + @" mutation ReportFunctionRunStatus( $automationId: String!, $automationRevisionId: String!, @@ -196,25 +217,31 @@ mutation ReportFunctionRunStatus( } } ", - Variables = new - { - automationId = AutomationRunData.AutomationId, - automationRevisionId = AutomationRunData.AutomationRevisionId, - automationRunId = AutomationRunData.AutomationRunId, - versionId = AutomationRunData.VersionId, - functionId = AutomationRunData.FunctionId, - functionName = AutomationRunData.FunctionName, - functionLogo = AutomationRunData.FunctionLogo, - runStatus = RunStatus, - statusMessage = AutomationResult.StatusMessage, - elapsed = Elapsed.TotalSeconds, - resultVersionIds = AutomationResult.ResultVersions, - objectResults, - } - }; + Variables = new + { + automationId = AutomationRunData.AutomationId, + automationRevisionId = AutomationRunData.AutomationRevisionId, + automationRunId = AutomationRunData.AutomationRunId, + versionId = AutomationRunData.VersionId, + functionId = AutomationRunData.FunctionId, + functionName = AutomationRunData.FunctionName, + functionLogo = AutomationRunData.FunctionLogo, + runStatus = RunStatus, + statusMessage = AutomationResult.StatusMessage, + elapsed = Elapsed.TotalSeconds, + resultVersionIds = AutomationResult.ResultVersions, + objectResults, + } + }; await SpeckleClient.ExecuteGraphQLRequest>(request).ConfigureAwait(false); } + /// + /// Stores result file in automation result. It will be available to download on Frontend if added. + /// + /// File path to store. + /// Throws if given file path is not exist. + /// Throws if upload requests return no result. public async Task StoreFileResult(string filePath) { if (!File.Exists(filePath)) @@ -222,38 +249,37 @@ public async Task StoreFileResult(string filePath) throw new FileNotFoundException("The given file path doesn't exist", fileName: filePath); } - using var formData = new MultipartFormDataContent(); - - var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - using var streamContent = new StreamContent(fileStream); + using MultipartFormDataContent formData = new(); + FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read); + using StreamContent streamContent = new(fileStream); formData.Add(streamContent, "files", Path.GetFileName(filePath)); - var request = await SpeckleClient.GQLClient.HttpClient + HttpResponseMessage? request = await SpeckleClient.GQLClient.HttpClient .PostAsync( new Uri($"{AutomationRunData.SpeckleServerUrl}/api/stream/{AutomationRunData.ProjectId}/blob"), formData ) .ConfigureAwait(false); request.EnsureSuccessStatusCode(); - var responseString = await request.Content.ReadAsStringAsync().ConfigureAwait(false); + string? responseString = await request.Content.ReadAsStringAsync().ConfigureAwait(false); Console.WriteLine("RESPONSE - " + responseString); - var uploadResponse = JsonConvert.DeserializeObject(responseString); + BlobUploadResponse uploadResponse = JsonConvert.DeserializeObject(responseString); if (uploadResponse.UploadResults.Count != 1) { - throw new Exception("Expected one upload result."); + throw new SpeckleException("Expected one upload result."); } AutomationResult.Blobs.AddRange(uploadResponse.UploadResults.Select(r => r.BlobId)); } - private void _markRun(AutomationStatus status, string? statusMessage) + private void MarkRun(AutomationStatus status, string? statusMessage) { - var duration = Elapsed.TotalSeconds; + double duration = Elapsed.TotalSeconds; AutomationResult.StatusMessage = statusMessage; - var statusValue = AutomationStatusMapping.Get(status); + string statusValue = AutomationStatusMapping.Get(status); AutomationResult.RunStatus = statusValue; AutomationResult.Elapsed = duration; - var msg = $"Automation run {statusValue} after {duration} seconds."; + string msg = $"Automation run {statusValue} after {duration} seconds."; if (statusMessage is not null) { msg += $"\n{statusMessage}"; @@ -262,49 +288,64 @@ private void _markRun(AutomationStatus status, string? statusMessage) Console.WriteLine(msg); } - public void MarkRunFailed(string statusMessage) - { - _markRun(AutomationStatus.Failed, statusMessage); - } - - public void MarkRunSuccess(string? statusMessage) - { - _markRun(AutomationStatus.Succeeded, statusMessage); - } - + public void MarkRunFailed(string statusMessage) => MarkRun(AutomationStatus.Failed, statusMessage); + + public void MarkRunSuccess(string? statusMessage) => MarkRun(AutomationStatus.Succeeded, statusMessage); + + /// + /// Add a new error case to the run results. + /// If the error cause has already created an error case, + /// the case will be extended with a new case referring to the causing objects. + /// + /// A short tag for the error type. + /// A list of objectId's that are causing the error. + /// Optional error message. + /// User provided metadata key value pairs. + /// Case specific 3D visual overrides. + /// Throws if the provided input is empty. public void AttachErrorToObjects( string category, IEnumerable objectIds, string? message = null, Dictionary? metadata = null, Dictionary? visualOverrides = null - ) - { - AttachResultToObjects(ObjectResultLevel.Error, category, objectIds, message, metadata, visualOverrides); - } - + ) => AttachResultToObjects(ObjectResultLevel.Error, category, objectIds, message, metadata, visualOverrides); + + /// + /// Add a new warning case to the run results. + /// If the warning cause has already created a warning case, + /// the case will be extended with a new case referring to the causing objects. + /// + /// public void AttachWarningToObjects( string category, IEnumerable objectIds, string? message = null, Dictionary? metadata = null, Dictionary? visualOverrides = null - ) - { - AttachResultToObjects(ObjectResultLevel.Warning, category, objectIds, message, metadata, visualOverrides); - } - + ) => AttachResultToObjects(ObjectResultLevel.Warning, category, objectIds, message, metadata, visualOverrides); + + /// + /// Add a new info case to the run results. + /// If the info cause has already created an info case, + /// the case will be extended with a new case referring to the causing objects. + /// + /// public void AttachInfoToObjects( string category, IEnumerable objectIds, string? message = null, Dictionary? metadata = null, Dictionary? visualOverrides = null - ) - { - AttachResultToObjects(ObjectResultLevel.Info, category, objectIds, message, metadata, visualOverrides); - } - + ) => AttachResultToObjects(ObjectResultLevel.Info, category, objectIds, message, metadata, visualOverrides); + + /// + /// Add a new case to the run results. + /// If the cause has already created an case with equal level, + /// the case will be extended with a new case referring to the causing objects. + /// + /// The level assigned to this result. + /// public void AttachResultToObjects( ObjectResultLevel level, string category, @@ -314,19 +355,25 @@ public void AttachResultToObjects( Dictionary? visualOverrides = null ) { - var levelString = ObjectResultLevelMapping.Get(level); - var objectIdList = objectIds.ToList(); + string levelString = ObjectResultLevelMapping.Get(level); + List objectIdList = objectIds.ToList(); + if (objectIdList.Count == 0) + { + throw new ArgumentException($"Need at least one object_id to report a(n) {level}"); + } + Console.WriteLine($"Created new {levelString.ToUpper()} category: {category} caused by: {message}"); - var resultCase = new ResultCase - { - Category = category, - Level = levelString, - ObjectIds = objectIdList, - Message = message, - Metadata = metadata, - VisualOverrides = visualOverrides - }; + ResultCase resultCase = + new() + { + Category = category, + Level = levelString, + ObjectIds = objectIdList, + Message = message, + Metadata = metadata, + VisualOverrides = visualOverrides + }; AutomationResult.ObjectResults.Add(resultCase); } diff --git a/Automate/Speckle.Automate.Sdk/Runner.cs b/Automate/Speckle.Automate.Sdk/Runner.cs index 275749821c..d3b0186adc 100644 --- a/Automate/Speckle.Automate.Sdk/Runner.cs +++ b/Automate/Speckle.Automate.Sdk/Runner.cs @@ -1,9 +1,10 @@ using System.CommandLine; using System.Diagnostics.CodeAnalysis; +using Newtonsoft.Json.Schema; using Newtonsoft.Json.Schema.Generation; using Newtonsoft.Json.Serialization; using Speckle.Automate.Sdk.Schema; -using Speckle.Newtonsoft.Json; +using Speckle.Core.Logging; namespace Speckle.Automate.Sdk; @@ -21,7 +22,9 @@ TInput inputs ) where TInput : struct { - var automationContext = await AutomationContext.Initialize(automationRunData, speckleToken).ConfigureAwait(false); + AutomationContext automationContext = await AutomationContext + .Initialize(automationRunData, speckleToken) + .ConfigureAwait(false); try { @@ -33,7 +36,7 @@ TInput inputs ); } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Console.WriteLine(ex.ToString()); automationContext.MarkRunFailed("Function error. Check the automation run logs for details."); @@ -83,7 +86,7 @@ public static async Task Main(string[] args, Func } /// - /// Main entrypoint to execute an Automate function with input data of type + /// Main entrypoint to execute an Automate function with input data of type . /// /// The command line arguments passed into the function by automate /// The automate function to execute @@ -92,31 +95,23 @@ public static async Task Main(string[] args, Func public static async Task Main(string[] args, Func automateFunction) where TInput : struct { - var returnCode = 0; // This is the CLI return code, defaults to 0 (Success), change to 1 to flag a failed run. + int returnCode = 0; // This is the CLI return code, defaults to 0 (Success), change to 1 to flag a failed run. - var speckleProjectDataArg = new Argument( - name: "Speckle project data", - description: "The values of the project / model / version that triggered this function" - ); - var functionInputsArg = new Argument( - name: "Function inputs", - description: "The values provided by the function user, matching the function input schema" - ); - var speckleTokenArg = new Argument( - name: "Speckle token", - description: "A token to talk to the Speckle server with" - ); - var rootCommand = new RootCommand(); - rootCommand.AddArgument(speckleProjectDataArg); - rootCommand.AddArgument(functionInputsArg); - rootCommand.AddArgument(speckleTokenArg); + Argument pathArg = new(name: "Input Path", description: "A file path to retrieve function inputs"); + RootCommand rootCommand = new(); + + rootCommand.AddArgument(pathArg); rootCommand.SetHandler( - async (speckleProjectData, functionInputs, speckleToken) => + async (inputPath) => { - var automationRunData = JsonConvert.DeserializeObject(speckleProjectData); - var functionInputsParsed = JsonConvert.DeserializeObject(functionInputs); + FunctionRunData? data = FunctionRunDataParser.FromPath(inputPath); - var context = await RunFunction(automateFunction, automationRunData, speckleToken, functionInputsParsed) + AutomationContext context = await RunFunction( + automateFunction, + data.AutomationRunData, + data.SpeckleToken, + data.FunctionInputs + ) .ConfigureAwait(false); if (context.RunStatus != AutomationStatusMapping.Get(AutomationStatus.Succeeded)) @@ -124,23 +119,19 @@ public static async Task Main(string[] args, Func( - name: "Function inputs file path", - description: "A token to talk to the Speckle server with" - ); + Argument schemaFilePathArg = + new(name: "Function inputs file path", description: "A token to talk to the Speckle server with"); - var generateSchemaCommand = new Command("generate-schema", "Generate JSON schema for the function inputs"); + Command generateSchemaCommand = new("generate-schema", "Generate JSON schema for the function inputs"); generateSchemaCommand.AddArgument(schemaFilePathArg); generateSchemaCommand.SetHandler( - async (schemaFilePath) => + (schemaFilePath) => { - var generator = new JSchemaGenerator { ContractResolver = new CamelCasePropertyNamesContractResolver() }; - var schema = generator.Generate(typeof(TInput)); + JSchemaGenerator generator = new() { ContractResolver = new CamelCasePropertyNamesContractResolver() }; + JSchema schema = generator.Generate(typeof(TInput)); schema.ToString(global::Newtonsoft.Json.Schema.SchemaVersion.Draft2019_09); File.WriteAllText(schemaFilePath, schema.ToString()); }, diff --git a/Automate/Speckle.Automate.Sdk/Schema/AutomationRunData.cs b/Automate/Speckle.Automate.Sdk/Schema/AutomationRunData.cs index cc74fff330..7dbccab790 100644 --- a/Automate/Speckle.Automate.Sdk/Schema/AutomationRunData.cs +++ b/Automate/Speckle.Automate.Sdk/Schema/AutomationRunData.cs @@ -1,8 +1,7 @@ -# nullable enable namespace Speckle.Automate.Sdk.Schema; /// -///Values of the project, model and automation that triggere this function run. +///Values of the project, model and automation that triggered this function run. /// public struct AutomationRunData { diff --git a/Automate/Speckle.Automate.Sdk/Schema/AutomationStatusMapping.cs b/Automate/Speckle.Automate.Sdk/Schema/AutomationStatusMapping.cs index e4474b114a..fe3f6d9f33 100644 --- a/Automate/Speckle.Automate.Sdk/Schema/AutomationStatusMapping.cs +++ b/Automate/Speckle.Automate.Sdk/Schema/AutomationStatusMapping.cs @@ -2,20 +2,18 @@ namespace Speckle.Automate.Sdk.Schema; public abstract class AutomationStatusMapping { - private const string Initializing = "INITIALIZING"; - private const string Running = "RUNNING"; - private const string Failed = "FAILED"; - private const string Succeeded = "SUCCEEDED"; + private const string INITIALIZING = "INITIALIZING"; + private const string RUNNING = "RUNNING"; + private const string FAILED = "FAILED"; + private const string SUCCEEDED = "SUCCEEDED"; - public static string Get(AutomationStatus status) - { - return status switch + public static string Get(AutomationStatus status) => + status switch { - AutomationStatus.Running => Running, - AutomationStatus.Failed => Failed, - AutomationStatus.Succeeded => Succeeded, - AutomationStatus.Initializing => Initializing, + AutomationStatus.Running => RUNNING, + AutomationStatus.Failed => FAILED, + AutomationStatus.Succeeded => SUCCEEDED, + AutomationStatus.Initializing => INITIALIZING, _ => throw new ArgumentOutOfRangeException($"Not valid value for enum {status}") }; - } } diff --git a/Automate/Speckle.Automate.Sdk/Schema/FunctionRunData.cs b/Automate/Speckle.Automate.Sdk/Schema/FunctionRunData.cs new file mode 100644 index 0000000000..97b8f1e967 --- /dev/null +++ b/Automate/Speckle.Automate.Sdk/Schema/FunctionRunData.cs @@ -0,0 +1,12 @@ +namespace Speckle.Automate.Sdk.Schema; + +/// +/// Required data to run a function. +/// +/// Type for . +public class FunctionRunData +{ + public string SpeckleToken { get; set; } + public AutomationRunData AutomationRunData { get; set; } + public T? FunctionInputs { get; set; } +} diff --git a/Automate/Speckle.Automate.Sdk/Schema/FunctionRunDataParser.cs b/Automate/Speckle.Automate.Sdk/Schema/FunctionRunDataParser.cs new file mode 100644 index 0000000000..b02ea8a318 --- /dev/null +++ b/Automate/Speckle.Automate.Sdk/Schema/FunctionRunDataParser.cs @@ -0,0 +1,44 @@ +using System.Runtime.Serialization; +using Speckle.Newtonsoft.Json; + +namespace Speckle.Automate.Sdk.Schema; + +public static class FunctionRunDataParser +{ + /// + /// Function run data parser from json file path./> + /// + /// Path to retrieve function run data. + /// Type for function inputs. + /// The data to be able run function. + /// Throws if deserialized object is null. + /// Throws unless file exists. + public static FunctionRunData FromPath(string inputLocation) + { + string inputJsonString = ReadInputData(inputLocation); + FunctionRunData? functionRunData = JsonConvert.DeserializeObject>(inputJsonString); + + if (functionRunData is null) + { + throw new SerializationException($"Function run data couldn't deserialized at {inputLocation}"); + } + + return functionRunData; + } + + /// + /// Read text from file. + /// + /// Path to check file is exist. + /// Text in file. + /// Throws unless file exists. + private static string ReadInputData(string inputLocation) + { + if (!File.Exists(inputLocation)) + { + throw new FileNotFoundException($"Cannot find the function inputs file at {inputLocation}"); + } + + return File.ReadAllText(inputLocation); + } +} diff --git a/Automate/Speckle.Automate.Sdk/Schema/ObjectResultLevelMapping.cs b/Automate/Speckle.Automate.Sdk/Schema/ObjectResultLevelMapping.cs index 3668fe65ba..9a35718173 100644 --- a/Automate/Speckle.Automate.Sdk/Schema/ObjectResultLevelMapping.cs +++ b/Automate/Speckle.Automate.Sdk/Schema/ObjectResultLevelMapping.cs @@ -2,18 +2,16 @@ namespace Speckle.Automate.Sdk.Schema; public abstract class ObjectResultLevelMapping { - private const string Info = "INFO"; - private const string Warning = "WARNING"; - private const string Error = "ERROR"; + private const string INFO = "INFO"; + private const string WARNING = "WARNING"; + private const string ERROR = "ERROR"; - public static string Get(ObjectResultLevel level) - { - return level switch + public static string Get(ObjectResultLevel level) => + level switch { - ObjectResultLevel.Error => Error, - ObjectResultLevel.Warning => Warning, - ObjectResultLevel.Info => Info, + ObjectResultLevel.Error => ERROR, + ObjectResultLevel.Warning => WARNING, + ObjectResultLevel.Info => INFO, _ => throw new ArgumentOutOfRangeException($"Not valid value for enum {level}") }; - } } diff --git a/Automate/Speckle.Automate.Sdk/Schema/ObjectResultValues.cs b/Automate/Speckle.Automate.Sdk/Schema/ObjectResultValues.cs index 1fdec07f64..802c77be10 100644 --- a/Automate/Speckle.Automate.Sdk/Schema/ObjectResultValues.cs +++ b/Automate/Speckle.Automate.Sdk/Schema/ObjectResultValues.cs @@ -1,6 +1,6 @@ namespace Speckle.Automate.Sdk.Schema; -struct ObjectResultValues +public struct ObjectResultValues { public List ObjectResults { get; set; } public List BlobIds { get; set; } diff --git a/Automate/Speckle.Automate.Sdk/Schema/ObjectResults.cs b/Automate/Speckle.Automate.Sdk/Schema/ObjectResults.cs index 947c072b0c..d751f7582d 100644 --- a/Automate/Speckle.Automate.Sdk/Schema/ObjectResults.cs +++ b/Automate/Speckle.Automate.Sdk/Schema/ObjectResults.cs @@ -1,7 +1,7 @@ namespace Speckle.Automate.Sdk.Schema; -struct ObjectResults +public struct ObjectResults { - public string Version => "1.0.0"; + public readonly string Version => "1.0.0"; public ObjectResultValues Values { get; set; } } diff --git a/Automate/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj b/Automate/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj index c3f4dc5858..7f4ddca2fc 100644 --- a/Automate/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj +++ b/Automate/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj @@ -1,31 +1,28 @@ + + netstandard2.0 + enable + enable + true + Speckle.Automate.Sdk + Speckle.Automate.Sdk + Speckle Automate SDK + $(PackageTags) speckle automation + Speckle.Automate.Sdk + - - netstandard2.0 - enable - enable - true - Speckle.Automate.Sdk - Speckle.Automate.Sdk - Speckle Automate SDK - $(PackageTags) speckle automation - Speckle.Automate.Sdk - - - - - + + true + - + - - - - - - - + + + + + diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/GetAutomationStatus.cs b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/GetAutomationStatus.cs index 43b8833103..4675ad4934 100644 --- a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/GetAutomationStatus.cs +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/GetAutomationStatus.cs @@ -3,34 +3,34 @@ namespace Speckle.Automate.Sdk.Tests.Integration; -public class FunctionRun +public struct FunctionRun { public string StatusMessage { get; set; } } -public class AutomationRun +public struct AutomationRun { public string Status { get; set; } public IList FunctionRuns { get; set; } } -public class AutomationStatus +public struct AutomationStatus { public string Status { get; set; } public IList AutomationRuns { get; set; } } -public class ModelAutomationStatus +public struct ModelAutomationStatus { public AutomationStatus AutomationStatus { get; set; } } -public class ProjectAutomationStatus +public struct ProjectAutomationStatus { public ModelAutomationStatus Model { get; set; } } -public class AutomationStatusResponseModel +public struct AutomationStatusResponseModel { public ProjectAutomationStatus Project { get; set; } } @@ -80,7 +80,9 @@ query AutomationRuns( """, variables: new { projectId, modelId, } ); - var response = await speckleClient.ExecuteGraphQLRequest(query); + AutomationStatusResponseModel response = await speckleClient.ExecuteGraphQLRequest( + query + ); return response.Project.Model.AutomationStatus; } } diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/README.md b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/README.md new file mode 100644 index 0000000000..6b23101c07 --- /dev/null +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/README.md @@ -0,0 +1,4 @@ +# Automate C# SDK Integration Tests + +Tests are run on server to do GET/POST requests in order to simulate real scenarios. +Before running tests, to be able to run local server follow the instructions [here](https://speckle.guide/dev/server-local-dev.html). diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/Speckle.Automate.Sdk.Tests.Integration.csproj b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/Speckle.Automate.Sdk.Tests.Integration.csproj index 6cbda57ccc..0d5b566f3c 100644 --- a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/Speckle.Automate.Sdk.Tests.Integration.csproj +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/Speckle.Automate.Sdk.Tests.Integration.csproj @@ -7,7 +7,10 @@ false true - $(NoWarn);CA2007 + + + + true @@ -16,7 +19,7 @@ - + diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/SpeckleAutomate.cs b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/SpeckleAutomate.cs index 4960258f35..06888f5c34 100644 --- a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/SpeckleAutomate.cs +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/SpeckleAutomate.cs @@ -1,9 +1,11 @@ +using Newtonsoft.Json; using Speckle.Automate.Sdk.Schema; using Speckle.Core.Api; using Speckle.Core.Credentials; +using Speckle.Core.Logging; using Speckle.Core.Models; +using Speckle.Core.Tests.Integration; using Speckle.Core.Transports; -using TestsIntegration; using Utils = Speckle.Automate.Sdk.Tests.Integration.TestAutomateUtils; namespace Speckle.Automate.Sdk.Tests.Integration; @@ -13,18 +15,16 @@ public sealed class AutomationContextTest : IDisposable { private async Task AutomationRunData(Base testObject) { - string projectId = await client.StreamCreate(new() { name = "Automate function e2e test" }); - const string branchName = "main"; + string projectId = await _client.StreamCreate(new() { name = "Automate function e2e test" }); + const string BRANCH_NAME = "main"; - Branch model = await client.BranchGet(projectId, branchName, 1); + Branch model = await _client.BranchGet(projectId, BRANCH_NAME, 1); string modelId = model.id; - string rootObjId = await Operations.Send( - testObject, - new List { new ServerTransport(client.Account, projectId) } - ); + using ServerTransport remoteTransport = new(_client.Account, projectId); + string rootObjId = await Operations.Send(testObject, remoteTransport, false); - string versionId = await client.CommitCreate( + string versionId = await _client.CommitCreate( new() { streamId = projectId, @@ -33,24 +33,24 @@ private async Task AutomationRunData(Base testObject) } ); - var automationName = Utils.RandomString(10); - var automationId = Utils.RandomString(10); - var automationRevisionId = Utils.RandomString(10); + string automationName = Utils.RandomString(10); + string automationId = Utils.RandomString(10); + string automationRevisionId = Utils.RandomString(10); - await Utils.RegisterNewAutomation(projectId, modelId, client, automationId, automationName, automationRevisionId); + await Utils.RegisterNewAutomation(projectId, modelId, _client, automationId, automationName, automationRevisionId); - var automationRunId = Utils.RandomString(10); - var functionId = Utils.RandomString(10); - var functionName = "Automation name " + Utils.RandomString(10); - var functionRelease = Utils.RandomString(10); + string automationRunId = Utils.RandomString(10); + string functionId = Utils.RandomString(10); + string functionName = "Automation name " + Utils.RandomString(10); + string functionRelease = Utils.RandomString(10); return new AutomationRunData { ProjectId = projectId, ModelId = modelId, - BranchName = branchName, + BranchName = BRANCH_NAME, VersionId = versionId, - SpeckleServerUrl = client.ServerUrl, + SpeckleServerUrl = _client.ServerUrl, AutomationId = automationId, AutomationRevisionId = automationRevisionId, AutomationRunId = automationRunId, @@ -60,46 +60,58 @@ private async Task AutomationRunData(Base testObject) }; } - private Client client; - private Account account; + private Client _client; + private Account _account; [OneTimeSetUp] public async Task Setup() { - account = await Fixtures.SeedUser().ConfigureAwait(false); - client = new Client(account); + _account = await Fixtures.SeedUser().ConfigureAwait(false); + _client = new Client(_account); } [Test] public async Task TestFunctionRun() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationRunner.RunFunction( + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationRunner.RunFunction( TestAutomateFunction.Run, automationRunData, - account.token, + _account.token, new TestFunctionInputs { ForbiddenSpeckleType = "Base" } ); Assert.That(automationContext.RunStatus, Is.EqualTo("FAILED")); - var status = await AutomationStatusOperations.Get( + AutomationStatus status = await AutomationStatusOperations.Get( automationRunData.ProjectId, automationRunData.ModelId, automationContext.SpeckleClient ); Assert.That(status.Status, Is.EqualTo(automationContext.RunStatus)); - var statusMessage = status.AutomationRuns[0].FunctionRuns[0].StatusMessage; + string statusMessage = status.AutomationRuns[0].FunctionRuns[0].StatusMessage; Assert.That(statusMessage, Is.EqualTo(automationContext.AutomationResult.StatusMessage)); } + [Test] + public void TestParseInputData() + { + TestFunctionInputs testFunctionInputs = new() { ForbiddenSpeckleType = "Base" }; + FunctionRunData functionRunData = new() { FunctionInputs = testFunctionInputs }; + string serializedFunctionRunData = JsonConvert.SerializeObject(functionRunData); + File.WriteAllText("./inputData.json", serializedFunctionRunData); + FunctionRunData? data = FunctionRunDataParser.FromPath("./inputData.json"); + + Assert.AreEqual("Base", data.FunctionInputs.ForbiddenSpeckleType); + } + [Test] public async Task TestFileUploads() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); string filePath = $"./{Utils.RandomString(10)}"; await File.WriteAllTextAsync(filePath, "foobar"); @@ -120,59 +132,59 @@ public async Task TestFileUploads() [Test] public async Task TestCreateVersionInProject() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); - const string branchName = "test-branch"; - const string commitMsg = "automation test"; + const string BRANCH_NAME = "test-branch"; + const string COMMIT_MSG = "automation test"; - await automationContext.CreateNewVersionInProject(Utils.TestObject(), branchName, commitMsg); + await automationContext.CreateNewVersionInProject(Utils.TestObject(), BRANCH_NAME, COMMIT_MSG); - var branch = await automationContext.SpeckleClient - .BranchGet(automationRunData.ProjectId, branchName, 1) + Branch branch = await automationContext.SpeckleClient + .BranchGet(automationRunData.ProjectId, BRANCH_NAME, 1) .ConfigureAwait(false); Assert.NotNull(branch); - Assert.That(branch.name, Is.EqualTo(branchName)); - Assert.That(branch.commits.items[0].message, Is.EqualTo(commitMsg)); + Assert.That(branch.name, Is.EqualTo(BRANCH_NAME)); + Assert.That(branch.commits.items[0].message, Is.EqualTo(COMMIT_MSG)); } [Test] public async Task TestCreateVersionInProject_ThrowsErrorForSameModel() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); - var branchName = automationRunData.BranchName; - const string commitMsg = "automation test"; + string branchName = automationRunData.BranchName; + const string COMMIT_MSG = "automation test"; Assert.ThrowsAsync(async () => { - await automationContext.CreateNewVersionInProject(Utils.TestObject(), branchName, commitMsg); + await automationContext.CreateNewVersionInProject(Utils.TestObject(), branchName, COMMIT_MSG); }); } [Test] public async Task TestSetContextView() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); automationContext.SetContextView(); Assert.That(automationContext.AutomationResult.ResultView, Is.Not.Null); string originModelView = $"{automationRunData.ModelId}@{automationRunData.VersionId}"; - Assert.That(automationContext.AutomationResult.ResultView.EndsWith($"models/{originModelView}"), Is.True); + Assert.That(automationContext.AutomationResult.ResultView?.EndsWith($"models/{originModelView}"), Is.True); await automationContext.ReportRunStatus(); - var dummyContext = "foo@bar"; + string dummyContext = "foo@bar"; automationContext.AutomationResult.ResultView = null; automationContext.SetContextView(new List { dummyContext }, true); Assert.That(automationContext.AutomationResult.ResultView, Is.Not.Null); Assert.That( - automationContext.AutomationResult.ResultView.EndsWith($"models/{originModelView},{dummyContext}"), + automationContext.AutomationResult.ResultView?.EndsWith($"models/{originModelView},{dummyContext}"), Is.True ); @@ -182,13 +194,13 @@ public async Task TestSetContextView() automationContext.SetContextView(new List { dummyContext }, false); Assert.That(automationContext.AutomationResult.ResultView, Is.Not.Null); - Assert.That(automationContext.AutomationResult.ResultView.EndsWith($"models/{dummyContext}"), Is.True); + Assert.That(automationContext.AutomationResult.ResultView?.EndsWith($"models/{dummyContext}"), Is.True); await automationContext.ReportRunStatus(); automationContext.AutomationResult.ResultView = null; - Assert.Throws(() => + Assert.Throws(() => { automationContext.SetContextView(null, false); }); @@ -199,8 +211,8 @@ public async Task TestSetContextView() [Test] public async Task TestReportRunStatus_Succeeded() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); Assert.That(automationContext.RunStatus, Is.EqualTo(AutomationStatusMapping.Get(Schema.AutomationStatus.Running))); @@ -215,20 +227,17 @@ public async Task TestReportRunStatus_Succeeded() [Test] public async Task TestReportRunStatus_Failed() { - var automationRunData = await AutomationRunData(Utils.TestObject()); - var automationContext = await AutomationContext.Initialize(automationRunData, account.token); + AutomationRunData automationRunData = await AutomationRunData(Utils.TestObject()); + AutomationContext automationContext = await AutomationContext.Initialize(automationRunData, _account.token); Assert.That(automationContext.RunStatus, Is.EqualTo(AutomationStatusMapping.Get(Schema.AutomationStatus.Running))); - var message = "This is a failure message"; + string message = "This is a failure message"; automationContext.MarkRunFailed(message); Assert.That(automationContext.RunStatus, Is.EqualTo(AutomationStatusMapping.Get(Schema.AutomationStatus.Failed))); Assert.That(automationContext.StatusMessage, Is.EqualTo(message)); } - public void Dispose() - { - client.Dispose(); - } + public void Dispose() => _client.Dispose(); } diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateFunction.cs b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateFunction.cs index 5fadf2cbe6..a26e5ff38a 100644 --- a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateFunction.cs +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateFunction.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using Speckle.Core.Models; namespace Speckle.Automate.Sdk.Tests.Integration; @@ -12,7 +13,7 @@ public static class TestAutomateFunction { public static async Task Run(AutomationContext automateContext, TestFunctionInputs testFunctionInputs) { - var versionRootObject = await automateContext.ReceiveVersion(); + Base versionRootObject = await automateContext.ReceiveVersion(); int count = 0; if (versionRootObject.speckle_type == testFunctionInputs.ForbiddenSpeckleType) diff --git a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateUtils.cs b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateUtils.cs index 80fb5326cc..081259cdff 100644 --- a/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateUtils.cs +++ b/Automate/Tests/Speckle.Automate.Sdk.Tests.Integration/TestAutomateUtils.cs @@ -11,8 +11,8 @@ public static class TestAutomateUtils public static string RandomString(int length) { Random rand = new(); - const string pool = "abcdefghijklmnopqrstuvwxyz0123456789"; - var chars = Enumerable.Range(0, length).Select(_ => pool[rand.Next(0, pool.Length)]); + const string POOL = "abcdefghijklmnopqrstuvwxyz0123456789"; + IEnumerable chars = Enumerable.Range(0, length).Select(_ => POOL[rand.Next(0, POOL.Length)]); return new string(chars.ToArray()); } diff --git a/ConnectorArchicad/AddOn/CMakeLists.txt b/ConnectorArchicad/AddOn/CMakeLists.txt index af7a1304fd..c2162a0cad 100644 --- a/ConnectorArchicad/AddOn/CMakeLists.txt +++ b/ConnectorArchicad/AddOn/CMakeLists.txt @@ -1,7 +1,11 @@ cmake_minimum_required (VERSION 3.16) -function (SetCompilerOptions target) - target_compile_features (${target} PUBLIC cxx_std_14) +function (SetCompilerOptions target ac_version) + if (${ac_version} LESS "27") + target_compile_features (${target} PUBLIC cxx_std_14) + else () + target_compile_features (${target} PUBLIC cxx_std_17) + endif () target_compile_options (${target} PUBLIC "$<$:-DDEBUG>") if (WIN32) target_compile_options (${target} PUBLIC /W4 /WX @@ -19,12 +23,12 @@ function (SetCompilerOptions target) -Wno-ignored-qualifiers -Wno-reorder -Wno-overloaded-virtual + -Wno-missing-braces -Wno-unused-parameter -Wno-deprecated # HashTable.hpp:1752 error: 'sprintf' is deprecated -Wno-unknown-pragmas - -Wno-missing-braces - -Wno-unused-private-field -Wno-shorten-64-to-32 # BrepExternalBufferArray.hpp:34: error: implicit conversion loses integer precision: 'long long' to 'const GS::USize' (aka 'const unsigned int') + -Wno-unused-private-field ) endif () endfunction () @@ -57,7 +61,6 @@ set (AC_ADDON_LANGUAGE "INT" CACHE STRING "Add-On language code.") set (AC_MDID_DEV "1" CACHE STRING "Your Developer ID") set (AC_MDID_LOC "1" CACHE STRING "Add-On Local ID") - set (ACAPINC_FILE_LOCATION ${AC_API_DEVKIT_DIR}/Support/Inc/ACAPinc.h) if (EXISTS ${ACAPINC_FILE_LOCATION}) file (READ ${ACAPINC_FILE_LOCATION} ACAPIncContent) @@ -72,6 +75,9 @@ if (WIN32) add_definitions (-DUNICODE -D_UNICODE) else () add_definitions (-Dmacintosh=1) + if (${ARCHICAD_VERSION} GREATER_EQUAL "26") + set (CMAKE_OSX_ARCHITECTURES "x86_64;arm64" PARENT_SCOPE CACHE STRING "" FORCE) + endif () endif () add_definitions (-DACExtension) @@ -187,20 +193,35 @@ target_include_directories (AddOn PUBLIC ) if (WIN32) - target_link_libraries (AddOn - "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STATD.lib>" - "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STAT.lib>" - "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STAT.lib>" - ) + if (${ARCHICAD_VERSION} LESS "27") + target_link_libraries (AddOn + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STATD.lib>" + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STAT.lib>" + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/Win/ACAP_STAT.lib>" + ) + else () + target_link_libraries (AddOn + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/ACAP_STATD.lib>" + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/ACAP_STAT.lib>" + "$<$:${AC_API_DEVKIT_DIR}/Support/Lib/ACAP_STAT.lib>" + ) + endif () else () find_library (CocoaFramework Cocoa) - target_link_libraries (AddOn - "${AC_API_DEVKIT_DIR}/Support/Lib/Mactel/libACAP_STAT.a" - ${CocoaFramework} - ) + if (${ARCHICAD_VERSION} LESS "27") + target_link_libraries (AddOn + "${AC_API_DEVKIT_DIR}/Support/Lib/Mactel/libACAP_STAT.a" + ${CocoaFramework} + ) + else () + target_link_libraries (AddOn + "${AC_API_DEVKIT_DIR}/Support/Lib/libACAP_STAT.a" + ${CocoaFramework} + ) + endif () endif () -SetCompilerOptions (AddOn) +SetCompilerOptions (AddOn ARCHICAD_VERSION) set_source_files_properties (${AddOnSourceFiles} PROPERTIES LANGUAGE CXX) file (GLOB ModuleFolders ${AC_API_DEVKIT_DIR}/Support/Modules/*) diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/APIMigrationHelper.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/APIMigrationHelper.hpp new file mode 100644 index 0000000000..1e7c700596 --- /dev/null +++ b/ConnectorArchicad/AddOn/Sources/AddOn/APIMigrationHelper.hpp @@ -0,0 +1,151 @@ +#pragma once + +#include + +// Renamed functions in Archicad 27 + +#ifndef ServerMainVers_2700 + +// API functions +#define ACAPI_Element_GetElemTypeName ACAPI_Goodies_GetElemTypeName + +#define ACAPI_Grouping_GetConnectedElements ACAPI_Element_GetConnectedElements + +#define ACAPI_Selection_Select ACAPI_Element_Select +#define ACAPI_Selection_DeselectAll ACAPI_Element_DeselectAll + +#define ACAPI_AddOnAddOnCommunication_CallFromEventLoop ACAPI_Command_CallFromEventLoop +#define ACAPI_AddOnAddOnCommunication_Test ACAPI_Command_Test +#define ACAPI_AddOnAddOnCommunication_Call ACAPI_Command_Call +#define ACAPI_AddOnAddOnCommunication_RegisterSupportedService ACAPI_Register_SupportedService +#define ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler ACAPI_Install_AddOnCommandHandler + +#define ACAPI_UserInput_SetElementHighlight ACAPI_Interface_SetElementHighlight +#define ACAPI_UserInput_ClearElementHighlight ACAPI_Interface_ClearElementHighlight + +#define ACAPI_Dialog_CreateAttributePicker ACAPI_Interface_CreateAttributePicker + +#define ACAPI_Category_GetCategoryValue ACAPI_Element_GetCategoryValue +#define ACAPI_Category_GetCategoryValueDefault ACAPI_Element_GetCategoryValueDefault + +#define ACAPI_LibraryPart_GetNum ACAPI_LibPart_GetNum +#define ACAPI_LibraryPart_Search ACAPI_LibPart_Search +#define ACAPI_LibraryPart_Create ACAPI_LibPart_Create +#define ACAPI_LibraryPart_NewSection ACAPI_LibPart_NewSection +#define ACAPI_LibraryPart_WriteSection ACAPI_LibPart_WriteSection +#define ACAPI_LibraryPart_EndSection ACAPI_LibPart_EndSection +#define ACAPI_LibraryPart_SetDetails_ParamDef ACAPI_LibPart_SetDetails_ParamDef +#define ACAPI_LibraryPart_Get ACAPI_LibPart_Get +#define ACAPI_LibraryPart_GetParams ACAPI_LibPart_GetParams +#define ACAPI_LibraryPart_GetSect_ParamDef ACAPI_LibPart_GetSect_ParamDef +#define ACAPI_LibraryPart_AddSection ACAPI_LibPart_AddSection +#define ACAPI_LibraryPart_Register ACAPI_LibPart_Register +#define ACAPI_LibraryPart_Save ACAPI_LibPart_Save + +#define ACAPI_Sight_GetCurrentWindowSight ACAPI_3D_GetCurrentWindowSight + +#define ACAPI_MenuItem_RegisterMenu ACAPI_Register_Menu +#define ACAPI_MenuItem_InstallMenuHandler ACAPI_Install_MenuHandler + +#define ACAPI_ProjectOperation_CatchProjectEvent ACAPI_Notify_CatchProjectEvent + +#define ACAPI_Notification_CatchSelectionChange ACAPI_Notify_CatchSelectionChange +#define ACAPI_Notification_RegisterEventHandler ACAPI_Notify_RegisterEventHandler + +#define ACAPI_AddOnIntegration_RegisterFileType ACAPI_Register_FileType +#define ACAPI_AddOnIntegration_InstallFileTypeHandler3D ACAPI_Install_FileTypeHandler3D +#define ACAPI_AddOnIntegration_InstallModulCommandHandler ACAPI_Install_ModulCommandHandler + +#define ACAPI_Licensing_GetProtectionMode ACAPI_Protection_GetProtectionMode +#define ACAPI_Licensing_GetSerialNumber ACAPI_Protection_GetSerialNumber +#define ACAPI_Licensing_GetBoxMask ACAPI_Protection_GetBoxMask +#define ACAPI_Licensing_GetConfigurationNumber ACAPI_Protection_GetConfigurationNumber +#define ACAPI_Licensing_GetNumberOfLicenses ACAPI_Protection_GetNumberOfLicenses +#define ACAPI_Licensing_GetPartnerId ACAPI_Protection_GetPartnerId + +#define ACAPI_AddOnIntegration_RegisterModulDataHandler ACAPI_Register_ModulDataHandler +#define ACAPI_AddOnIntegration_InstallModulDataSaveOldFormatHandler ACAPI_Install_ModulDataSaveOldFormatHandler +#define ACAPI_AddOnIntegration_InstallModulDataMergeHandler ACAPI_Install_ModulDataMergeHandler + +#define ACAPI_MenuItem_GetMenuItemFlags(par1, par2) (ACAPI_Interface (APIIo_GetMenuItemFlagsID, par1, par2)) +#define ACAPI_MenuItem_SetMenuItemFlags(par1, par2) (ACAPI_Interface (APIIo_SetMenuItemFlagsID, par1, par2)) +#define ACAPI_UserInput_GetPoint(par1, par2) (ACAPI_Interface (APIIo_GetPointID, par1, par2)) + +#define ACAPI_View_ShowAllIn3D() (ACAPI_Automate (APIDo_ShowAllIn3DID)) +#define ACAPI_View_Rebuild() (ACAPI_Automate (APIDo_RebuildID)) +#define ACAPI_View_ZoomToSelected() (ACAPI_Automate (APIDo_ZoomToSelectedID)) +#define ACAPI_View_GoToView(par1) (ACAPI_Automate (APIDo_GoToViewID, (void*)(par1))) +#define ACAPI_ProjectOperation_Open(par1) (ACAPI_Automate (APIDo_OpenID, (void*)(par1))) +#define ACAPI_ProjectOperation_Save(par1, par2) (ACAPI_Automate (APIDo_SaveID, (void*)(par1), (void*)(par2))) +#define ACAPI_Window_ChangeWindow(par1) (ACAPI_Automate (APIDo_ChangeWindowID, (void*)(par1))) +#define ACAPI_View_ShowSelectionIn3D() (ACAPI_Automate (APIDo_ShowSelectionIn3DID)) + +#define ACAPI_LibraryManagement_OverwriteLibPart(par1) (ACAPI_Environment (APIEnv_OverwriteLibPartID, (void*)(par1), nullptr)) +#define ACAPI_LibraryManagement_GetLibraries(par1, par2) (ACAPI_Environment (APIEnv_GetLibrariesID, (void*)(par1), (void*)(par2))) +#define ACAPI_LibraryManagement_SetLibraries(par1) (ACAPI_Environment (APIEnv_SetLibrariesID, (void*)(par1))) +#define ACAPI_ProjectOperation_Project(par1) (ACAPI_Environment (APIEnv_ProjectID, (void*)(par1))) +#define ACAPI_ProjectSetting_GetStorySettings(par1) (ACAPI_Environment (APIEnv_GetStorySettingsID, (void*)(par1))) +#define ACAPI_ProjectSetting_ChangeStorySettings(par1) (ACAPI_Environment (APIEnv_ChangeStorySettingsID, (void*)(par1))) +#define ACAPI_ProjectSetting_GetPreferences(par1, par2) (ACAPI_Environment (APIEnv_GetPreferencesID, (void*)(par1), (void*)(par2))) +#define ACAPI_ProjectSettings_GetSpecFolder(par1, par2) (ACAPI_Environment (APIEnv_GetSpecFolderID, (void*)(par1), (void*)(par2))) +#define ACAPI_SurveyPoint_GetSurveyPointTransformation(par1) (ACAPI_Environment (APIEnv_GetSurveyPointTransformationID, (void*)(par1))) +#define ACAPI_View_Get3DProjectionSets(par1) (ACAPI_Environment (APIEnv_Get3DProjectionSetsID, (void*)(par1))) +#define ACAPI_View_Change3DProjectionSets(par1) (ACAPI_Environment (APIEnv_Change3DProjectionSetsID, (void*)(par1))) +#define ACAPI_View_Get3DImageSets(par1) (ACAPI_Environment (APIEnv_Get3DImageSetsID, (void*)(par1))) +#define ACAPI_View_Get3DCuttingPlanes(par1) (ACAPI_Environment (APIEnv_Get3DCuttingPlanesID, (void*)(par1), nullptr)) +#define ACAPI_View_Change3DCuttingPlanes(par1) (ACAPI_Environment (APIEnv_Change3DCuttingPlanesID, (void*)(par1), nullptr)) + +#define ACAPI_Window_GetCurrentWindow(par1) (ACAPI_Database (APIDb_GetCurrentWindowID, (void*)(par1))) +#define ACAPI_Database_GetCurrentDatabase(par1) (ACAPI_Database (APIDb_GetCurrentDatabaseID, (void*)(par1))) +#define ACAPI_Database_ChangeCurrentDatabase(par1) (ACAPI_Database (APIDb_ChangeCurrentDatabaseID, (void*)(par1))) + +#define ACAPI_Command_GetHttpConnectionPort(par1) (ACAPI_Goodies (APIAny_GetHttpConnectionPortID, (void*)(par1))) +#define ACAPI_LibraryPart_GetMarkerParent(par1, par2) (ACAPI_Goodies_GetMarkerParent ((par1),(par2))) + +#define ACAPI_Navigator_GetNavigatorItem(par1, par2) (ACAPI_Navigator (APINavigator_GetNavigatorItemID, (void*)(par1), (void*)(par2))) + +// API_OverriddenAttribute +#define IsAPIOverriddenAttributeOverridden(par) (par.overridden) +#define GetAPIOverriddenAttribute(par) par.attributeIndex +#define SetAPIOverriddenAttribute(par1, par2) (par1.overridden = true, par1.attributeIndex = par2) +#define ResetAPIOverriddenAttribute(par) (par.overridden = false) +#define GetAPIOverriddenAttributeIndexField(par) par.attributeIndex +#define GetAPIOverriddenAttributeBoolField(par) par.overridden + +// JSON +#include "DGModule.hpp" + +#define JSONBase DG::JSBase +#define JSONObject DG::JSObject +#define JSONFunction DG::JSFunction +#define JSONValue DG::JSValue +#define JSONArray DG::JSArray + +#else + +// API_OverriddenAttribute +#define IsAPIOverriddenAttributeOverridden(par) (par.hasValue) +#define GetAPIOverriddenAttribute(par) par.value +#define SetAPIOverriddenAttribute(par1, par2) (par1 = par2) +#define ResetAPIOverriddenAttribute(par) (par = APINullValue) +#define GetAPIOverriddenAttributeIndexField(par) par +#define GetAPIOverriddenAttributeBoolField(par) par + +// JSON +#include "JavascriptEngine.hpp" + +#define JSONBase JS::Base +#define JSONObject JS::Object +#define JSONFunction JS::Function +#define JSONValue JS::Value +#define JSONArray JS::Array + +#endif + +// New constants in Archicad 27 + +#ifndef ServerMainVers_2700 + +#define APIApplicationLayerAttributeIndex 1 + +#endif diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp index ae51e406e4..532f056af6 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp @@ -1,5 +1,6 @@ #include "APIEnvir.h" #include "ACAPinc.h" +#include "APIMigrationHelper.hpp" #include "DGModule.hpp" #include "Process.hpp" @@ -22,7 +23,6 @@ #include "Commands/GetShellData.hpp" #include "Commands/GetSkylightData.hpp" #include "Commands/GetProjectInfo.hpp" -#include "Commands/GetSubElementInfo.hpp" #include "Commands/GetZoneData.hpp" #include "Commands/CreateWall.hpp" #include "Commands/CreateDoor.hpp" @@ -143,7 +143,7 @@ class AvaloniaProcessManager { { UShort portNumber = 0; { - const auto err = ACAPI_Goodies (APIAny_GetHttpConnectionPortID, &portNumber); + const auto err = ACAPI_Command_GetHttpConnectionPort (&portNumber); if (err != NoError) { throw GS::IllegalArgumentException (); @@ -189,39 +189,38 @@ static GSErrCode MenuCommandHandler (const API_MenuParams* menuParams) static GSErrCode RegisterAddOnCommands () { - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); - CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); + CHECKERROR (ACAPI_AddOnAddOnCommunication_InstallAddOnCommandHandler (NewOwned ())); return NoError; } @@ -242,7 +241,7 @@ API_AddonType __ACDLL_CALL CheckEnvironment (API_EnvirParams* envir) GSErrCode __ACDLL_CALL RegisterInterface (void) { - return ACAPI_Register_Menu (AddOnMenuID, 0, MenuCode_Interoperability, MenuFlag_Default); + return ACAPI_MenuItem_RegisterMenu (AddOnMenuID, 0, MenuCode_Interoperability, MenuFlag_Default); } @@ -250,7 +249,7 @@ GSErrCode __ACENV_CALL Initialize (void) { CHECKERROR (RegisterAddOnCommands ()); - return ACAPI_Install_MenuHandler (AddOnMenuID, MenuCommandHandler); + return ACAPI_MenuItem_InstallMenuHandler (AddOnMenuID, MenuCommandHandler); } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CommandHelpers.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CommandHelpers.hpp new file mode 100644 index 0000000000..232b1f28dd --- /dev/null +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CommandHelpers.hpp @@ -0,0 +1,84 @@ +#ifndef CREATE_COMMAND_HELPERS_HPP +#define CREATE_COMMAND_HELPERS_HPP + +#include "APIEnvir.h" +#include "ACAPinc.h" +#include "APIMigrationHelper.hpp" +#include "ObjectState.hpp" + +namespace AddOnCommands { + +namespace CommandHelpers { + +template +GSErrCode GetCutfillPens (const T& element, GS::ObjectState& os, const GS::String& cutfillPenName, const GS::String& backgroundCutfillPenName) +{ + // Override cut fill pen +#ifdef ServerMainVers_2700 + if (element.cutFillPen.hasValue) { + os.Add (cutfillPenName, element.cutFillPen.value); + } +#else + if (element.penOverride.overrideCutFillPen) { + os.Add (cutfillPenName, element.penOverride.cutFillPen); + } +#endif + // Override cut fill background pen +#ifdef ServerMainVers_2700 + if (element.cutFillBackgroundPen.hasValue) { + os.Add (backgroundCutfillPenName, element.cutFillBackgroundPen.value); +} +#else + if (element.penOverride.overrideCutFillBackgroundPen) { + os.Add (backgroundCutfillPenName, element.penOverride.cutFillBackgroundPen); + } +#endif + return NoError; +} + +template +static GSErrCode SetCutfillPens(const GS::ObjectState& os, + const GS::String& cutFillPenIndexField, + const GS::String& cutFillBackgroundPenIndexField, + T& element, + API_Element& mask) +{ + // Override cut fill pen +#ifdef ServerMainVers_2700 + element.cutFillPen = APINullValue; + ACAPI_ELEMENT_MASK_SET (mask, T, cutFillPen); + if (os.Contains (cutFillPenIndexField)) { + os.Get (cutFillPenIndexField, element.cutFillPen.value); + } +#else + element.penOverride.overrideCutFillPen = false; + ACAPI_ELEMENT_MASK_SET (mask, T, penOverride.overrideCutFillPen); + if (os.Contains (cutFillPenIndexField)) { + element.penOverride.overrideCutFillPen = true; + os.Get (cutFillPenIndexField, element.penOverride.cutFillPen); + ACAPI_ELEMENT_MASK_SET (mask, T, penOverride.cutFillPen); + } +#endif + + // Override cut fill backgound pen +#ifdef ServerMainVers_2700 + element.cutFillBackgroundPen = APINullValue; + ACAPI_ELEMENT_MASK_SET (mask, T, cutFillBackgroundPen); + if (os.Contains (cutFillBackgroundPenIndexField)) { + os.Get (cutFillBackgroundPenIndexField, element.cutFillBackgroundPen.value); + } +#else + element.penOverride.overrideCutFillBackgroundPen = false; + ACAPI_ELEMENT_MASK_SET (mask, T, penOverride.overrideCutFillBackgroundPen); + if (os.Contains (cutFillBackgroundPenIndexField)) { + element.penOverride.overrideCutFillBackgroundPen = true; + os.Get (cutFillBackgroundPenIndexField, element.penOverride.cutFillBackgroundPen); + ACAPI_ELEMENT_MASK_SET (mask, T, penOverride.cutFillBackgroundPen); + } +#endif + return NoError; +} +} +} + +#endif diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateBeam.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateBeam.cpp index 49ab23ff50..21bd26a0be 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateBeam.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateBeam.cpp @@ -1,677 +1,663 @@ -#include "CreateBeam.hpp" -#include "ResourceIds.hpp" -#include "ObjectState.hpp" -#include "Utility.hpp" -#include "Objects/Level.hpp" -#include "Objects/Point.hpp" -#include "FieldNames.hpp" -#include "TypeNameTables.hpp" -using namespace FieldNames; - -namespace AddOnCommands { - - -GS::String CreateBeam::GetFieldName () const -{ - return FieldNames::Beams; -} - - -GS::UniString CreateBeam::GetUndoableCommandName () const -{ - return "CreateSpeckleBeam"; -} - - -GSErrCode CreateBeam::GetElementFromObjectState (const GS::ObjectState& os, - API_Element& element, - API_Element& beamMask, - API_ElementMemo& memo, - GS::UInt64& memoMask, - API_SubElement** /*marker*/, - AttributeManager& /*attributeManager*/, - LibpartImportManager& /*libpartImportManager*/, - GS::Array& log) const -{ - GSErrCode err = NoError; - - Utility::SetElementType (element.header, API_BeamID); - err = Utility::GetBaseElementData (element, &memo, nullptr, log); - if (err != NoError) - return err; - - err = GetElementBaseFromObjectState (os, element, beamMask); - if (err != NoError) - return err; - - // Positioning - Objects::Point3D startPoint; - if (os.Contains (Beam::begC)) { - os.Get (Beam::begC, startPoint); - element.beam.begC = startPoint.ToAPI_Coord (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, begC); - } - - Objects::Point3D endPoint; - if (os.Contains (Beam::endC)) { - os.Get (Beam::endC, endPoint); - element.beam.endC = endPoint.ToAPI_Coord (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, endC); - } - - - if (os.Contains (ElementBase::Level)) { - GetStoryFromObjectState (os, startPoint.z, element.header.floorInd, element.beam.offset); - } else { - Utility::SetStoryLevelAndFloor (startPoint.z, element.header.floorInd, element.beam.offset); - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_Elem_Head, floorInd); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, offset); - - if (os.Contains (Beam::level)) { - os.Get (Beam::level, element.beam.level); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, level); - } - - if (os.Contains (Beam::isSlanted)) { - os.Get (Beam::isSlanted, element.beam.isSlanted); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isSlanted); - } - - if (os.Contains (Beam::slantAngle)) { - os.Get (Beam::slantAngle, element.beam.slantAngle); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, slantAngle); - } - - if (os.Contains (Beam::beamShape)) { - API_BeamShapeTypeID realBeamShapeType = API_StraightBeam; - GS::UniString beamShapeName; - os.Get (Beam::beamShape, beamShapeName); - - GS::Optional tmpBeamShapeType = beamShapeTypeNames.FindValue (beamShapeName); - if (tmpBeamShapeType.HasValue ()) - realBeamShapeType = tmpBeamShapeType.Get (); - element.beam.beamShape = realBeamShapeType; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, beamShape); - } - - if (os.Contains (Beam::sequence)) { - os.Get (Beam::sequence, element.beam.sequence); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, sequence); - } - - if (os.Contains (Beam::curveAngle)) { - os.Get (Beam::curveAngle, element.beam.curveAngle); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, curveAngle); - } - - if (os.Contains (Beam::verticalCurveHeight)) { - os.Get (Beam::verticalCurveHeight, element.beam.verticalCurveHeight); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, verticalCurveHeight); - } - - if (os.Contains (Beam::isFlipped)) { - os.Get (Beam::isFlipped, element.beam.isFlipped); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isFlipped); - } - - // End Cuts - if (os.Contains (Beam::nCuts)) { - os.Get (Beam::nCuts, element.beam.nCuts); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nCuts); - } - - Utility::CreateAllCutData (os, element.beam.nCuts, element, beamMask, &memo); - - // Reference Axis - if (os.Contains (Beam::anchorPoint)) { - os.Get (Beam::anchorPoint, element.beam.anchorPoint); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, anchorPoint); - } - - if (os.Contains (Beam::offset)) { - os.Get (Beam::offset, element.beam.offset); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, offset); - } - - if (os.Contains (Beam::profileAngle)) { - os.Get (Beam::profileAngle, element.beam.profileAngle); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, profileAngle); - } - - // Segment - if (os.Contains (Beam::nSegments)) { - os.Get (Beam::nSegments, element.beam.nSegments); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nSegments); - } - - if (os.Contains (Beam::nProfiles)) { - os.Get (Beam::nProfiles, element.beam.nProfiles); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nProfiles); - } - -#pragma region Segment - GS::ObjectState allSegments; - if (os.Contains (Beam::segments)) - os.Get (Beam::segments, allSegments); - - if (!allSegments.IsEmpty ()) { - API_BeamSegmentType defaultBeamSegment; - if (memo.beamSegments != nullptr) { - defaultBeamSegment = memo.beamSegments[0]; - memo.beamSegments = (API_BeamSegmentType*) BMAllocatePtr ((element.beam.nSegments) * sizeof (API_BeamSegmentType), ALLOCATE_CLEAR, 0); - } else { - return Error; - } - - memoMask = APIMemoMask_BeamSegment | - APIMemoMask_AssemblySegmentScheme | - APIMemoMask_BeamHole | - APIMemoMask_AssemblySegmentCut; - - for (UInt32 idx = 0; idx < element.beam.nSegments; ++idx) { - GS::ObjectState currentSegment; - allSegments.Get (GS::String::SPrintf (AssemblySegment::SegmentName, idx + 1), currentSegment); - - if (!currentSegment.IsEmpty ()) { - - memo.beamSegments[idx] = defaultBeamSegment; - GS::ObjectState assemblySegment; - currentSegment.Get (Beam::BeamSegment::segmentData, assemblySegment); - Utility::CreateOneSegmentData (assemblySegment, memo.beamSegments[idx].assemblySegmentData, beamMask); - - // The left overridden material name - in case of circle or profiled segment the left surface is the extrusion surface, but the import does not work properly in API - memo.beamSegments[idx].leftMaterial.overridden = false; - if (currentSegment.Contains (Beam::BeamSegment::LeftMaterial)) { - memo.beamSegments[idx].leftMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Beam::BeamSegment::LeftMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) { - memo.beamSegments[idx].leftMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, leftMaterial.attributeIndex); - } - } - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, leftMaterial.overridden); - - // The top overridden material name - memo.beamSegments[idx].topMaterial.overridden = false; - if (currentSegment.Contains (Beam::BeamSegment::TopMaterial)) { - memo.beamSegments[idx].topMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Beam::BeamSegment::TopMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) { - memo.beamSegments[idx].topMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, topMaterial.attributeIndex); - } - } - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, topMaterial.overridden); - - // The right overridden material name - memo.beamSegments[idx].rightMaterial.overridden = false; - if (currentSegment.Contains (Beam::BeamSegment::RightMaterial)) { - memo.beamSegments[idx].rightMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Beam::BeamSegment::RightMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) { - memo.beamSegments[idx].rightMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, rightMaterial.attributeIndex); - } - } - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, rightMaterial.overridden); - - // The bottom overridden material name - memo.beamSegments[idx].bottomMaterial.overridden = false; - if (currentSegment.Contains (Beam::BeamSegment::BottomMaterial)) { - memo.beamSegments[idx].bottomMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Beam::BeamSegment::BottomMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) { - memo.beamSegments[idx].bottomMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, bottomMaterial.attributeIndex); - } - } - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, bottomMaterial.overridden); - - // The ends overridden material name - memo.beamSegments[idx].endsMaterial.overridden = false; - if (currentSegment.Contains (Beam::BeamSegment::EndsMaterial)) { - memo.beamSegments[idx].endsMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Beam::BeamSegment::EndsMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) { - memo.beamSegments[idx].endsMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, endsMaterial.attributeIndex); - } - } - } - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, endsMaterial.overridden); - - // The overridden materials are chained - if (currentSegment.Contains (Beam::BeamSegment::MaterialsChained)) { - currentSegment.Get (Beam::BeamSegment::MaterialsChained, memo.beamSegments[idx].materialsChained); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, materialsChained); - } - } - } - } -#pragma endregion - - // Scheme - if (os.Contains (Beam::nSchemes)) { - os.Get (Beam::nSchemes, element.beam.nSchemes); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nSchemes); - } - - Utility::CreateAllSchemeData (os, element.beam.nSchemes, element, beamMask, &memo); - - // Hole -#pragma region Hole - GS::ObjectState allHoles; - UInt32 holesCount = 0; - - if (os.Contains (AssemblySegment::HoleData)) { - os.Get (AssemblySegment::HoleData, allHoles); - holesCount = allHoles.GetFieldCount (); - } - - if (holesCount > 0) { - memo.beamHoles = reinterpret_cast (BMAllocateHandle (holesCount * sizeof (API_Beam_Hole), ALLOCATE_CLEAR, 0)); - for (UInt32 idx = 0; idx < holesCount; ++idx) { - GS::ObjectState currentHole; - allHoles.Get (GS::String::SPrintf (Beam::HoleName, idx + 1), currentHole); - - if (!currentHole.IsEmpty ()) { - if (currentHole.Contains (Beam::holeType)) { - API_BHoleTypeID realHoleType = APIBHole_Rectangular; - GS::UniString holeName; - currentHole.Get (Beam::holeType, holeName); - - GS::Optional tmpHoleType = beamHoleTypeNames.FindValue (holeName); - if (tmpHoleType.HasValue ()) - realHoleType = tmpHoleType.Get (); - (*memo.beamHoles)[idx].holeType = realHoleType; - } - - if (currentHole.Contains (Beam::holeContourOn)) - currentHole.Get (Beam::holeContourOn, (*memo.beamHoles)[idx].holeContureOn); - - if (currentHole.Contains (Beam::holeId)) - currentHole.Get (Beam::holeId, (*memo.beamHoles)[idx].holeID); - - if (currentHole.Contains (Beam::centerx)) - currentHole.Get (Beam::centerx, (*memo.beamHoles)[idx].centerx); - - if (currentHole.Contains (Beam::centerz)) - currentHole.Get (Beam::centerz, (*memo.beamHoles)[idx].centerz); - - if (currentHole.Contains (Beam::width)) - currentHole.Get (Beam::width, (*memo.beamHoles)[idx].width); - - if (currentHole.Contains (Beam::height)) - currentHole.Get (Beam::height, (*memo.beamHoles)[idx].height); - } - } - } -#pragma endregion - - // Floor Plan and Section - Floor Plan Display - - // Show on Stories - Story visibility - Utility::CreateVisibility (os, "", element.beam.isAutoOnStoryVisibility, element.beam.visibility); - - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isAutoOnStoryVisibility); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showOnHome); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showAllAbove); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showAllBelow); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showRelAbove); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showRelBelow); - - // The display options (Projected, Projected with Overhead, Cut Only, Outlines Only, Overhead All or Symbolic Cut) - if (os.Contains (Beam::DisplayOptionName)) { - GS::UniString displayOptionName; - os.Get (Beam::DisplayOptionName, displayOptionName); - - GS::Optional type = displayOptionNames.FindValue (displayOptionName); - if (type.HasValue ()) { - element.beam.displayOption = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, displayOption); - } - } - - // Uncut projection mode (Symbolic, Projected) - if (os.Contains (Beam::UncutProjectionModeName)) { - GS::UniString uncutProjectionModeName; - os.Get (Beam::UncutProjectionModeName, uncutProjectionModeName); - - GS::Optional type = projectionModeNames.FindValue (uncutProjectionModeName); - if (type.HasValue ()) { - element.beam.uncutProjectionMode = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, uncutProjectionMode); - } - } - - // Overhead projection mode (Symbolic, Projected) - if (os.Contains (Beam::OverheadProjectionModeName)) { - GS::UniString overheadProjectionModeName; - os.Get (Beam::OverheadProjectionModeName, overheadProjectionModeName); - - GS::Optional type = projectionModeNames.FindValue (overheadProjectionModeName); - if (type.HasValue ()) { - element.beam.overheadProjectionMode = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, overheadProjectionMode); - } - } - - // Show projection (To Floor Plan Range, To Absolute Display Limit, Entire Element) - if (os.Contains (Beam::ViewDepthLimitationName)) { - GS::UniString viewDepthLimitationName; - os.Get (Beam::ViewDepthLimitationName, viewDepthLimitationName); - - GS::Optional type = viewDepthLimitationNames.FindValue (viewDepthLimitationName); - if (type.HasValue ()) { - element.beam.viewDepthLimitation = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, viewDepthLimitation); - } - } - - // Floor Plan and Section - Cut Surfaces - - // The pen index of beam contour line - if (os.Contains (Beam::cutContourLinePen)) { - os.Get (Beam::cutContourLinePen, element.beam.cutContourLinePen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, cutContourLinePen); - } - - // The linetype name of beam contour line - GS::UniString attributeName; - if (os.Contains (Beam::CutContourLinetypeName)) { - - os.Get (Beam::CutContourLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.cutContourLineType = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, cutContourLineType); - } - } - } - - // Override cut fill pen - if (os.Contains (Beam::OverrideCutFillPenIndex)) { - element.beam.penOverride.overrideCutFillPen = true; - os.Get (Beam::OverrideCutFillPenIndex, element.beam.penOverride.cutFillPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, penOverride.overrideCutFillPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (os.Contains (Beam::OverrideCutFillBackgroundPenIndex)) { - element.beam.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Beam::OverrideCutFillBackgroundPenIndex, element.beam.penOverride.cutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, penOverride.overrideCutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, penOverride.cutFillBackgroundPen); - } - - // Floor Plan and Section - Outlines - - // Always show outline - if (os.Contains (Beam::UncutLinePenIndex)) { - GS::UniString beamVisibleLinesName; - os.Get (Beam::UncutLinePenIndex, beamVisibleLinesName); - - GS::Optional type = beamVisibleLinesNames.FindValue (beamVisibleLinesName); - if (type.HasValue ()) { - element.beam.showContourLines = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, showContourLines); - } - } - - // The pen index of beam uncut contour line - if (os.Contains (Beam::UncutLinePenIndex)) { - os.Get (Beam::UncutLinePenIndex, element.beam.belowViewLinePen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, belowViewLinePen); - } - - // The linetype name of beam uncut contour line - if (os.Contains (Beam::UncutLinetypeName)) { - - os.Get (Beam::UncutLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.belowViewLineType = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, belowViewLineType); - } - } - } - - // The pen index of beam overhead contour line - if (os.Contains (Beam::OverheadLinePenIndex)) { - os.Get (Beam::OverheadLinePenIndex, element.beam.aboveViewLinePen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, aboveViewLinePen); - } - - // The linetype name of beam overhead contour line - if (os.Contains (Beam::OverheadLinetypeName)) { - - os.Get (Beam::OverheadLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.aboveViewLineType = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, aboveViewLineType); - } - } - } - - // The pen index of beam hidden contour line - if (os.Contains (Beam::HiddenLinePenIndex)) { - os.Get (Beam::HiddenLinePenIndex, element.beam.hiddenLinePen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, hiddenLinePen); - } - - // The linetype name of beam hidden contour line - if (os.Contains (Beam::HiddenLinetypeName)) { - - os.Get (Beam::HiddenLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.hiddenLineType = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, hiddenLineType); - } - } - } - - // Floor Plan and Section - Symbol - - // Always show outline - if (os.Contains (Beam::ShowReferenceAxisIndex)) { - GS::UniString beamVisibleLinesName; - os.Get (Beam::ShowReferenceAxisIndex, beamVisibleLinesName); - - GS::Optional type = beamVisibleLinesNames.FindValue (beamVisibleLinesName); - if (type.HasValue ()) { - element.beam.showReferenceAxis = type.Get (); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, showReferenceAxis); - } - } - - // Reference Axis Pen - if (os.Contains (Beam::refPen)) { - os.Get (Beam::refPen, element.beam.refPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, refPen); - } - - // Reference Axis Type - if (os.Contains (Beam::refLtype)) { - - os.Get (Beam::refLtype, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.refLtype = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, refLtype); - } - } - } - - // Floor Plan and Section - Cover Fills - if (os.Contains (Beam::useCoverFill)) { - os.Get (Beam::useCoverFill, element.beam.useCoverFill); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, useCoverFill); - } - - if (os.Contains (Beam::useCoverFillFromSurface)) { - os.Get (Beam::useCoverFillFromSurface, element.beam.useCoverFillFromSurface); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, useCoverFillFromSurface); - } - - if (os.Contains (Beam::coverFillForegroundPen)) { - os.Get (Beam::coverFillForegroundPen, element.beam.coverFillForegroundPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillForegroundPen); - } - - if (os.Contains (Beam::coverFillBackgroundPen)) { - os.Get (Beam::coverFillBackgroundPen, element.beam.coverFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillBackgroundPen); - } - - // Cover fill type - if (os.Contains (Beam::coverFillType)) { - - os.Get (Beam::coverFillType, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_FilltypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.beam.coverFillType = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillType); - } - } - } - - // Cover Fill Transformation - Utility::CreateCoverFillTransformation (os, element.beam.coverFillOrientationComesFrom3D, element.beam.coverFillTransformationType); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillOrientationComesFrom3D); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformationType); - - if (os.Contains (Beam::CoverFillTransformationOrigoX)) { - os.Get (Beam::CoverFillTransformationOrigoX, element.beam.coverFillTransformation.origo.x); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.origo.x); - } - - if (os.Contains (Beam::CoverFillTransformationOrigoY)) { - os.Get (Beam::CoverFillTransformationOrigoY, element.beam.coverFillTransformation.origo.y); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.origo.y); - } - - if (os.Contains (Beam::CoverFillTransformationXAxisX)) { - os.Get (Beam::CoverFillTransformationXAxisX, element.beam.coverFillTransformation.xAxis.x); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.xAxis.x); - } - - if (os.Contains (Beam::CoverFillTransformationXAxisY)) { - os.Get (Beam::CoverFillTransformationXAxisY, element.beam.coverFillTransformation.xAxis.y); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.xAxis.y); - } - - if (os.Contains (Beam::CoverFillTransformationYAxisX)) { - os.Get (Beam::CoverFillTransformationYAxisX, element.beam.coverFillTransformation.yAxis.x); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.yAxis.x); - } - - if (os.Contains (Beam::CoverFillTransformationYAxisY)) { - os.Get (Beam::CoverFillTransformationYAxisY, element.beam.coverFillTransformation.yAxis.y); - ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.yAxis.y); - } - - return NoError; -} - - -GS::String CreateBeam::GetName () const -{ - return CreateBeamCommandName; -} - - -} // namespace AddOnCommands +#include "CreateBeam.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" +#include "ResourceIds.hpp" +#include "ObjectState.hpp" +#include "Utility.hpp" +#include "Objects/Level.hpp" +#include "Objects/Point.hpp" +#include "FieldNames.hpp" +#include "TypeNameTables.hpp" +using namespace FieldNames; + +namespace AddOnCommands { + + +GS::String CreateBeam::GetFieldName () const +{ + return FieldNames::Beams; +} + + +GS::UniString CreateBeam::GetUndoableCommandName () const +{ + return "CreateSpeckleBeam"; +} + + +GSErrCode CreateBeam::GetElementFromObjectState (const GS::ObjectState& os, + API_Element& element, + API_Element& beamMask, + API_ElementMemo& memo, + GS::UInt64& memoMask, + API_SubElement** /*marker*/, + AttributeManager& /*attributeManager*/, + LibpartImportManager& /*libpartImportManager*/, + GS::Array& log) const +{ + GSErrCode err = NoError; + + Utility::SetElementType (element.header, API_BeamID); + err = Utility::GetBaseElementData (element, &memo, nullptr, log); + if (err != NoError) + return err; + + err = GetElementBaseFromObjectState (os, element, beamMask); + if (err != NoError) + return err; + + // Positioning + Objects::Point3D startPoint; + if (os.Contains (Beam::begC)) { + os.Get (Beam::begC, startPoint); + element.beam.begC = startPoint.ToAPI_Coord (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, begC); + } + + Objects::Point3D endPoint; + if (os.Contains (Beam::endC)) { + os.Get (Beam::endC, endPoint); + element.beam.endC = endPoint.ToAPI_Coord (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, endC); + } + + + if (os.Contains (ElementBase::Level)) { + GetStoryFromObjectState (os, startPoint.z, element.header.floorInd, element.beam.offset); + } else { + Utility::SetStoryLevelAndFloor (startPoint.z, element.header.floorInd, element.beam.offset); + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_Elem_Head, floorInd); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, offset); + + if (os.Contains (Beam::level)) { + os.Get (Beam::level, element.beam.level); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, level); + } + + if (os.Contains (Beam::isSlanted)) { + os.Get (Beam::isSlanted, element.beam.isSlanted); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isSlanted); + } + + if (os.Contains (Beam::slantAngle)) { + os.Get (Beam::slantAngle, element.beam.slantAngle); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, slantAngle); + } + + if (os.Contains (Beam::beamShape)) { + API_BeamShapeTypeID realBeamShapeType = API_StraightBeam; + GS::UniString beamShapeName; + os.Get (Beam::beamShape, beamShapeName); + + GS::Optional tmpBeamShapeType = beamShapeTypeNames.FindValue (beamShapeName); + if (tmpBeamShapeType.HasValue ()) + realBeamShapeType = tmpBeamShapeType.Get (); + element.beam.beamShape = realBeamShapeType; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, beamShape); + } + + if (os.Contains (Beam::sequence)) { + os.Get (Beam::sequence, element.beam.sequence); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, sequence); + } + + if (os.Contains (Beam::curveAngle)) { + os.Get (Beam::curveAngle, element.beam.curveAngle); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, curveAngle); + } + + if (os.Contains (Beam::verticalCurveHeight)) { + os.Get (Beam::verticalCurveHeight, element.beam.verticalCurveHeight); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, verticalCurveHeight); + } + + if (os.Contains (Beam::isFlipped)) { + os.Get (Beam::isFlipped, element.beam.isFlipped); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isFlipped); + } + + // End Cuts + if (os.Contains (Beam::nCuts)) { + os.Get (Beam::nCuts, element.beam.nCuts); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nCuts); + } + + Utility::CreateAllCutData (os, element.beam.nCuts, element, beamMask, &memo); + + // Reference Axis + if (os.Contains (Beam::anchorPoint)) { + os.Get (Beam::anchorPoint, element.beam.anchorPoint); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, anchorPoint); + } + + if (os.Contains (Beam::offset)) { + os.Get (Beam::offset, element.beam.offset); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, offset); + } + + if (os.Contains (Beam::profileAngle)) { + os.Get (Beam::profileAngle, element.beam.profileAngle); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, profileAngle); + } + + // Segment + if (os.Contains (Beam::nSegments)) { + os.Get (Beam::nSegments, element.beam.nSegments); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nSegments); + } + + if (os.Contains (Beam::nProfiles)) { + os.Get (Beam::nProfiles, element.beam.nProfiles); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nProfiles); + } + +#pragma region Segment + GS::ObjectState allSegments; + if (os.Contains (Beam::segments)) + os.Get (Beam::segments, allSegments); + + if (!allSegments.IsEmpty ()) { + API_BeamSegmentType defaultBeamSegment; + if (memo.beamSegments != nullptr) { + defaultBeamSegment = memo.beamSegments[0]; + memo.beamSegments = (API_BeamSegmentType*) BMAllocatePtr ((element.beam.nSegments) * sizeof (API_BeamSegmentType), ALLOCATE_CLEAR, 0); + } else { + return Error; + } + + memoMask = APIMemoMask_BeamSegment | + APIMemoMask_AssemblySegmentScheme | + APIMemoMask_BeamHole | + APIMemoMask_AssemblySegmentCut; + + for (UInt32 idx = 0; idx < element.beam.nSegments; ++idx) { + GS::ObjectState currentSegment; + allSegments.Get (GS::String::SPrintf (AssemblySegment::SegmentName, idx + 1), currentSegment); + + if (!currentSegment.IsEmpty ()) { + + memo.beamSegments[idx] = defaultBeamSegment; + GS::ObjectState assemblySegment; + currentSegment.Get (Beam::BeamSegment::segmentData, assemblySegment); + Utility::CreateOneSegmentData (assemblySegment, memo.beamSegments[idx].assemblySegmentData, beamMask); + + // The left overridden material name - in case of circle or profiled segment the left surface is the extrusion surface, but the import does not work properly in API + ResetAPIOverriddenAttribute (memo.beamSegments[idx].leftMaterial); + if (currentSegment.Contains (Beam::BeamSegment::LeftMaterial)) { + GS::UniString attrName; + currentSegment.Get (Beam::BeamSegment::LeftMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.beamSegments[idx].leftMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (leftMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (leftMaterial)); + + // The top overridden material name + ResetAPIOverriddenAttribute (memo.beamSegments[idx].topMaterial); + if (currentSegment.Contains (Beam::BeamSegment::TopMaterial)) { + GS::UniString attrName; + currentSegment.Get (Beam::BeamSegment::TopMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.beamSegments[idx].topMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (topMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeBoolField (topMaterial)); + + // The right overridden material name + ResetAPIOverriddenAttribute (memo.beamSegments[idx].rightMaterial); + if (currentSegment.Contains (Beam::BeamSegment::RightMaterial)) { + GS::UniString attrName; + currentSegment.Get (Beam::BeamSegment::RightMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.beamSegments[idx].rightMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (rightMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeBoolField (rightMaterial)); + + // The bottom overridden material name + ResetAPIOverriddenAttribute (memo.beamSegments[idx].bottomMaterial); + if (currentSegment.Contains (Beam::BeamSegment::BottomMaterial)) { + GS::UniString attrName; + currentSegment.Get (Beam::BeamSegment::BottomMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.beamSegments[idx].bottomMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (bottomMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeBoolField (bottomMaterial)); + + // The ends overridden material name + ResetAPIOverriddenAttribute (memo.beamSegments[idx].endsMaterial); + if (currentSegment.Contains (Beam::BeamSegment::EndsMaterial)) { + GS::UniString attrName; + currentSegment.Get (Beam::BeamSegment::EndsMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.beamSegments[idx].endsMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeIndexField (endsMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, GetAPIOverriddenAttributeBoolField (endsMaterial)); + + // The overridden materials are chained + if (currentSegment.Contains (Beam::BeamSegment::MaterialsChained)) { + currentSegment.Get (Beam::BeamSegment::MaterialsChained, memo.beamSegments[idx].materialsChained); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, materialsChained); + } + } + } + } +#pragma endregion + + // Scheme + if (os.Contains (Beam::nSchemes)) { + os.Get (Beam::nSchemes, element.beam.nSchemes); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, nSchemes); + } + + Utility::CreateAllSchemeData (os, element.beam.nSchemes, element, beamMask, &memo); + + // Hole +#pragma region Hole + GS::ObjectState allHoles; + UInt32 holesCount = 0; + + if (os.Contains (AssemblySegment::HoleData)) { + os.Get (AssemblySegment::HoleData, allHoles); + holesCount = allHoles.GetFieldCount (); + } + + if (holesCount > 0) { + memo.beamHoles = reinterpret_cast (BMAllocateHandle (holesCount * sizeof (API_Beam_Hole), ALLOCATE_CLEAR, 0)); + for (UInt32 idx = 0; idx < holesCount; ++idx) { + GS::ObjectState currentHole; + allHoles.Get (GS::String::SPrintf (Beam::HoleName, idx + 1), currentHole); + + if (!currentHole.IsEmpty ()) { + if (currentHole.Contains (Beam::holeType)) { + API_BHoleTypeID realHoleType = APIBHole_Rectangular; + GS::UniString holeName; + currentHole.Get (Beam::holeType, holeName); + + GS::Optional tmpHoleType = beamHoleTypeNames.FindValue (holeName); + if (tmpHoleType.HasValue ()) + realHoleType = tmpHoleType.Get (); + (*memo.beamHoles)[idx].holeType = realHoleType; + } + + if (currentHole.Contains (Beam::holeContourOn)) + currentHole.Get (Beam::holeContourOn, (*memo.beamHoles)[idx].holeContureOn); + + if (currentHole.Contains (Beam::holeId)) + currentHole.Get (Beam::holeId, (*memo.beamHoles)[idx].holeID); + + if (currentHole.Contains (Beam::centerx)) + currentHole.Get (Beam::centerx, (*memo.beamHoles)[idx].centerx); + + if (currentHole.Contains (Beam::centerz)) + currentHole.Get (Beam::centerz, (*memo.beamHoles)[idx].centerz); + + if (currentHole.Contains (Beam::width)) + currentHole.Get (Beam::width, (*memo.beamHoles)[idx].width); + + if (currentHole.Contains (Beam::height)) + currentHole.Get (Beam::height, (*memo.beamHoles)[idx].height); + } + } + } +#pragma endregion + + // Floor Plan and Section - Floor Plan Display + + // Show on Stories - Story visibility + Utility::CreateVisibility (os, "", element.beam.isAutoOnStoryVisibility, element.beam.visibility); + + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, isAutoOnStoryVisibility); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showOnHome); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showAllAbove); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showAllBelow); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showRelAbove); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, visibility.showRelBelow); + + // The display options (Projected, Projected with Overhead, Cut Only, Outlines Only, Overhead All or Symbolic Cut) + if (os.Contains (Beam::DisplayOptionName)) { + GS::UniString displayOptionName; + os.Get (Beam::DisplayOptionName, displayOptionName); + + GS::Optional type = displayOptionNames.FindValue (displayOptionName); + if (type.HasValue ()) { + element.beam.displayOption = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, displayOption); + } + } + + // Uncut projection mode (Symbolic, Projected) + if (os.Contains (Beam::UncutProjectionModeName)) { + GS::UniString uncutProjectionModeName; + os.Get (Beam::UncutProjectionModeName, uncutProjectionModeName); + + GS::Optional type = projectionModeNames.FindValue (uncutProjectionModeName); + if (type.HasValue ()) { + element.beam.uncutProjectionMode = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, uncutProjectionMode); + } + } + + // Overhead projection mode (Symbolic, Projected) + if (os.Contains (Beam::OverheadProjectionModeName)) { + GS::UniString overheadProjectionModeName; + os.Get (Beam::OverheadProjectionModeName, overheadProjectionModeName); + + GS::Optional type = projectionModeNames.FindValue (overheadProjectionModeName); + if (type.HasValue ()) { + element.beam.overheadProjectionMode = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, overheadProjectionMode); + } + } + + // Show projection (To Floor Plan Range, To Absolute Display Limit, Entire Element) + if (os.Contains (Beam::ViewDepthLimitationName)) { + GS::UniString viewDepthLimitationName; + os.Get (Beam::ViewDepthLimitationName, viewDepthLimitationName); + + GS::Optional type = viewDepthLimitationNames.FindValue (viewDepthLimitationName); + if (type.HasValue ()) { + element.beam.viewDepthLimitation = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, viewDepthLimitation); + } + } + + // Floor Plan and Section - Cut Surfaces + + // The pen index of beam contour line + if (os.Contains (Beam::cutContourLinePen)) { + os.Get (Beam::cutContourLinePen, element.beam.cutContourLinePen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, cutContourLinePen); + } + + // The linetype name of beam contour line + GS::UniString attributeName; + if (os.Contains (Beam::CutContourLinetypeName)) { + + os.Get (Beam::CutContourLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.cutContourLineType = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, cutContourLineType); + } + } + } + + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Beam::OverrideCutFillPenIndex, + Beam::OverrideCutFillBackgroundPenIndex, + element.beam, + beamMask) + != NoError) + return Error; + + // Floor Plan and Section - Outlines + + // Always show outline + if (os.Contains (Beam::UncutLinePenIndex)) { + GS::UniString beamVisibleLinesName; + os.Get (Beam::UncutLinePenIndex, beamVisibleLinesName); + + GS::Optional type = beamVisibleLinesNames.FindValue (beamVisibleLinesName); + if (type.HasValue ()) { + element.beam.showContourLines = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, showContourLines); + } + } + + // The pen index of beam uncut contour line + if (os.Contains (Beam::UncutLinePenIndex)) { + os.Get (Beam::UncutLinePenIndex, element.beam.belowViewLinePen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, belowViewLinePen); + } + + // The linetype name of beam uncut contour line + if (os.Contains (Beam::UncutLinetypeName)) { + + os.Get (Beam::UncutLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.belowViewLineType = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, belowViewLineType); + } + } + } + + // The pen index of beam overhead contour line + if (os.Contains (Beam::OverheadLinePenIndex)) { + os.Get (Beam::OverheadLinePenIndex, element.beam.aboveViewLinePen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, aboveViewLinePen); + } + + // The linetype name of beam overhead contour line + if (os.Contains (Beam::OverheadLinetypeName)) { + + os.Get (Beam::OverheadLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.aboveViewLineType = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, aboveViewLineType); + } + } + } + + // The pen index of beam hidden contour line + if (os.Contains (Beam::HiddenLinePenIndex)) { + os.Get (Beam::HiddenLinePenIndex, element.beam.hiddenLinePen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, hiddenLinePen); + } + + // The linetype name of beam hidden contour line + if (os.Contains (Beam::HiddenLinetypeName)) { + + os.Get (Beam::HiddenLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.hiddenLineType = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, hiddenLineType); + } + } + } + + // Floor Plan and Section - Symbol + + // Always show outline + if (os.Contains (Beam::ShowReferenceAxisIndex)) { + GS::UniString beamVisibleLinesName; + os.Get (Beam::ShowReferenceAxisIndex, beamVisibleLinesName); + + GS::Optional type = beamVisibleLinesNames.FindValue (beamVisibleLinesName); + if (type.HasValue ()) { + element.beam.showReferenceAxis = type.Get (); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, showReferenceAxis); + } + } + + // Reference Axis Pen + if (os.Contains (Beam::refPen)) { + os.Get (Beam::refPen, element.beam.refPen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, refPen); + } + + // Reference Axis Type + if (os.Contains (Beam::refLtype)) { + + os.Get (Beam::refLtype, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.refLtype = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, refLtype); + } + } + } + + // Floor Plan and Section - Cover Fills + if (os.Contains (Beam::useCoverFill)) { + os.Get (Beam::useCoverFill, element.beam.useCoverFill); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, useCoverFill); + } + + if (os.Contains (Beam::useCoverFillFromSurface)) { + os.Get (Beam::useCoverFillFromSurface, element.beam.useCoverFillFromSurface); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, useCoverFillFromSurface); + } + + if (os.Contains (Beam::coverFillForegroundPen)) { + os.Get (Beam::coverFillForegroundPen, element.beam.coverFillForegroundPen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillForegroundPen); + } + + if (os.Contains (Beam::coverFillBackgroundPen)) { + os.Get (Beam::coverFillBackgroundPen, element.beam.coverFillBackgroundPen); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillBackgroundPen); + } + + // Cover fill type + if (os.Contains (Beam::coverFillType)) { + + os.Get (Beam::coverFillType, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_FilltypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) { + element.beam.coverFillType = attribute.header.index; + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillType); + } + } + } + + // Cover Fill Transformation + Utility::CreateCoverFillTransformation (os, element.beam.coverFillOrientationComesFrom3D, element.beam.coverFillTransformationType); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillOrientationComesFrom3D); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformationType); + + if (os.Contains (Beam::CoverFillTransformationOrigoX)) { + os.Get (Beam::CoverFillTransformationOrigoX, element.beam.coverFillTransformation.origo.x); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.origo.x); + } + + if (os.Contains (Beam::CoverFillTransformationOrigoY)) { + os.Get (Beam::CoverFillTransformationOrigoY, element.beam.coverFillTransformation.origo.y); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.origo.y); + } + + if (os.Contains (Beam::CoverFillTransformationXAxisX)) { + os.Get (Beam::CoverFillTransformationXAxisX, element.beam.coverFillTransformation.xAxis.x); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.xAxis.x); + } + + if (os.Contains (Beam::CoverFillTransformationXAxisY)) { + os.Get (Beam::CoverFillTransformationXAxisY, element.beam.coverFillTransformation.xAxis.y); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.xAxis.y); + } + + if (os.Contains (Beam::CoverFillTransformationYAxisX)) { + os.Get (Beam::CoverFillTransformationYAxisX, element.beam.coverFillTransformation.yAxis.x); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.yAxis.x); + } + + if (os.Contains (Beam::CoverFillTransformationYAxisY)) { + os.Get (Beam::CoverFillTransformationYAxisY, element.beam.coverFillTransformation.yAxis.y); + ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamType, coverFillTransformation.yAxis.y); + } + + return NoError; +} + + +GS::String CreateBeam::GetName () const +{ + return CreateBeamCommandName; +} + + +} // namespace AddOnCommands diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateColumn.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateColumn.cpp index bc57f3b24d..908f3f3592 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateColumn.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateColumn.cpp @@ -1,573 +1,570 @@ -#include "CreateColumn.hpp" -#include "ResourceIds.hpp" -#include "ObjectState.hpp" -#include "Utility.hpp" -#include "Objects/Level.hpp" -#include "Objects/Point.hpp" -#include "RealNumber.h" -#include "DGModule.hpp" -#include "FieldNames.hpp" -#include "TypeNameTables.hpp" -using namespace FieldNames; - -namespace AddOnCommands -{ - - -GS::String CreateColumn::GetFieldName () const -{ - return Columns; -} - - -GS::UniString CreateColumn::GetUndoableCommandName () const -{ - return "CreateSpeckleColumn"; -} - - -GSErrCode CreateColumn::GetElementFromObjectState (const GS::ObjectState& os, - API_Element& element, - API_Element& elementMask, - API_ElementMemo& memo, - GS::UInt64& memoMask, - API_SubElement** /*marker*/, - AttributeManager& /*attributeManager*/, - LibpartImportManager& /*libpartImportManager*/, - GS::Array& log) const -{ - GSErrCode err = NoError; - - Utility::SetElementType (element.header, API_ColumnID); - err = Utility::GetBaseElementData (element, &memo, nullptr, log); - if (err != NoError) - return err; - - err = GetElementBaseFromObjectState (os, element, elementMask); - if (err != NoError) - return err; - - // Positioning - geometry - Objects::Point3D origoPos; - if (os.Contains (Column::origoPos)) { - os.Get (Column::origoPos, origoPos); - element.column.origoPos = origoPos.ToAPI_Coord (); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, origoPos); - } - - - if (os.Contains (ElementBase::Level)) { - GetStoryFromObjectState (os, origoPos.z, element.header.floorInd, element.column.bottomOffset); - } - else { - Utility::SetStoryLevelAndFloor (origoPos.z, element.header.floorInd, element.column.bottomOffset); - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_Elem_Head, floorInd); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, bottomOffset); - - if (os.Contains (Column::height)) { - os.Get (Column::height, element.column.height); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, height); - } - - // Positioning - story relation - if (os.Contains (Column::bottomOffset)) { - os.Get (Column::bottomOffset, element.column.bottomOffset); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, bottomOffset); - } - - if (os.Contains (Column::topOffset)) { - os.Get (Column::topOffset, element.column.topOffset); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, topOffset); - } - - if (os.Contains (Column::relativeTopStory)) { - os.Get (Column::relativeTopStory, element.column.relativeTopStory); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, relativeTopStory); - } - - // Positioning - slanted column - if (os.Contains (Column::isSlanted)) { - os.Get (Column::isSlanted, element.column.isSlanted); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isSlanted); - } - - if (os.Contains (Column::slantAngle)) { - os.Get (Column::slantAngle, element.column.slantAngle); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, slantAngle); - } - - if (os.Contains (Column::slantDirectionAngle)) { - os.Get (Column::slantDirectionAngle, element.column.slantDirectionAngle); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, slantDirectionAngle); - } - - if (os.Contains (Column::isFlipped)) { - os.Get (Column::isFlipped, element.column.isFlipped); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isFlipped); - } - - // Positioning - wrapping - if (os.Contains (Column::Wrapping)) { - os.Get (Column::Wrapping, element.column.wrapping); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, wrapping); - } - - // Model - Defines the relation of column to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) - if (os.Contains (Column::ColumnRelationToZoneName)) { - GS::UniString columnRelationToZoneName; - os.Get (Column::ColumnRelationToZoneName, columnRelationToZoneName); - - GS::Optional type = relationToZoneNames.FindValue (columnRelationToZoneName); - if (type.HasValue ()) - element.column.zoneRel = type.Get (); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, type); - } - - // End Cuts - if (os.Contains (Column::nCuts)) { - os.Get (Column::nCuts, element.column.nCuts); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nCuts); - } - - Utility::CreateAllCutData (os, element.column.nCuts, element, elementMask, &memo); - - // Reference Axis - if (os.Contains (Column::coreAnchor)) { - os.Get (Column::coreAnchor, element.column.coreAnchor); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreAnchor); - } - - if (os.Contains (Column::axisRotationAngle)) { - os.Get (Column::axisRotationAngle, element.column.axisRotationAngle); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, axisRotationAngle); - } - - // Segment - if (os.Contains (Column::nSegments)) { - os.Get (Column::nSegments, element.column.nSegments); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nSegments); - } - - if (os.Contains (Column::nProfiles)) { - os.Get (Column::nProfiles, element.column.nProfiles); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nProfiles); - } - - API_ColumnSegmentType defaultColumnSegment; - if (memo.columnSegments != nullptr) { - defaultColumnSegment = memo.columnSegments[0]; - memo.columnSegments = (API_ColumnSegmentType*) BMAllocatePtr ((element.column.nSegments) * sizeof (API_ColumnSegmentType), ALLOCATE_CLEAR, 0); - } else { - return Error; - } - - memoMask = APIMemoMask_ColumnSegment | - APIMemoMask_AssemblySegmentScheme | - APIMemoMask_AssemblySegmentCut; - -#pragma region Segment - GS::ObjectState allSegments; - if (os.Contains (Column::segments)) - os.Get (Column::segments, allSegments); - - for (UInt32 idx = 0; idx < element.column.nSegments; ++idx) { - GS::ObjectState currentSegment; - allSegments.Get (GS::String::SPrintf (AssemblySegment::SegmentName, idx + 1), currentSegment); - - if (!currentSegment.IsEmpty ()) { - - memo.columnSegments[idx] = defaultColumnSegment; - GS::ObjectState assemblySegment; - currentSegment.Get (Column::ColumnSegment::segmentData, assemblySegment); - Utility::CreateOneSegmentData (assemblySegment, memo.columnSegments[idx].assemblySegmentData, elementMask); - - // Veneer attributes - if (currentSegment.Contains (Column::ColumnSegment::VenThick)) { - // Veneer type - API_VeneerTypeID venType = APIVeneer_Core; - if (os.Contains (Column::ColumnSegment::VenType)) { - GS::UniString venTypeName; - currentSegment.Get (Column::ColumnSegment::VenType, venTypeName); - GS::Optional type = venTypeNames.FindValue (venTypeName); - if (type.HasValue ()) - venType = type.Get (); - - memo.columnSegments[idx].venType = venType; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, venType); - } - - // Veneer building material - if (currentSegment.Contains (Column::ColumnSegment::VenBuildingMaterial)) { - GS::UniString attrName; - currentSegment.Get (Column::ColumnSegment::VenBuildingMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_BuildingMaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) - memo.columnSegments[idx].venBuildingMaterial = attrib.header.index; - } - } - - // Veneer thick - currentSegment.Get (Column::ColumnSegment::VenThick, memo.columnSegments[idx].venThick); - } else { - memo.columnSegments[idx].venThick = 0.0; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, venThick); - - // The extrusion overridden material name - if (currentSegment.Contains (Column::ColumnSegment::ExtrusionSurfaceMaterial)) { - memo.columnSegments[idx].extrusionSurfaceMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Column::ColumnSegment::ExtrusionSurfaceMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) - memo.columnSegments[idx].extrusionSurfaceMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, extrusionSurfaceMaterial.attributeIndex); - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, extrusionSurfaceMaterial.overridden); - } - - // The ends overridden material name - if (currentSegment.Contains (Column::ColumnSegment::EndsSurfaceMaterial)) { - memo.columnSegments[idx].endsMaterial.overridden = true; - - GS::UniString attrName; - currentSegment.Get (Column::ColumnSegment::EndsSurfaceMaterial, attrName); - - if (!attrName.IsEmpty ()) { - API_Attribute attrib; - BNZeroMemory (&attrib, sizeof (API_Attribute)); - attrib.header.typeID = API_MaterialID; - CHCopyC (attrName.ToCStr (), attrib.header.name); - err = ACAPI_Attribute_Get (&attrib); - - if (err == NoError) - memo.columnSegments[idx].endsMaterial.attributeIndex = attrib.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, endsMaterial.attributeIndex); - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, endsMaterial.overridden); - } - - // The overridden materials are chained - if (currentSegment.Contains (Column::ColumnSegment::MaterialsChained)) - currentSegment.Get (Column::ColumnSegment::MaterialsChained, memo.columnSegments[idx].materialsChained); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, materialsChained); - } - } -#pragma endregion - - // Scheme - if (os.Contains (Column::nSchemes)) { - os.Get (Column::nSchemes, element.column.nSchemes); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nSchemes); - } - - Utility::CreateAllSchemeData (os, element.column.nSchemes, element, elementMask, &memo); - - // Floor Plan and Section - Floor Plan Display - - // Story visibility - Utility::CreateVisibility (os, "", element.column.isAutoOnStoryVisibility, element.column.visibility); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isAutoOnStoryVisibility); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showOnHome); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showAllAbove); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showAllBelow); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showRelAbove); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showRelBelow); - - // The display options (Projected, Projected with Overhead, Cut Only, Outlines Only, Overhead All or Symbolic Cut) - if (os.Contains (Column::DisplayOptionName)) { - GS::UniString displayOptionName; - os.Get (Column::DisplayOptionName, displayOptionName); - - GS::Optional type = displayOptionNames.FindValue (displayOptionName); - if (type.HasValue ()) { - element.column.displayOption = type.Get (); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, displayOption); - } - } - - // Show projection (To Floor Plan Range, To Absolute Display Limit, Entire Element) - if (os.Contains (Column::ViewDepthLimitationName)) { - GS::UniString viewDepthLimitationName; - os.Get (Column::ViewDepthLimitationName, viewDepthLimitationName); - - GS::Optional type = viewDepthLimitationNames.FindValue (viewDepthLimitationName); - if (type.HasValue ()) - element.column.viewDepthLimitation = type.Get (); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, viewDepthLimitation); - } - - // Floor Plan and Section - Cut Surfaces - - // The pen index of column core contour line - if (os.Contains (Column::corePen)) { - os.Get (Column::corePen, element.column.corePen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, corePen); - } - - // The linetype name of column core contour line - GS::UniString attributeName; - if (os.Contains (Column::CoreLinetypeName)) { - - os.Get (Column::CoreLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.contLtype = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, contLtype); - } - - // The pen index of column veneer contour line - if (os.Contains (Column::VeneerPenIndex)) { - os.Get (Column::VeneerPenIndex, element.column.venLinePen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, venLinePen); - } - - // The linetype name of column veneer contour line - if (os.Contains (Column::VeneerLinetypeName)) { - - os.Get (Column::VeneerLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.venLineType = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, venLineType); - } - - // Override cut fill pen - element.column.penOverride.overrideCutFillPen = false; - if (os.Contains (Column::OverrideCutFillPenIndex)) { - element.column.penOverride.overrideCutFillPen = true; - os.Get (Column::OverrideCutFillPenIndex, element.column.penOverride.cutFillPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, penOverride.cutFillPen); - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, penOverride.overrideCutFillPen); - - // Override cut fill background pen - element.column.penOverride.overrideCutFillBackgroundPen = false; - if (os.Contains (Column::OverrideCutFillBackgroundPenIndex)) { - element.column.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Column::OverrideCutFillBackgroundPenIndex, element.column.penOverride.cutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, penOverride.cutFillBackgroundPen); - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, penOverride.overrideCutFillBackgroundPen); - - // Floor Plan and Section - Outlines - - // The pen index of column uncut contour line - if (os.Contains (Column::UncutLinePenIndex)) { - os.Get (Column::UncutLinePenIndex, element.column.belowViewLinePen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, belowViewLinePen); - } - - // The linetype name of column uncut contour line - if (os.Contains (Column::UncutLinetypeName)) { - - os.Get (Column::UncutLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.belowViewLineType = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, belowViewLineType); - } - - // The pen index of column overhead contour line - if (os.Contains (Column::OverheadLinePenIndex)) { - os.Get (Column::OverheadLinePenIndex, element.column.aboveViewLinePen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, aboveViewLinePen); - } - - // The linetype name of column overhead contour line - if (os.Contains (Column::OverheadLinetypeName)) { - - os.Get (Column::OverheadLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.aboveViewLineType = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, aboveViewLineType); - } - - // The pen index of column hidden contour line - if (os.Contains (Column::HiddenLinePenIndex)) { - os.Get (Column::HiddenLinePenIndex, element.column.hiddenLinePen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, hiddenLinePen); - } - - // The linetype name of column hidden contour line - if (os.Contains (Column::HiddenLinetypeName)) { - - os.Get (Column::HiddenLinetypeName, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_LinetypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.hiddenLineType = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, hiddenLineType); - } - - // Floor Plan and Section - Floor Plan Symbol - - // Symbol Type (Plain, Slash, X, Crosshair) - if (os.Contains (Column::CoreSymbolTypeName)) { - GS::UniString coreSymbolTypeName; - os.Get (Column::CoreSymbolTypeName, coreSymbolTypeName); - - GS::Optional type = coreSymbolTypeNames.FindValue (coreSymbolTypeName); - if (type.HasValue ()) - element.column.coreSymbolType = type.Get (); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolType); - } - - // Core Symbol Lengths - if (os.Contains (Column::coreSymbolPar1)) { - os.Get (Column::coreSymbolPar1, element.column.coreSymbolPar1); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPar1); - } - - if (os.Contains (Column::coreSymbolPar2)) { - os.Get (Column::coreSymbolPar2, element.column.coreSymbolPar2); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPar2); - } - - // Core Symbol Pen - if (os.Contains (Column::CoreSymbolPenIndex)) { - os.Get (Column::CoreSymbolPenIndex, element.column.coreSymbolPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPen); - } - - // Floor Plan and Section - Cover Fills - if (os.Contains (Column::useCoverFill)) { - os.Get (Column::useCoverFill, element.column.useCoverFill); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, useCoverFill); - } - - if (os.Contains (Column::useCoverFillFromSurface)) { - os.Get (Column::useCoverFillFromSurface, element.column.useCoverFillFromSurface); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, useCoverFillFromSurface); - } - - if (os.Contains (Column::coverFillForegroundPen)) { - os.Get (Column::coverFillForegroundPen, element.column.coverFillForegroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillForegroundPen); - } - - if (os.Contains (Column::coverFillBackgroundPen)) { - os.Get (Column::coverFillBackgroundPen, element.column.coverFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillBackgroundPen); - } - - // Cover fill type - if (os.Contains (Column::coverFillType)) { - - os.Get (Column::coverFillType, attributeName); - - if (!attributeName.IsEmpty ()) { - API_Attribute attribute; - BNZeroMemory (&attribute, sizeof (API_Attribute)); - attribute.header.typeID = API_FilltypeID; - CHCopyC (attributeName.ToCStr (), attribute.header.name); - - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.column.coverFillType = attribute.header.index; - } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillType); - } - - // Cover Fill Transformation - Utility::CreateCoverFillTransformation (os, element.column.coverFillOrientationComesFrom3D, element.column.coverFillTransformationType); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillOrientationComesFrom3D); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformationType); - - if (os.Contains (Column::CoverFillTransformationOrigoX)) { - os.Get (Column::CoverFillTransformationOrigoX, element.column.coverFillTransformation.origo.x); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.origo.x); - } - - if (os.Contains (Column::CoverFillTransformationOrigoY)) { - os.Get (Column::CoverFillTransformationOrigoY, element.column.coverFillTransformation.origo.y); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.origo.y); - } - - if (os.Contains (Column::CoverFillTransformationXAxisX)) { - os.Get (Column::CoverFillTransformationXAxisX, element.column.coverFillTransformation.xAxis.x); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.xAxis.x); - } - - if (os.Contains (Column::CoverFillTransformationXAxisY)) { - os.Get (Column::CoverFillTransformationXAxisY, element.column.coverFillTransformation.xAxis.y); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.xAxis.y); - } - - if (os.Contains (Column::CoverFillTransformationYAxisX)) { - os.Get (Column::CoverFillTransformationYAxisX, element.column.coverFillTransformation.yAxis.x); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.yAxis.x); - } - - if (os.Contains (Column::CoverFillTransformationYAxisY)) { - os.Get (Column::CoverFillTransformationYAxisY, element.column.coverFillTransformation.yAxis.y); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.yAxis.y); - } - - return err; -} -#pragma endregion - - -GS::String CreateColumn::GetName () const -{ - return CreateColumnCommandName; -} - - -} // namespace AddOnCommands - +#include "CreateColumn.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" +#include "ResourceIds.hpp" +#include "ObjectState.hpp" +#include "Utility.hpp" +#include "Objects/Level.hpp" +#include "Objects/Point.hpp" +#include "RealNumber.h" +#include "DGModule.hpp" +#include "FieldNames.hpp" +#include "TypeNameTables.hpp" +using namespace FieldNames; + +namespace AddOnCommands +{ + + +GS::String CreateColumn::GetFieldName () const +{ + return Columns; +} + + +GS::UniString CreateColumn::GetUndoableCommandName () const +{ + return "CreateSpeckleColumn"; +} + + +GSErrCode CreateColumn::GetElementFromObjectState (const GS::ObjectState& os, + API_Element& element, + API_Element& elementMask, + API_ElementMemo& memo, + GS::UInt64& memoMask, + API_SubElement** /*marker*/, + AttributeManager& /*attributeManager*/, + LibpartImportManager& /*libpartImportManager*/, + GS::Array& log) const +{ + GSErrCode err = NoError; + + Utility::SetElementType (element.header, API_ColumnID); + err = Utility::GetBaseElementData (element, &memo, nullptr, log); + if (err != NoError) + return err; + + err = GetElementBaseFromObjectState (os, element, elementMask); + if (err != NoError) + return err; + + // Positioning - geometry + Objects::Point3D origoPos; + if (os.Contains (Column::origoPos)) { + os.Get (Column::origoPos, origoPos); + element.column.origoPos = origoPos.ToAPI_Coord (); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, origoPos); + } + + + if (os.Contains (ElementBase::Level)) { + GetStoryFromObjectState (os, origoPos.z, element.header.floorInd, element.column.bottomOffset); + } else { + Utility::SetStoryLevelAndFloor (origoPos.z, element.header.floorInd, element.column.bottomOffset); + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_Elem_Head, floorInd); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, bottomOffset); + + if (os.Contains (Column::height)) { + os.Get (Column::height, element.column.height); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, height); + } + + // Positioning - story relation + if (os.Contains (Column::bottomOffset)) { + os.Get (Column::bottomOffset, element.column.bottomOffset); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, bottomOffset); + } + + if (os.Contains (Column::topOffset)) { + os.Get (Column::topOffset, element.column.topOffset); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, topOffset); + } + + if (os.Contains (Column::relativeTopStory)) { + os.Get (Column::relativeTopStory, element.column.relativeTopStory); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, relativeTopStory); + } + + // Positioning - slanted column + if (os.Contains (Column::isSlanted)) { + os.Get (Column::isSlanted, element.column.isSlanted); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isSlanted); + } + + if (os.Contains (Column::slantAngle)) { + os.Get (Column::slantAngle, element.column.slantAngle); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, slantAngle); + } + + if (os.Contains (Column::slantDirectionAngle)) { + os.Get (Column::slantDirectionAngle, element.column.slantDirectionAngle); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, slantDirectionAngle); + } + + if (os.Contains (Column::isFlipped)) { + os.Get (Column::isFlipped, element.column.isFlipped); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isFlipped); + } + + // Positioning - wrapping + if (os.Contains (Column::Wrapping)) { + os.Get (Column::Wrapping, element.column.wrapping); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, wrapping); + } + + // Model - Defines the relation of column to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) + if (os.Contains (Column::ColumnRelationToZoneName)) { + GS::UniString columnRelationToZoneName; + os.Get (Column::ColumnRelationToZoneName, columnRelationToZoneName); + + GS::Optional type = relationToZoneNames.FindValue (columnRelationToZoneName); + if (type.HasValue ()) + element.column.zoneRel = type.Get (); + + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, type); + } + + // End Cuts + if (os.Contains (Column::nCuts)) { + os.Get (Column::nCuts, element.column.nCuts); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nCuts); + } + + Utility::CreateAllCutData (os, element.column.nCuts, element, elementMask, &memo); + + // Reference Axis + if (os.Contains (Column::coreAnchor)) { + os.Get (Column::coreAnchor, element.column.coreAnchor); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreAnchor); + } + + if (os.Contains (Column::axisRotationAngle)) { + os.Get (Column::axisRotationAngle, element.column.axisRotationAngle); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, axisRotationAngle); + } + + // Segment + if (os.Contains (Column::nSegments)) { + os.Get (Column::nSegments, element.column.nSegments); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nSegments); + } + + if (os.Contains (Column::nProfiles)) { + os.Get (Column::nProfiles, element.column.nProfiles); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nProfiles); + } + + API_ColumnSegmentType defaultColumnSegment; + if (memo.columnSegments != nullptr) { + defaultColumnSegment = memo.columnSegments[0]; + memo.columnSegments = (API_ColumnSegmentType*) BMAllocatePtr ((element.column.nSegments) * sizeof (API_ColumnSegmentType), ALLOCATE_CLEAR, 0); + } else { + return Error; + } + + memoMask = APIMemoMask_ColumnSegment | + APIMemoMask_AssemblySegmentScheme | + APIMemoMask_AssemblySegmentCut; + +#pragma region Segment + GS::ObjectState allSegments; + if (os.Contains (Column::segments)) + os.Get (Column::segments, allSegments); + + for (UInt32 idx = 0; idx < element.column.nSegments; ++idx) { + GS::ObjectState currentSegment; + allSegments.Get (GS::String::SPrintf (AssemblySegment::SegmentName, idx + 1), currentSegment); + + if (!currentSegment.IsEmpty ()) { + + memo.columnSegments[idx] = defaultColumnSegment; + GS::ObjectState assemblySegment; + currentSegment.Get (Column::ColumnSegment::segmentData, assemblySegment); + Utility::CreateOneSegmentData (assemblySegment, memo.columnSegments[idx].assemblySegmentData, elementMask); + + // Veneer attributes + if (currentSegment.Contains (Column::ColumnSegment::VenThick)) { + // Veneer type + API_VeneerTypeID venType = APIVeneer_Core; + if (os.Contains (Column::ColumnSegment::VenType)) { + GS::UniString venTypeName; + currentSegment.Get (Column::ColumnSegment::VenType, venTypeName); + GS::Optional type = venTypeNames.FindValue (venTypeName); + if (type.HasValue ()) + venType = type.Get (); + + memo.columnSegments[idx].venType = venType; + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, venType); + } + + // Veneer building material + if (currentSegment.Contains (Column::ColumnSegment::VenBuildingMaterial)) { + GS::UniString attrName; + currentSegment.Get (Column::ColumnSegment::VenBuildingMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_BuildingMaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) + memo.columnSegments[idx].venBuildingMaterial = attrib.header.index; + } + } + + // Veneer thick + currentSegment.Get (Column::ColumnSegment::VenThick, memo.columnSegments[idx].venThick); + } else { + memo.columnSegments[idx].venThick = 0.0; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, venThick); + + // The extrusion overridden material name + ResetAPIOverriddenAttribute (memo.columnSegments[idx].extrusionSurfaceMaterial); + if (currentSegment.Contains (Column::ColumnSegment::ExtrusionSurfaceMaterial)) { + + GS::UniString attrName; + currentSegment.Get (Column::ColumnSegment::ExtrusionSurfaceMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.columnSegments[idx].extrusionSurfaceMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, GetAPIOverriddenAttributeIndexField (extrusionSurfaceMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, GetAPIOverriddenAttributeBoolField (extrusionSurfaceMaterial)); + + + // The ends overridden material name + ResetAPIOverriddenAttribute (memo.columnSegments[idx].endsMaterial); + if (currentSegment.Contains (Column::ColumnSegment::EndsSurfaceMaterial)) { + + + GS::UniString attrName; + currentSegment.Get (Column::ColumnSegment::EndsSurfaceMaterial, attrName); + + if (!attrName.IsEmpty ()) { + API_Attribute attrib; + BNZeroMemory (&attrib, sizeof (API_Attribute)); + attrib.header.typeID = API_MaterialID; + CHCopyC (attrName.ToCStr (), attrib.header.name); + err = ACAPI_Attribute_Get (&attrib); + + if (err == NoError) { + SetAPIOverriddenAttribute (memo.columnSegments[idx].endsMaterial, attrib.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, GetAPIOverriddenAttributeIndexField (endsMaterial)); + } + } + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, GetAPIOverriddenAttributeBoolField (endsMaterial)); + + // The overridden materials are chained + if (currentSegment.Contains (Column::ColumnSegment::MaterialsChained)) + currentSegment.Get (Column::ColumnSegment::MaterialsChained, memo.columnSegments[idx].materialsChained); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnSegmentType, materialsChained); + } + } +#pragma endregion + + // Scheme + if (os.Contains (Column::nSchemes)) { + os.Get (Column::nSchemes, element.column.nSchemes); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, nSchemes); + } + + Utility::CreateAllSchemeData (os, element.column.nSchemes, element, elementMask, &memo); + + // Floor Plan and Section - Floor Plan Display + + // Story visibility + Utility::CreateVisibility (os, "", element.column.isAutoOnStoryVisibility, element.column.visibility); + + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, isAutoOnStoryVisibility); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showOnHome); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showAllAbove); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showAllBelow); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showRelAbove); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, visibility.showRelBelow); + + // The display options (Projected, Projected with Overhead, Cut Only, Outlines Only, Overhead All or Symbolic Cut) + if (os.Contains (Column::DisplayOptionName)) { + GS::UniString displayOptionName; + os.Get (Column::DisplayOptionName, displayOptionName); + + GS::Optional type = displayOptionNames.FindValue (displayOptionName); + if (type.HasValue ()) { + element.column.displayOption = type.Get (); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, displayOption); + } + } + + // Show projection (To Floor Plan Range, To Absolute Display Limit, Entire Element) + if (os.Contains (Column::ViewDepthLimitationName)) { + GS::UniString viewDepthLimitationName; + os.Get (Column::ViewDepthLimitationName, viewDepthLimitationName); + + GS::Optional type = viewDepthLimitationNames.FindValue (viewDepthLimitationName); + if (type.HasValue ()) + element.column.viewDepthLimitation = type.Get (); + + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, viewDepthLimitation); + } + + // Floor Plan and Section - Cut Surfaces + + // The pen index of column core contour line + if (os.Contains (Column::corePen)) { + os.Get (Column::corePen, element.column.corePen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, corePen); + } + + // The linetype name of column core contour line + GS::UniString attributeName; + if (os.Contains (Column::CoreLinetypeName)) { + + os.Get (Column::CoreLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.contLtype = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, contLtype); + } + + // The pen index of column veneer contour line + if (os.Contains (Column::VeneerPenIndex)) { + os.Get (Column::VeneerPenIndex, element.column.venLinePen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, venLinePen); + } + + // The linetype name of column veneer contour line + if (os.Contains (Column::VeneerLinetypeName)) { + + os.Get (Column::VeneerLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.venLineType = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, venLineType); + } + + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Column::OverrideCutFillPenIndex, + Column::OverrideCutFillBackgroundPenIndex, + element.column, + elementMask) + != NoError) + return Error; + + // Floor Plan and Section - Outlines + + // The pen index of column uncut contour line + if (os.Contains (Column::UncutLinePenIndex)) { + os.Get (Column::UncutLinePenIndex, element.column.belowViewLinePen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, belowViewLinePen); + } + + // The linetype name of column uncut contour line + if (os.Contains (Column::UncutLinetypeName)) { + + os.Get (Column::UncutLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.belowViewLineType = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, belowViewLineType); + } + + // The pen index of column overhead contour line + if (os.Contains (Column::OverheadLinePenIndex)) { + os.Get (Column::OverheadLinePenIndex, element.column.aboveViewLinePen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, aboveViewLinePen); + } + + // The linetype name of column overhead contour line + if (os.Contains (Column::OverheadLinetypeName)) { + + os.Get (Column::OverheadLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.aboveViewLineType = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, aboveViewLineType); + } + + // The pen index of column hidden contour line + if (os.Contains (Column::HiddenLinePenIndex)) { + os.Get (Column::HiddenLinePenIndex, element.column.hiddenLinePen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, hiddenLinePen); + } + + // The linetype name of column hidden contour line + if (os.Contains (Column::HiddenLinetypeName)) { + + os.Get (Column::HiddenLinetypeName, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_LinetypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.hiddenLineType = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, hiddenLineType); + } + + // Floor Plan and Section - Floor Plan Symbol + + // Symbol Type (Plain, Slash, X, Crosshair) + if (os.Contains (Column::CoreSymbolTypeName)) { + GS::UniString coreSymbolTypeName; + os.Get (Column::CoreSymbolTypeName, coreSymbolTypeName); + + GS::Optional type = coreSymbolTypeNames.FindValue (coreSymbolTypeName); + if (type.HasValue ()) + element.column.coreSymbolType = type.Get (); + + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolType); + } + + // Core Symbol Lengths + if (os.Contains (Column::coreSymbolPar1)) { + os.Get (Column::coreSymbolPar1, element.column.coreSymbolPar1); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPar1); + } + + if (os.Contains (Column::coreSymbolPar2)) { + os.Get (Column::coreSymbolPar2, element.column.coreSymbolPar2); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPar2); + } + + // Core Symbol Pen + if (os.Contains (Column::CoreSymbolPenIndex)) { + os.Get (Column::CoreSymbolPenIndex, element.column.coreSymbolPen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coreSymbolPen); + } + + // Floor Plan and Section - Cover Fills + if (os.Contains (Column::useCoverFill)) { + os.Get (Column::useCoverFill, element.column.useCoverFill); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, useCoverFill); + } + + if (os.Contains (Column::useCoverFillFromSurface)) { + os.Get (Column::useCoverFillFromSurface, element.column.useCoverFillFromSurface); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, useCoverFillFromSurface); + } + + if (os.Contains (Column::coverFillForegroundPen)) { + os.Get (Column::coverFillForegroundPen, element.column.coverFillForegroundPen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillForegroundPen); + } + + if (os.Contains (Column::coverFillBackgroundPen)) { + os.Get (Column::coverFillBackgroundPen, element.column.coverFillBackgroundPen); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillBackgroundPen); + } + + // Cover fill type + if (os.Contains (Column::coverFillType)) { + + os.Get (Column::coverFillType, attributeName); + + if (!attributeName.IsEmpty ()) { + API_Attribute attribute; + BNZeroMemory (&attribute, sizeof (API_Attribute)); + attribute.header.typeID = API_FilltypeID; + CHCopyC (attributeName.ToCStr (), attribute.header.name); + + if (NoError == ACAPI_Attribute_Get (&attribute)) + element.column.coverFillType = attribute.header.index; + } + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillType); + } + + // Cover Fill Transformation + Utility::CreateCoverFillTransformation (os, element.column.coverFillOrientationComesFrom3D, element.column.coverFillTransformationType); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillOrientationComesFrom3D); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformationType); + + if (os.Contains (Column::CoverFillTransformationOrigoX)) { + os.Get (Column::CoverFillTransformationOrigoX, element.column.coverFillTransformation.origo.x); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.origo.x); + } + + if (os.Contains (Column::CoverFillTransformationOrigoY)) { + os.Get (Column::CoverFillTransformationOrigoY, element.column.coverFillTransformation.origo.y); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.origo.y); + } + + if (os.Contains (Column::CoverFillTransformationXAxisX)) { + os.Get (Column::CoverFillTransformationXAxisX, element.column.coverFillTransformation.xAxis.x); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.xAxis.x); + } + + if (os.Contains (Column::CoverFillTransformationXAxisY)) { + os.Get (Column::CoverFillTransformationXAxisY, element.column.coverFillTransformation.xAxis.y); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.xAxis.y); + } + + if (os.Contains (Column::CoverFillTransformationYAxisX)) { + os.Get (Column::CoverFillTransformationYAxisX, element.column.coverFillTransformation.yAxis.x); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.yAxis.x); + } + + if (os.Contains (Column::CoverFillTransformationYAxisY)) { + os.Get (Column::CoverFillTransformationYAxisY, element.column.coverFillTransformation.yAxis.y); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ColumnType, coverFillTransformation.yAxis.y); + } + + return err; +} +#pragma endregion + + +GS::String CreateColumn::GetName () const +{ + return CreateColumnCommandName; +} + + +} // namespace AddOnCommands + diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateCommand.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateCommand.cpp index e5010babe6..b159461dd1 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateCommand.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateCommand.cpp @@ -1,3 +1,4 @@ +#include "APIMigrationHelper.hpp" #include "ObjectState.hpp" #include "Utility.hpp" #include "CreateCommand.hpp" @@ -43,7 +44,7 @@ void CreateCommand::GetStoryFromObjectState (const GS::ObjectState& os, const do API_StoryInfo storyInfo; BNZeroMemory (&storyInfo, sizeof (API_StoryInfo)); - ACAPI_Environment(APIEnv_GetStorySettingsID, &storyInfo); + ACAPI_ProjectSetting_GetStorySettings (&storyInfo); API_StoryCmdType command; @@ -59,13 +60,13 @@ void CreateCommand::GetStoryFromObjectState (const GS::ObjectState& os, const do command.action = APIStory_InsAbove; command.height = level.elevation - actStory.level; command.index = actStory.index; - ACAPI_Environment (APIEnv_ChangeStorySettingsID, &command); + ACAPI_ProjectSetting_ChangeStorySettings (&command); BNZeroMemory (&command, sizeof (API_StoryCmdType)); command.action = APIStory_SetHeight; command.height = (*storyInfo.data)[i + 1].level - level.elevation; command.index = actStory.index + 1; - ACAPI_Environment (APIEnv_ChangeStorySettingsID, &command); + ACAPI_ProjectSetting_ChangeStorySettings (&command); break; } else if (level.elevation < actStory.level - EPS) { @@ -74,7 +75,7 @@ void CreateCommand::GetStoryFromObjectState (const GS::ObjectState& os, const do command.action = APIStory_InsBelow; command.height = actStory.level - level.elevation; command.index = actStory.index; - ACAPI_Environment (APIEnv_ChangeStorySettingsID, &command); + ACAPI_ProjectSetting_ChangeStorySettings (&command); break; } else if (i == (storyInfo.lastStory - storyInfo.firstStory) && nextStory.level <= level.elevation) { @@ -83,7 +84,7 @@ void CreateCommand::GetStoryFromObjectState (const GS::ObjectState& os, const do command.action = APIStory_InsAbove; command.height = level.elevation - actStory.level; command.index = storyInfo.lastStory; - ACAPI_Environment (APIEnv_ChangeStorySettingsID, &command); + ACAPI_ProjectSetting_ChangeStorySettings (&command); } } @@ -104,9 +105,8 @@ GSErrCode CreateCommand::GetElementBaseFromObjectState (const GS::ObjectState& o BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_LayerID; attribute.header.uniStringNamePtr = &layer; - err = ACAPI_Attribute_Get (&attribute); - if (err == NoError) { + if (NoError == ACAPI_Attribute_Get (&attribute)) { element.header.layer = attribute.header.index; ACAPI_ELEMENT_MASK_SET (elementMask, API_Elem_Head, layer); } @@ -189,8 +189,11 @@ GS::ObjectState CreateCommand::Execute (const GS::ObjectState& parameters, GS::P } } - if (err == NoError) + if (err == NoError) { err = ImportClassificationsAndProperties (objectState, element.header.guid); + if (err != NoError) + err = NoError; // don't fail because of classification systems + } } GS::ObjectState applicationObject; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateDirectShape.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateDirectShape.cpp index acbd7ef67a..a7b4d29250 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateDirectShape.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateDirectShape.cpp @@ -1,4 +1,6 @@ #include "CreateDirectShape.hpp" + +#include "APIMigrationHelper.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -79,8 +81,7 @@ GSErrCode CreateDirectShape::GetElementFromObjectState (const GS::ObjectState& o API_Attribute materialAttribute; err = attributeManager.GetMaterial (material, materialAttribute); if (NoError == err) { - overrideMaterial.attributeIndex = materialAttribute.header.index; - overrideMaterial.overridden = true; + SetAPIOverriddenAttribute (overrideMaterial, materialAttribute.header.index); } } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateObject.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateObject.cpp index 05d7a380d9..7381415197 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateObject.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateObject.cpp @@ -1,10 +1,13 @@ -#include "APIHelper.hpp" #include "CreateObject.hpp" + +#include "APIMigrationHelper.hpp" +#include "APIHelper.hpp" #include "LibpartImportManager.hpp" #include "ResourceIds.hpp" #include "Utility.hpp" #include "DGModule.hpp" #include "FieldNames.hpp" +#include "Point.hpp" #include "ModelInfo.hpp" using namespace FieldNames; @@ -73,7 +76,7 @@ GSErrCode CreateObject::GetElementFromObjectState (const GS::ObjectState& os, Int32 addParNumDef = 0; API_AddParType **addParDefault = nullptr; - err = ACAPI_LibPart_GetParams (libPart.index, nullptr, nullptr, &addParNumDef, &addParDefault); + err = ACAPI_LibraryPart_GetParams (libPart.index, nullptr, nullptr, &addParNumDef, &addParDefault); if (err != NoError) return err; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.cpp index 813a11ce43..d9582c709a 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.cpp @@ -54,7 +54,7 @@ bool CreateOpeningBase::CheckEnvironment (const GS::ObjectState& os, API_Element return false; // Set its parent - API_ElemTypeID elementType = Utility::GetElementType (elem.header).typeID; + API_ElemTypeID elementType = Utility::GetElementType (element.header).typeID; if (elementType == API_DoorID) { element.door.owner = parentArchicadId; } else if (elementType == API_WindowID) { diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.hpp index a353df8212..fb6bc4394f 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.hpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateOpeningBase.hpp @@ -1,6 +1,7 @@ #ifndef CREATE_OPENING_BASE #define CREATE_OPENING_BASE +#include "APIMigrationHelper.hpp" #include "CreateCommand.hpp" #include "FieldNames.hpp" #include "TypeNameTables.hpp" @@ -265,7 +266,7 @@ GSErrCode GetOpeningBaseFromObjectState (const GS::ObjectState& os, T& element, BNZeroMemory (&libPart, sizeof (API_LibPart)); GS::ucscpy (libPart.docu_UName, libPartName.ToUStr ()); - err = ACAPI_LibPart_Search (&libPart, false, true); + err = ACAPI_LibraryPart_Search (&libPart, false, true); if (err == NoError) { element.openingBase.libInd = libPart.index; ACAPI_ELEMENT_MASK_SET (mask, T, openingBase.libInd); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateRoof.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateRoof.cpp index 4eb3fbc1cc..2a0cde0d11 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateRoof.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateRoof.cpp @@ -1,4 +1,6 @@ #include "CreateRoof.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -335,23 +337,15 @@ GSErrCode CreateRoof::GetElementFromObjectState (const GS::ObjectState& os, } } - // Override cut fill pen - if (os.Contains (Roof::CutFillPen)) { - element.roof.shellBase.penOverride.overrideCutFillPen = true; - os.Get (Roof::CutFillPen, element.roof.shellBase.penOverride.cutFillPen); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.penOverride.overrideCutFillPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (os.Contains (Roof::CutFillBackgroundPen)) { - element.roof.shellBase.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Roof::CutFillBackgroundPen, element.roof.shellBase.penOverride.cutFillBackgroundPen); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.penOverride.overrideCutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.penOverride.cutFillBackgroundPen); - } + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Roof::CutFillPen, + Roof::CutFillBackgroundPen, + element.roof.shellBase, + elementMask) + != NoError) + return Error; // Outlines @@ -488,9 +482,9 @@ GSErrCode CreateRoof::GetElementFromObjectState (const GS::ObjectState& os, // Model // Overridden materials - element.roof.shellBase.topMat.overridden = false; + ResetAPIOverriddenAttribute (element.roof.shellBase.topMat); if (os.Contains (Roof::TopMat)) { - element.roof.shellBase.topMat.overridden = true; + os.Get (Roof::TopMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -500,16 +494,16 @@ GSErrCode CreateRoof::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.roof.shellBase.topMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.topMat.attributeIndex); + SetAPIOverriddenAttribute (element.roof.shellBase.topMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeIndexField (shellBase.topMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.topMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeBoolField (shellBase.topMat)); - element.roof.shellBase.sidMat.overridden = false; + ResetAPIOverriddenAttribute (element.roof.shellBase.sidMat); if (os.Contains (Roof::SideMat)) { - element.roof.shellBase.sidMat.overridden = true; + os.Get (Roof::SideMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -519,16 +513,15 @@ GSErrCode CreateRoof::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.roof.shellBase.sidMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.sidMat.attributeIndex); + SetAPIOverriddenAttribute (element.roof.shellBase.sidMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeIndexField (shellBase.sidMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.sidMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeBoolField (shellBase.sidMat)); - element.roof.shellBase.botMat.overridden = false; + ResetAPIOverriddenAttribute (element.roof.shellBase.botMat); if (os.Contains (Roof::BotMat)) { - element.roof.shellBase.botMat.overridden = true; os.Get (Roof::BotMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -538,12 +531,12 @@ GSErrCode CreateRoof::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.roof.shellBase.botMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.botMat.attributeIndex); + SetAPIOverriddenAttribute (element.roof.shellBase.botMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeIndexField (shellBase.botMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, shellBase.botMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_RoofType, GetAPIOverriddenAttributeBoolField (shellBase.botMat)); // The overridden materials are chained if (os.Contains (Roof::MaterialsChained)) { diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateShell.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateShell.cpp index 965f4175c1..f65db5c364 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateShell.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateShell.cpp @@ -1,4 +1,6 @@ #include "CreateShell.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -227,7 +229,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (begShapeEdgeOs.Contains (Shell::BegShapeEdgeSideMaterial)) { - element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial.overridden = true; + begShapeEdgeOs.Get (Shell::BegShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -237,11 +239,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.begShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.extrudedShell.begShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.begShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.extrudedShell.begShapeEdgeData.sideMaterial)); } // Edge type @@ -276,7 +278,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (endShapeEdgeOs.Contains (Shell::EndShapeEdgeSideMaterial)) { - element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial.overridden = true; + endShapeEdgeOs.Get (Shell::EndShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -286,11 +288,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.endShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField(u.extrudedShell.endShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.endShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.extrudedShell.endShapeEdgeData.sideMaterial)); } // Edge type @@ -325,7 +327,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (extrudedEdgeOs1.Contains (Shell::ExtrudedEdgeSideMaterial1)) { - element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.overridden = true; + extrudedEdgeOs1.Get (Shell::ExtrudedEdgeSideMaterial1, attributeName); if (!attributeName.IsEmpty ()) { @@ -335,11 +337,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.extrudedShell.extrudedEdgeDatas[0].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.extrudedShell.extrudedEdgeDatas[0].sideMaterial)); } // Edge type @@ -374,7 +376,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (extrudedEdgeOs2.Contains (Shell::ExtrudedEdgeSideMaterial1)) { - element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.overridden = true; + extrudedEdgeOs2.Get (Shell::ExtrudedEdgeSideMaterial1, attributeName); if (!attributeName.IsEmpty ()) { @@ -384,11 +386,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.extrudedShell.extrudedEdgeDatas[1].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.extrudedShell.extrudedEdgeDatas[1].sideMaterial)); } // Edge type @@ -477,7 +479,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (begShapeEdgeOs.Contains (Shell::BegShapeEdgeSideMaterial)) { - element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial.overridden = true; + begShapeEdgeOs.Get (Shell::BegShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -487,11 +489,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.begShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.revolvedShell.begShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.begShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.revolvedShell.begShapeEdgeData.sideMaterial)); } // Edge type @@ -526,7 +528,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (endShapeEdgeOs.Contains (Shell::EndShapeEdgeSideMaterial)) { - element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial.overridden = true; + endShapeEdgeOs.Get (Shell::EndShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -536,11 +538,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.endShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.revolvedShell.endShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.endShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.revolvedShell.endShapeEdgeData.sideMaterial)); } // Edge type @@ -575,7 +577,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (revolvedEdgeOs1.Contains (Shell::RevolvedEdgeSideMaterial1)) { - element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.overridden = true; + revolvedEdgeOs1.Get (Shell::RevolvedEdgeSideMaterial1, attributeName); if (!attributeName.IsEmpty ()) { @@ -585,11 +587,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.revolvedShell.revolvedEdgeDatas[0].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.revolvedShell.revolvedEdgeDatas[0].sideMaterial)); } // Edge type @@ -624,7 +626,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (revolvedEdgeOs2.Contains (Shell::RevolvedEdgeSideMaterial1)) { - element.shell.u.revolvedShell.revolvedEdgeDatas[1].sideMaterial.overridden = true; + revolvedEdgeOs2.Get (Shell::RevolvedEdgeSideMaterial1, attributeName); if (!attributeName.IsEmpty ()) { @@ -634,11 +636,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.revolvedShell.revolvedEdgeDatas[1].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.revolvedEdgeDatas[1].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.revolvedShell.revolvedEdgeDatas[1].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.revolvedShell.revolvedEdgeDatas[1].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.revolvedShell.revolvedEdgeDatas[1].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.revolvedShell.revolvedEdgeDatas[1].sideMaterial)); } // Edge type @@ -716,7 +718,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (begShapeEdgeOs.Contains (Shell::BegShapeEdgeSideMaterial)) { - element.shell.u.ruledShell.begShapeEdgeData.sideMaterial.overridden = true; + begShapeEdgeOs.Get (Shell::BegShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -726,11 +728,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.ruledShell.begShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.begShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.ruledShell.begShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.ruledShell.begShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.begShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.ruledShell.begShapeEdgeData.sideMaterial)); } // Edge type @@ -765,7 +767,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (endShapeEdgeOs.Contains (Shell::EndShapeEdgeSideMaterial)) { - element.shell.u.ruledShell.endShapeEdgeData.sideMaterial.overridden = true; + endShapeEdgeOs.Get (Shell::EndShapeEdgeSideMaterial, attributeName); if (!attributeName.IsEmpty ()) { @@ -775,11 +777,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.ruledShell.endShapeEdgeData.sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.endShapeEdgeData.sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.ruledShell.endShapeEdgeData.sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.ruledShell.endShapeEdgeData.sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.endShapeEdgeData.sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.ruledShell.endShapeEdgeData.sideMaterial)); } // Edge type @@ -814,7 +816,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (ruledEdgeOs1.Contains (Shell::RuledEdgeSideMaterial1)) { - element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.overridden = true; + ruledEdgeOs1.Get (Shell::RuledEdgeSideMaterial1, attributeName); if (!attributeName.IsEmpty ()) { @@ -824,11 +826,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.ruledEdgeDatas[0].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.ruledShell.ruledEdgeDatas[0].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.ruledEdgeDatas[0].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.ruledShell.ruledEdgeDatas[0].sideMaterial)); } // Edge type @@ -863,7 +865,7 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Overridden side material if (ruledEdgeOs2.Contains (Shell::RuledEdgeSideMaterial2)) { - element.shell.u.ruledShell.ruledEdgeDatas[1].sideMaterial.overridden = true; + ruledEdgeOs2.Get (Shell::RuledEdgeSideMaterial2, attributeName); if (!attributeName.IsEmpty ()) { @@ -873,11 +875,11 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.u.ruledShell.ruledEdgeDatas[1].sideMaterial.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.ruledEdgeDatas[1].sideMaterial.attributeIndex); + SetAPIOverriddenAttribute (element.shell.u.ruledShell.ruledEdgeDatas[1].sideMaterial, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (u.ruledShell.ruledEdgeDatas[1].sideMaterial)); } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, u.ruledShell.ruledEdgeDatas[1].sideMaterial.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (u.ruledShell.ruledEdgeDatas[1].sideMaterial)); } // Edge type @@ -1059,23 +1061,15 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.sectContLtype); } - // Override cut fill pen - if (os.Contains (Shell::CutFillPen)) { - element.shell.shellBase.penOverride.overrideCutFillPen = true; - os.Get (Shell::CutFillPen, element.shell.shellBase.penOverride.cutFillPen); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.penOverride.overrideCutFillPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (os.Contains (Shell::CutFillBackgroundPen)) { - element.shell.shellBase.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Shell::CutFillBackgroundPen, element.shell.shellBase.penOverride.cutFillBackgroundPen); - - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.penOverride.overrideCutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.penOverride.cutFillBackgroundPen); - } + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Shell::CutFillPen, + Shell::CutFillBackgroundPen, + element.shell.shellBase, + elementMask) + != NoError) + return Error; // Outlines @@ -1212,9 +1206,9 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, // Model // Overridden materials - element.shell.shellBase.topMat.overridden = false; + ResetAPIOverriddenAttribute (element.shell.shellBase.topMat); if (os.Contains (Shell::TopMat)) { - element.shell.shellBase.topMat.overridden = true; + os.Get (Shell::TopMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -1224,16 +1218,16 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.shellBase.topMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.topMat.attributeIndex); + SetAPIOverriddenAttribute (element.shell.shellBase.topMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (shellBase.topMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.topMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (shellBase.topMat)); - element.shell.shellBase.sidMat.overridden = false; + ResetAPIOverriddenAttribute (element.shell.shellBase.sidMat); if (os.Contains (Shell::SideMat)) { - element.shell.shellBase.sidMat.overridden = true; + os.Get (Shell::SideMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -1243,16 +1237,16 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.shellBase.sidMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.sidMat.attributeIndex); + SetAPIOverriddenAttribute (element.shell.shellBase.sidMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (shellBase.sidMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.sidMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (shellBase.sidMat)); - element.shell.shellBase.botMat.overridden = false; + ResetAPIOverriddenAttribute (element.shell.shellBase.botMat); if (os.Contains (Shell::BotMat)) { - element.shell.shellBase.botMat.overridden = true; + os.Get (Shell::BotMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -1262,12 +1256,12 @@ GSErrCode CreateShell::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.shell.shellBase.botMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.botMat.attributeIndex); + SetAPIOverriddenAttribute (element.shell.shellBase.botMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeIndexField (shellBase.botMat)); } } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, shellBase.botMat.overridden); + ACAPI_ELEMENT_MASK_SET (elementMask, API_ShellType, GetAPIOverriddenAttributeBoolField (shellBase.botMat)); // The overridden materials are chained if (os.Contains (Shell::MaterialsChained)) { diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateSlab.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateSlab.cpp index 99fde7a864..ca852d45a7 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateSlab.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateSlab.cpp @@ -1,4 +1,6 @@ #include "CreateSlab.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -220,21 +222,15 @@ GSErrCode CreateSlab::GetElementFromObjectState (const GS::ObjectState& os, ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, sectContLtype); } - // Override cut fill pen - if (os.Contains (Slab::cutFillPen)) { - element.slab.penOverride.overrideCutFillPen = true; - os.Get (Slab::cutFillPen, element.slab.penOverride.cutFillPen); - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, penOverride.overrideCutFillPen); - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (os.Contains (Slab::cutFillBackgroundPen)) { - element.slab.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Slab::cutFillBackgroundPen, element.slab.penOverride.cutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, penOverride.overrideCutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, penOverride.cutFillBackgroundPen); - } + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Slab::cutFillPen, + Slab::cutFillBackgroundPen, + element.slab, + mask) + != NoError) + return Error; // Outlines @@ -357,9 +353,9 @@ GSErrCode CreateSlab::GetElementFromObjectState (const GS::ObjectState& os, // Model // Overridden materials - element.slab.topMat.overridden = false; + ResetAPIOverriddenAttribute (element.slab.topMat); if (os.Contains (Slab::topMat)) { - element.slab.topMat.overridden = true; + os.Get (Slab::topMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -369,16 +365,16 @@ GSErrCode CreateSlab::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.slab.topMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, topMat.attributeIndex); + SetAPIOverriddenAttribute (element.slab.topMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeIndexField (topMat)); } } } - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, topMat.overridden); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeBoolField (topMat)); - element.slab.sideMat.overridden = false; + ResetAPIOverriddenAttribute (element.slab.sideMat); if (os.Contains (Slab::sideMat)) { - element.slab.sideMat.overridden = true; + os.Get (Slab::sideMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -388,16 +384,16 @@ GSErrCode CreateSlab::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.slab.sideMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, sideMat.attributeIndex); + SetAPIOverriddenAttribute (element.slab.sideMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeIndexField (sideMat)); } } } - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, sideMat.overridden); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeBoolField (sideMat)); - element.slab.botMat.overridden = false; + ResetAPIOverriddenAttribute (element.slab.botMat); if (os.Contains (Slab::botMat)) { - element.slab.botMat.overridden = true; + os.Get (Slab::botMat, attributeName); if (!attributeName.IsEmpty ()) { @@ -407,12 +403,12 @@ GSErrCode CreateSlab::GetElementFromObjectState (const GS::ObjectState& os, CHCopyC (attributeName.ToCStr (), attribute.header.name); if (NoError == ACAPI_Attribute_Get (&attribute)) { - element.slab.botMat.attributeIndex = attribute.header.index; - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, botMat.attributeIndex); + SetAPIOverriddenAttribute (element.slab.botMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeIndexField (botMat)); } } } - ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, botMat.overridden); + ACAPI_ELEMENT_MASK_SET (mask, API_SlabType, GetAPIOverriddenAttributeBoolField (botMat)); // The overridden materials are chained if (os.Contains (Slab::materialsChained)) { diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateWall.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateWall.cpp index c7cf90d42f..a69368bd4a 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateWall.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateWall.cpp @@ -1,4 +1,6 @@ #include "CreateWall.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -71,8 +73,7 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, // The floor index and bottom offset of the wall if (os.Contains (ElementBase::Level)) { GetStoryFromObjectState (os, startPoint.z, element.header.floorInd, element.wall.bottomOffset); - } - else { + } else { Utility::SetStoryLevelAndFloor (startPoint.z, element.header.floorInd, element.wall.bottomOffset); } ACAPI_ELEMENT_MASK_SET (elementMask, API_Elem_Head, floorInd); @@ -273,7 +274,7 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, referenceLineLocation); } - // The offset of the walls base line from reference line + // The offset of the wall�s base line from reference line if (os.Contains (Wall::ReferenceLineOffset)) { os.Get (Wall::ReferenceLineOffset, element.wall.offset); ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, offset); @@ -339,13 +340,13 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, // Floor Plan and Section - Cut Surfaces parameters - // The pen index of walls cut contour line + // The pen index of wall�s cut contour line if (os.Contains (Wall::CutLinePenIndex)) { os.Get (Wall::CutLinePenIndex, element.wall.contPen); ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, contPen); } - // The linetype name of walls cut contour line + // The linetype name of wall�s cut contour line if (os.Contains (Wall::CutLinetypeName)) { os.Get (Wall::CutLinetypeName, attributeName); @@ -362,31 +363,25 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, contLtype); } - // Override cut fill pen - if (os.Contains (Wall::OverrideCutFillPenIndex)) { - element.wall.penOverride.overrideCutFillPen = true; - os.Get (Wall::OverrideCutFillPenIndex, element.wall.penOverride.cutFillPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, penOverride.overrideCutFillPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, penOverride.cutFillPen); - } - - // Override cut fill background pen - if (os.Contains (Wall::OverrideCutFillBackgroundPenIndex)) { - element.wall.penOverride.overrideCutFillBackgroundPen = true; - os.Get (Wall::OverrideCutFillBackgroundPenIndex, element.wall.penOverride.cutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, penOverride.overrideCutFillBackgroundPen); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, penOverride.cutFillBackgroundPen); - } + // Override cut fill and cut fill backgound pens + if (CommandHelpers::SetCutfillPens( + os, + Wall::OverrideCutFillPenIndex, + Wall::OverrideCutFillBackgroundPenIndex, + element.wall, + elementMask) + != NoError) + return Error; // Floor Plan and Section - Outlines parameters - // The pen index of walls uncut contour line + // The pen index of wall�s uncut contour line if (os.Contains (Wall::UncutLinePenIndex)) { os.Get (Wall::UncutLinePenIndex, element.wall.contPen3D); ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, contPen3D); } - // The linetype name of walls uncut contour line + // The linetype name of wall�s uncut contour line if (os.Contains (Wall::UncutLinetypeName)) { os.Get (Wall::UncutLinetypeName, attributeName); @@ -403,13 +398,13 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, belowViewLineType); } - // The pen index of walls overhead contour line + // The pen index of wall�s overhead contour line if (os.Contains (Wall::OverheadLinePenIndex)) { os.Get (Wall::OverheadLinePenIndex, element.wall.aboveViewLinePen); ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, aboveViewLinePen); } - // The linetype name of walls overhead contour line + // The linetype name of wall�s overhead contour line if (os.Contains (Wall::OverheadLinetypeName)) { os.Get (Wall::OverheadLinetypeName, attributeName); @@ -429,8 +424,9 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, // Model - Override Surfaces // The reference overridden material name + ResetAPIOverriddenAttribute (element.wall.refMat); if (os.Contains (Wall::ReferenceMaterialName)) { - element.wall.refMat.overridden = true; + //element.wall.refMat.overridden = true; os.Get (Wall::ReferenceMaterialName, attributeName); if (!attributeName.IsEmpty ()) { @@ -439,12 +435,13 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, attribute.header.typeID = API_MaterialID; CHCopyC (attributeName.ToCStr (), attribute.header.name); - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.wall.refMat.attributeIndex = attribute.header.index; + if (NoError == ACAPI_Attribute_Get (&attribute)) { + SetAPIOverriddenAttribute (element.wall.refMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeIndexField (refMat)); + } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, refMat.overridden); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, refMat.attributeIndex); } + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeBoolField (refMat)); // The index of the reference material start and end edge index if (os.Contains (Wall::ReferenceMaterialStartIndex)) { @@ -458,8 +455,9 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, } // The opposite overridden material name + ResetAPIOverriddenAttribute (element.wall.oppMat); if (os.Contains (Wall::OppositeMaterialName)) { - element.wall.oppMat.overridden = true; + //element.wall.oppMat.overridden = true; os.Get (Wall::OppositeMaterialName, attributeName); if (!attributeName.IsEmpty ()) { @@ -468,12 +466,13 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, attribute.header.typeID = API_MaterialID; CHCopyC (attributeName.ToCStr (), attribute.header.name); - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.wall.oppMat.attributeIndex = attribute.header.index; + if (NoError == ACAPI_Attribute_Get (&attribute)) { + SetAPIOverriddenAttribute (element.wall.oppMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeIndexField (oppMat)); + } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, oppMat.overridden); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, oppMat.attributeIndex); } + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeBoolField (oppMat)); // The index of the opposite material start and end edge index if (os.Contains (Wall::OppositeMaterialStartIndex)) { @@ -487,8 +486,9 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, } // The side overridden material name + ResetAPIOverriddenAttribute (element.wall.sidMat); if (os.Contains (Wall::SideMaterialName)) { - element.wall.sidMat.overridden = true; + //element.wall.sidMat.overridden = true; os.Get (Wall::SideMaterialName, attributeName); if (!attributeName.IsEmpty ()) { @@ -497,12 +497,13 @@ GSErrCode CreateWall::GetElementFromObjectState (const GS::ObjectState& os, attribute.header.typeID = API_MaterialID; CHCopyC (attributeName.ToCStr (), attribute.header.name); - if (NoError == ACAPI_Attribute_Get (&attribute)) - element.wall.sidMat.attributeIndex = attribute.header.index; + if (NoError == ACAPI_Attribute_Get (&attribute)) { + SetAPIOverriddenAttribute (element.wall.sidMat, attribute.header.index); + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeIndexField (sidMat)); + } } - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, sidMat.overridden); - ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, sidMat.attributeIndex); } + ACAPI_ELEMENT_MASK_SET (elementMask, API_WallType, GetAPIOverriddenAttributeBoolField (sidMat)); // The overridden materials are chained if (os.Contains (Wall::MaterialsChained)) { diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/FinishReceiveTransaction.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/FinishReceiveTransaction.cpp index 81496e3436..960e525ca9 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/FinishReceiveTransaction.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/FinishReceiveTransaction.cpp @@ -1,6 +1,7 @@ #include "FinishReceiveTransaction.hpp" #include "LibpartImportManager.hpp" #include "ClassificationImportManager.hpp" +#include "PropertyExportManager.hpp" #include "ResourceIds.hpp" @@ -9,6 +10,7 @@ GS::ObjectState AddOnCommands::FinishReceiveTransaction::Execute (const GS::Obje AttributeManager::DeleteInstance(); LibpartImportManager::DeleteInstance (); ClassificationImportManager::DeleteInstance (); + PropertyExportManager::DeleteInstance (); return GS::ObjectState (); } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetBeamData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetBeamData.cpp index d8a17f3c46..16570eb3f5 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetBeamData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetBeamData.cpp @@ -1,4 +1,7 @@ #include "GetBeamData.hpp" + +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -40,11 +43,6 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (elem, memo, os); - if (NoError != err) - return err; - // Positioning API_StoryType story = Utility::GetStory (elem.beam.head.floorInd); os.Add (ElementBase::Level, Objects::Level (story)); @@ -85,7 +83,7 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, GS::ObjectState allSegments; GSSize segmentsCount = BMGetPtrSize (reinterpret_cast(memo.beamSegments)) / sizeof (API_BeamSegmentType); - DBASSERT (segmentsCount == elem.beam.nSegments); + DBASSERT (segmentsCount == (GSSize)elem.beam.nSegments); for (GSSize idx = 0; idx < segmentsCount; ++idx) { API_BeamSegmentType beamSegment = memo.beamSegments[idx]; @@ -100,10 +98,10 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, // The left overridden material name int countOverriddenMaterial = 0; - if (beamSegment.leftMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (beamSegment.leftMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = beamSegment.leftMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (beamSegment.leftMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -111,10 +109,10 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, } // The top overridden material name - if (beamSegment.topMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (beamSegment.topMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = beamSegment.topMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (beamSegment.topMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -122,10 +120,10 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, } // The right overridden material name - if (beamSegment.rightMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (beamSegment.rightMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = beamSegment.rightMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (beamSegment.rightMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -133,10 +131,10 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, } // The bottom overridden material name - if (beamSegment.bottomMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (beamSegment.bottomMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = beamSegment.bottomMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (beamSegment.bottomMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -144,10 +142,10 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, } // The ends overridden material name - if (beamSegment.endsMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (beamSegment.endsMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = beamSegment.endsMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (beamSegment.endsMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -227,15 +225,8 @@ GS::ErrCode GetBeamData::SerializeElementType (const API_Element& elem, os.Add (Beam::CutContourLinetypeName, GS::UniString{attrib.header.name}); } - // Override cut fill pen - if (elem.beam.penOverride.overrideCutFillPen) { - os.Add (Beam::OverrideCutFillPenIndex, elem.beam.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (elem.beam.penOverride.overrideCutFillBackgroundPen) { - os.Add (Beam::OverrideCutFillBackgroundPenIndex, elem.beam.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (elem.beam, os, Beam::OverrideCutFillPenIndex, Beam::OverrideCutFillBackgroundPenIndex); // Floor Plan and Section - Outlines diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetColumnData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetColumnData.cpp index 6a3d3251c4..a13881594e 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetColumnData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetColumnData.cpp @@ -1,4 +1,6 @@ #include "GetColumnData.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -37,11 +39,6 @@ GS::ErrCode GetColumnData::SerializeElementType (const API_Element& elem, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (elem, memo, os); - if (NoError != err) - return err; - // Positioning - geometry API_StoryType story = Utility::GetStory (elem.column.head.floorInd); os.Add (ElementBase::Level, Objects::Level (story)); @@ -90,7 +87,7 @@ GS::ErrCode GetColumnData::SerializeElementType (const API_Element& elem, GS::ObjectState allSegments; GSSize segmentsCount = BMGetPtrSize (reinterpret_cast(memo.columnSegments)) / sizeof (API_ColumnSegmentType); - DBASSERT (segmentsCount == elem.column.nSegments); + DBASSERT (segmentsCount == (GSSize)elem.column.nSegments); for (GSSize idx = 0; idx < segmentsCount; ++idx) { API_ColumnSegmentType columnSegment = memo.columnSegments[idx]; @@ -122,10 +119,10 @@ GS::ErrCode GetColumnData::SerializeElementType (const API_Element& elem, // The extrusion overridden material name int countOverriddenMaterial = 0; - if (columnSegment.extrusionSurfaceMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (columnSegment.extrusionSurfaceMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = columnSegment.extrusionSurfaceMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (columnSegment.extrusionSurfaceMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -133,10 +130,10 @@ GS::ErrCode GetColumnData::SerializeElementType (const API_Element& elem, } // The ends overridden material name - if (columnSegment.endsMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (columnSegment.endsMaterial)) { BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_MaterialID; - attrib.header.index = columnSegment.endsMaterial.attributeIndex; + attrib.header.index = GetAPIOverriddenAttribute (columnSegment.endsMaterial); if (NoError == ACAPI_Attribute_Get (&attrib)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -199,18 +196,11 @@ GS::ErrCode GetColumnData::SerializeElementType (const API_Element& elem, os.Add (Column::VeneerLinetypeName, GS::UniString{attrib.header.name}); } - // Override cut fill pen - if (elem.column.penOverride.overrideCutFillPen) { - os.Add (Column::OverrideCutFillPenIndex, elem.column.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (elem.column.penOverride.overrideCutFillBackgroundPen) { - os.Add (Column::OverrideCutFillBackgroundPenIndex, elem.column.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (elem.column, os, Column::OverrideCutFillPenIndex, Column::OverrideCutFillBackgroundPenIndex); // Floor Plan and Section - Outlines - ; + // The pen index of column uncut contour line os.Add (Column::UncutLinePenIndex, elem.column.belowViewLinePen); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.cpp index acea1e8554..841b77126c 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.cpp @@ -2,19 +2,230 @@ #include "ObjectState.hpp" #include "FieldNames.hpp" #include "Utility.hpp" +#include "PropertyExportManager.hpp" namespace AddOnCommands { - -GS::ErrCode GetDataCommand::ExportClassificationsAndProperties (const API_Element& elem, GS::ObjectState& os) const + +GS::ErrCode SerializePropertyGroups (const GS::Array& definitions, const GS::Array& properties, std::function propertyGroupListAdder) +{ + GS::ErrCode err = NoError; + + GS::HashTable>> propertiesByGroup; + + for (UInt32 i = 0; i < definitions.GetSize (); i++) { + API_PropertyDefinition definition = definitions[i]; + + API_PropertyGroup group; + group.guid = definition.groupGuid; + err = ACAPI_Property_GetPropertyGroup (group); + if (err != NoError) + continue; + + const GS::UniString& groupName = group.name; + const API_Guid& groupID = group.guid; + + if (propertiesByGroup.ContainsKey (groupID)) { + propertiesByGroup[groupID].second.Push (definition); + } else { + GS::Array definitionsByGroup; + definitionsByGroup.Push (definition); + propertiesByGroup.Add (groupID, GS::Pair> (groupName, definitionsByGroup)); + } + } + + for (auto& propertyByGroup : propertiesByGroup) { + const API_Guid& groupID = *propertyByGroup.key; + + GS::ObjectState propertyGroupsOs; + propertyGroupsOs.Add (FieldNames::ElementBase::PropertyGroup::Name, propertyByGroup.value->first); + const auto& propertyListAdder = propertyGroupsOs.AddList (FieldNames::ElementBase::PropertyGroup::PropertList); + + bool propertyAdded = false; + for (auto& apiProperty : properties) { + if (apiProperty.definition.groupGuid != groupID) + continue; + + if (apiProperty.status == API_Property_HasValue && apiProperty.value.variantStatus == API_VariantStatusNormal) { + switch (apiProperty.definition.collectionType) { + case API_PropertySingleCollectionType: + case API_PropertySingleChoiceEnumerationCollectionType: + { + GS::ObjectState propertyOs; + propertyOs.Add (FieldNames::ElementBase::Property::Name, apiProperty.definition.name); + + switch (apiProperty.value.singleVariant.variant.type) { + case API_PropertyIntegerValueType: + propertyOs.Add (FieldNames::ElementBase::Property::Value, apiProperty.value.singleVariant.variant.intValue); + break; + case API_PropertyRealValueType: + if (GS::ClassifyDouble (apiProperty.value.singleVariant.variant.doubleValue) == GS::DoubleClass::Normal) + propertyOs.Add (FieldNames::ElementBase::Property::Value, apiProperty.value.singleVariant.variant.doubleValue); + break; + case API_PropertyStringValueType: + propertyOs.Add (FieldNames::ElementBase::Property::Value, apiProperty.value.singleVariant.variant.uniStringValue); + break; + case API_PropertyBooleanValueType: + propertyOs.Add (FieldNames::ElementBase::Property::Value, apiProperty.value.singleVariant.variant.boolValue); + break; + case API_PropertyGuidValueType: + for (auto& possibleEnumValue : apiProperty.definition.possibleEnumValues) { + if (possibleEnumValue.keyVariant.guidValue == apiProperty.value.singleVariant.variant.guidValue) { + propertyOs.Add (FieldNames::ElementBase::Property::Value, possibleEnumValue.displayVariant.uniStringValue); + break; + } + } + break; + default: + continue; + } + + propertyListAdder (propertyOs); + propertyAdded = true; + break; + } + case API_PropertyListCollectionType: + case API_PropertyMultipleChoiceEnumerationCollectionType: + { + if (apiProperty.value.listVariant.variants.GetSize () == 0) + continue; + + GS::ObjectState propertyOs; + propertyOs.Add (FieldNames::ElementBase::Property::Name, apiProperty.definition.name); + + switch (apiProperty.value.listVariant.variants[0].type) { + case API_PropertyIntegerValueType: + { + const auto& valueListAdder = propertyOs.AddList (FieldNames::ElementBase::Property::Values); + for (auto value : apiProperty.value.listVariant.variants) { + valueListAdder (value.intValue); + } + break; + } + case API_PropertyRealValueType: + { + const auto& valueListAdder = propertyOs.AddList (FieldNames::ElementBase::Property::Values); + for (auto value : apiProperty.value.listVariant.variants) { + if (GS::ClassifyDouble (value.doubleValue) == GS::DoubleClass::Normal) + valueListAdder (value.doubleValue); + } + break; + } + case API_PropertyStringValueType: + { + const auto& valueListAdder = propertyOs.AddList (FieldNames::ElementBase::Property::Values); + for (auto value : apiProperty.value.listVariant.variants) { + valueListAdder (value.uniStringValue); + } + break; + } + case API_PropertyBooleanValueType: + { + const auto& valueListAdder = propertyOs.AddList (FieldNames::ElementBase::Property::Values); + for (auto value : apiProperty.value.listVariant.variants) { + valueListAdder (value.boolValue); + } + break; + } + case API_PropertyGuidValueType: + { + const auto& valueListAdder = propertyOs.AddList (FieldNames::ElementBase::Property::Values); + for (auto& possibleEnumValue : apiProperty.definition.possibleEnumValues) { + for (auto value : apiProperty.value.listVariant.variants) { + if (possibleEnumValue.keyVariant.guidValue == value.guidValue) { + valueListAdder (possibleEnumValue.displayVariant.uniStringValue); + break; + } + } + } + break; + } + default: + continue; + } + + propertyListAdder (propertyOs); + propertyAdded = true; + break; + } + case API_PropertyUndefinedCollectionType: + continue; + } + } + } + + if (propertyAdded) + propertyGroupListAdder (propertyGroupsOs); + } + + return NoError; +} + + +GS::ErrCode GetDataCommand::ExportProperties (const API_Element& element, const bool& sendProperties, const bool& sendListingParameters, const GS::Array>& systemItemPairs, GS::ObjectState& os) const +{ + GS::ErrCode err = NoError; + + if (!sendProperties && !sendListingParameters) + return NoError; + + GS::Array elementDefinitions; + GS::Array < GS::Pair>> componentsDefinitions; + + err = PropertyExportManager::GetInstance ()->GetElementDefinitions (element, sendProperties, sendListingParameters, systemItemPairs, elementDefinitions, componentsDefinitions); + if (err != NoError) + return false; + + // element properties + { + GS::Array properties; + err = ACAPI_Element_GetPropertyValues (element.header.guid, elementDefinitions, properties); + if (err == NoError && !properties.IsEmpty ()) { + const auto& propertyGroupListAdder = os.AddList (FieldNames::ElementBase::ElementProperties); + err = SerializePropertyGroups (elementDefinitions, properties, propertyGroupListAdder); + if (err != NoError) + return err; + } + } + + // components properties + auto componentPropertyListAdder = os.AddList (FieldNames::ElementBase::ComponentProperties); + + UInt32 componentNumber (1); + for (auto& componentDefinitions : componentsDefinitions) { + GS::Array properties; +#ifdef ServerMainVers_2700 + err = ACAPI_Element_GetPropertyValues (componentDefinitions.first, componentDefinitions.second, properties); +#else + err = ACAPI_ElemComponent_GetPropertyValues (componentDefinitions.first, componentDefinitions.second, properties); +#endif + if (err != NoError || properties.IsEmpty ()) + continue; + + GS::ObjectState componentPropertiesOs; + componentPropertiesOs.Add (FieldNames::ElementBase::ComponentProperty::Name, GS::String::SPrintf ("Component %d", componentNumber++)); + std::function propertyGroupListAdder = componentPropertiesOs.AddList (FieldNames::ElementBase::ComponentProperty::PropertyGroups); + + err = SerializePropertyGroups (componentDefinitions.second, properties, propertyGroupListAdder); + if (err != NoError) + continue; + + componentPropertyListAdder (componentPropertiesOs); + } + + return NoError; +} + + +GS::ErrCode GetDataCommand::ExportClassificationsAndProperties (const API_Element& element, GS::ObjectState& os, const bool& sendProperties, const bool& sendListingParameters) const { GS::ErrCode err = NoError; { GS::UniString typeName; - err = Utility::GetLocalizedElementTypeName (elem.header, typeName); + err = Utility::GetLocalizedElementTypeName (element.header, typeName); if (err != NoError) return err; @@ -22,7 +233,7 @@ GS::ErrCode GetDataCommand::ExportClassificationsAndProperties (const API_Elemen } GS::Array> systemItemPairs; - err = ACAPI_Element_GetClassificationItems (elem.header.guid, systemItemPairs); + err = ACAPI_Element_GetClassificationItems (element.header.guid, systemItemPairs); if (err != NoError) return err; @@ -54,7 +265,7 @@ GS::ErrCode GetDataCommand::ExportClassificationsAndProperties (const API_Elemen } } - return err; + return ExportProperties (element, sendProperties, sendListingParameters, systemItemPairs, os); } @@ -64,7 +275,7 @@ GS::UInt64 GetDataCommand::GetMemoMask () const } -GS::ErrCode GetDataCommand::SerializeElementType(const API_Element& elem, const API_ElementMemo& /*memo*/, GS::ObjectState& os) const +GS::ErrCode GetDataCommand::SerializeElementType(const API_Element& elem, const API_ElementMemo& /*memo*/, GS::ObjectState& os, const bool& sendProperties, const bool& sendListingParameters) const { GS::ErrCode err = NoError; @@ -78,7 +289,7 @@ GS::ErrCode GetDataCommand::SerializeElementType(const API_Element& elem, const os.Add(FieldNames::ElementBase::Layer, GS::UniString{attribute.header.name}); } - err = ExportClassificationsAndProperties (elem, os); + err = ExportClassificationsAndProperties (elem, os, sendProperties, sendListingParameters); return err; } @@ -93,6 +304,11 @@ GS::ObjectState GetDataCommand::Execute (const GS::ObjectState& parameters, [] (const GS::UniString& idStr) { return APIGuidFromString (idStr.ToCStr ()); } ); + bool sendProperties = false; + bool sendListingParameters = false; + parameters.Get (FieldNames::ElementBase::SendProperties, sendProperties); + parameters.Get (FieldNames::ElementBase::SendListingParameters, sendListingParameters); + GS::ObjectState result; const auto& listAdder = result.AddList (GetFieldName ()); for (const API_Guid& guid : elementGuids) { @@ -102,25 +318,29 @@ GS::ObjectState GetDataCommand::Execute (const GS::ObjectState& parameters, element.header.guid = guid; GSErrCode err = ACAPI_Element_Get (&element); - if (err != NoError) { + if (err != NoError) continue; - } // check for elem type if (API_ZombieElemID != GetElemTypeID ()) { API_ElemTypeID elementType = Utility::GetElementType (element.header).typeID; - if (elementType != GetElemTypeID ()) - { + if (elementType != GetElemTypeID ()) { continue; } } err = ACAPI_Element_GetMemo (guid, &memo, GetMemoMask ()); - if (err != NoError) continue; + if (err != NoError) + continue; GS::ObjectState os; + err = SerializeElementType (element, memo, os, sendProperties, sendListingParameters); + if (err != NoError) + continue; + err = SerializeElementType (element, memo, os); - if (err != NoError) continue; + if (err != NoError) + continue; listAdder (os); } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.hpp index aa81f1ada6..a46a9733d8 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.hpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDataCommand.hpp @@ -13,12 +13,19 @@ class GetDataCommand : public BaseCommand { virtual GS::UInt64 GetMemoMask () const; protected: - GS::ErrCode ExportClassificationsAndProperties(const API_Element& elem, GS::ObjectState& os) const; + GS::ErrCode ExportProperties (const API_Element& element, const bool& sendProperties, const bool& sendListingParameters, const GS::Array>& systemItemPairs, GS::ObjectState& os) const; + GS::ErrCode ExportClassificationsAndProperties(const API_Element& element, GS::ObjectState& os, const bool& sendProperties, const bool& sendListingParameters) const; virtual GS::ErrCode SerializeElementType (const API_Element& elem, const API_ElementMemo& memo, - GS::ObjectState& os) const; - + GS::ObjectState& os) const = 0; + + GS::ErrCode SerializeElementType (const API_Element& elem, + const API_ElementMemo& memo, + GS::ObjectState& os, + const bool& sendProperties, + const bool& sendListingParameters) const; + public: virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDoorData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDoorData.cpp index f67d7e8b61..a1781806cc 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDoorData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetDoorData.cpp @@ -26,14 +26,9 @@ API_ElemTypeID GetDoorData::GetElemTypeID () const GS::ErrCode GetDoorData::SerializeElementType (const API_Element& element, - const API_ElementMemo& memo, + const API_ElementMemo& /*memo*/, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - os.Add (ElementBase::ParentElementId, APIGuidToString (element.door.owner)); AddOnCommands::GetDoorWindowData (element.door, os); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetElementBaseData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetElementBaseData.cpp index f2aa202178..58bb1af715 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetElementBaseData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetElementBaseData.cpp @@ -33,14 +33,9 @@ GS::UInt64 GetElementBaseData::GetMemoMask () const GS::ErrCode GetElementBaseData::SerializeElementType (const API_Element& elem, - const API_ElementMemo& memo, + const API_ElementMemo& /*memo*/, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (elem, memo, os); - if (NoError != err) - return err; - // Positioning API_StoryType story = Utility::GetStory (elem.header.floorInd); os.Add (ElementBase::Level, Objects::Level (story)); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetGridElementData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetGridElementData.cpp index 544a8fea76..a7a93a54db 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetGridElementData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetGridElementData.cpp @@ -29,11 +29,6 @@ GS::ErrCode GetGridElementData::SerializeElementType (const API_Element& element const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - GS::UniString markerText; double angle = element.object.angle; double length = .0; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp index 025dfea734..5e5fa49c39 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp @@ -1,4 +1,6 @@ #include "GetModelForElements.hpp" + +#include "APIMigrationHelper.hpp" #include "ResourceIds.hpp" #include "Sight.hpp" #include "ModelInfo.hpp" @@ -220,13 +222,13 @@ static ModelInfo CalculateModelOfElement (const Modeler::Model3DViewer& modelVie static GS::ObjectState StoreModelOfElements (const GS::Array&applicationIds) { - GSErrCode err = ACAPI_Automate (APIDo_ShowAllIn3DID); + GSErrCode err = ACAPI_View_ShowAllIn3D (); if (err != NoError) { return {}; } Modeler::Sight* sight = nullptr; - err = ACAPI_3D_GetCurrentWindowSight ((void**) &sight); + err = ACAPI_Sight_GetCurrentWindowSight ((void**) &sight); if (err != NoError || sight == nullptr) { return {}; } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetObjectData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetObjectData.cpp index 5c44c41aac..6c22643496 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetObjectData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetObjectData.cpp @@ -26,14 +26,9 @@ API_ElemTypeID GetObjectData::GetElemTypeID() const GS::ErrCode GetObjectData::SerializeElementType (const API_Element& elem, - const API_ElementMemo& memo, + const API_ElementMemo& /*memo*/, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (elem, memo, os); - if (NoError != err) - return err; - API_StoryType story = Utility::GetStory (elem.object.head.floorInd); os.Add (ElementBase::Level, Objects::Level (story)); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetOpeningBaseData.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetOpeningBaseData.hpp index 166c416f9f..6f82f5782d 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetOpeningBaseData.hpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetOpeningBaseData.hpp @@ -4,6 +4,7 @@ // API #include "APIEnvir.h" #include "ACAPinc.h" +#include "APIMigrationHelper.hpp" #include "Objects/Point.hpp" #include "FieldNames.hpp" @@ -135,7 +136,7 @@ GSErrCode GetOpeningBaseData (const T& element, GS::ObjectState& os) BNZeroMemory (&libPart, sizeof (API_LibPart)); libPart.index = element.openingBase.libInd; - err = ACAPI_LibPart_Get (&libPart); + err = ACAPI_LibraryPart_Get (&libPart); if (err == NoError) os.Add (OpeningBase::LibraryPart, GS::UniString (libPart.docu_UName)); } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetProjectInfo.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetProjectInfo.cpp index c4f81d9df4..5331859da6 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetProjectInfo.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetProjectInfo.cpp @@ -1,3 +1,4 @@ +#include "APIMigrationHelper.hpp" #include "GetProjectInfo.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" @@ -26,7 +27,7 @@ GS::ObjectState GetProjectInfo::Execute (const GS::ObjectState& /*parameters*/, { API_ProjectInfo projectInfo{}; - const GSErrCode err = ACAPI_Environment (APIEnv_ProjectID, &projectInfo, nullptr); + const GSErrCode err = ACAPI_ProjectOperation_Project (&projectInfo); if (err != NoError) { return GS::ObjectState{}; } @@ -41,7 +42,7 @@ GS::ObjectState GetProjectInfo::Execute (const GS::ObjectState& /*parameters*/, os.Add (FieldNames::ProjectLocation, *projectInfo.projectPath); API_WorkingUnitPrefs unitPrefs; - ACAPI_Environment (APIEnv_GetPreferencesID, &unitPrefs, (void*) APIPrefs_WorkingUnitsID); + ACAPI_ProjectSetting_GetPreferences (&unitPrefs, APIPrefs_WorkingUnitsID); os.Add (FieldNames::ProjectLengthUnits, unitPrefs.lengthUnit); os.Add (FieldNames::ProjectAreaUnits, unitPrefs.areaUnit); os.Add (FieldNames::ProjectVolumeUnits, unitPrefs.volumeUnit); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetRoofData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetRoofData.cpp index 44de06038a..509661d7ea 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetRoofData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetRoofData.cpp @@ -1,4 +1,6 @@ #include "GetRoofData.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -29,11 +31,6 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - // quantities API_ElementQuantity quantity = {}; API_Quantities quantities = {}; @@ -43,7 +40,7 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, ACAPI_ELEMENT_QUANTITY_MASK_SET (quantityMask, roof, volume); quantities.elements = &quantity; - err = ACAPI_Element_GetQuantities (element.roof.head.guid, nullptr, &quantities, &quantityMask); + GSErrCode err = ACAPI_Element_GetQuantities (element.roof.head.guid, nullptr, &quantities, &quantityMask); if (err != NoError) return err; @@ -174,15 +171,8 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, if (NoError == ACAPI_Attribute_Get (&attrib)) os.Add (Roof::SectContLtype, GS::UniString{attrib.header.name}); - // Override cut fill pen - if (element.roof.shellBase.penOverride.overrideCutFillPen) { - os.Add (Roof::CutFillPen, element.roof.shellBase.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (element.roof.shellBase.penOverride.overrideCutFillBackgroundPen) { - os.Add (Roof::CutFillBackgroundPen, element.roof.shellBase.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (element.roof.shellBase, os, Roof::CutFillPen, Roof::CutFillBackgroundPen); // Outlines @@ -243,10 +233,10 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, // Overridden materials int countOverriddenMaterial = 0; - if (element.roof.shellBase.topMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.roof.shellBase.topMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.roof.shellBase.topMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.roof.shellBase.topMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -254,10 +244,10 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, os.Add (Roof::TopMat, GS::UniString{attribute.header.name}); } - if (element.roof.shellBase.sidMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.roof.shellBase.sidMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.roof.shellBase.sidMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.roof.shellBase.sidMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -265,10 +255,10 @@ GS::ErrCode GetRoofData::SerializeElementType (const API_Element& element, os.Add (Roof::SideMat, GS::UniString{attribute.header.name}); } - if (element.roof.shellBase.botMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.roof.shellBase.botMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.roof.shellBase.botMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.roof.shellBase.botMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetShellData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetShellData.cpp index 0e3a14b287..484aade43c 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetShellData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetShellData.cpp @@ -1,4 +1,7 @@ #include "GetShellData.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" +#include "APIMigrationHelper.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -30,11 +33,6 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - // Geometry and positioning // The story of the shell API_StoryType story = Utility::GetStory (element.shell.head.floorInd); @@ -70,10 +68,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, currentEdgeOs.Add (Shell::ShellContourSideTypeName, edgeAngleTypeNames.Get (memo.shellContours[idx].edgeData[iEdge].edgeTrim.sideType)); currentEdgeOs.Add (Shell::ShellContourSideAngle, memo.shellContours[idx].edgeData[iEdge].edgeTrim.sideAngle); - if (memo.shellContours[idx].edgeData[iEdge].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (memo.shellContours[idx].edgeData[iEdge].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = memo.shellContours[idx].edgeData[iEdge].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (memo.shellContours[idx].edgeData[iEdge].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) currentEdgeOs.Add (Shell::ShellContourEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -127,10 +125,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Beg shape edge begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.extrudedShell.begShapeEdgeData.edgeTrim.sideType)); begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideAngle, element.shell.u.extrudedShell.begShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.extrudedShell.begShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) begShapeEdgeOs.Add (Shell::BegShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -142,10 +140,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // End shape edge endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.extrudedShell.endShapeEdgeData.edgeTrim.sideType)); endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideAngle, element.shell.u.extrudedShell.endShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial)){ BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.extrudedShell.endShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) endShapeEdgeOs.Add (Shell::EndShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -157,10 +155,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Side shape edge 1 extrudedEdgeOs1.Add (Shell::ExtrudedEdgeTrimSideType1, edgeAngleTypeNames.Get (element.shell.u.extrudedShell.extrudedEdgeDatas[0].edgeTrim.sideType)); extrudedEdgeOs1.Add (Shell::ExtrudedEdgeTrimSideAngle1, element.shell.u.extrudedShell.extrudedEdgeDatas[0].edgeTrim.sideAngle); - if (element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.extrudedShell.extrudedEdgeDatas[0].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) extrudedEdgeOs1.Add (Shell::ExtrudedEdgeSideMaterial1, GS::UniString{attribute.header.name}); @@ -172,10 +170,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Side shape edge 2 extrudedEdgeOs2.Add (Shell::ExtrudedEdgeTrimSideType2, edgeAngleTypeNames.Get (element.shell.u.extrudedShell.extrudedEdgeDatas[1].edgeTrim.sideType)); extrudedEdgeOs2.Add (Shell::ExtrudedEdgeTrimSideAngle2, element.shell.u.extrudedShell.extrudedEdgeDatas[1].edgeTrim.sideAngle); - if (element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.extrudedShell.extrudedEdgeDatas[1].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) extrudedEdgeOs2.Add (Shell::ExtrudedEdgeSideMaterial2, GS::UniString{attribute.header.name}); @@ -203,10 +201,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Beg shape edge begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.revolvedShell.begShapeEdgeData.edgeTrim.sideType)); begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideAngle, element.shell.u.revolvedShell.begShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.revolvedShell.begShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) begShapeEdgeOs.Add (Shell::BegShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -218,10 +216,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // End shape edge endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.revolvedShell.endShapeEdgeData.edgeTrim.sideType)); endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideAngle, element.shell.u.revolvedShell.endShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.revolvedShell.endShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) endShapeEdgeOs.Add (Shell::EndShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -233,10 +231,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Revolved edge 1 revolvedEdgeOs1.Add (Shell::RevolvedEdgeTrimSideType1, edgeAngleTypeNames.Get (element.shell.u.revolvedShell.revolvedEdgeDatas[0].edgeTrim.sideType)); revolvedEdgeOs1.Add (Shell::RevolvedEdgeTrimSideAngle1, element.shell.u.revolvedShell.revolvedEdgeDatas[0].edgeTrim.sideAngle); - if (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) revolvedEdgeOs1.Add (Shell::RevolvedEdgeSideMaterial1, GS::UniString{attribute.header.name}); @@ -248,10 +246,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Revolved edge 2 revolvedEdgeOs2.Add (Shell::RevolvedEdgeTrimSideType2, edgeAngleTypeNames.Get (element.shell.u.revolvedShell.revolvedEdgeDatas[0].edgeTrim.sideType)); revolvedEdgeOs2.Add (Shell::RevolvedEdgeTrimSideAngle2, element.shell.u.revolvedShell.revolvedEdgeDatas[0].edgeTrim.sideAngle); - if (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.revolvedShell.revolvedEdgeDatas[0].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) revolvedEdgeOs2.Add (Shell::RevolvedEdgeSideMaterial2, GS::UniString{attribute.header.name}); @@ -277,10 +275,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Beg shape edge begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.ruledShell.begShapeEdgeData.edgeTrim.sideType)); begShapeEdgeOs.Add (Shell::BegShapeEdgeTrimSideAngle, element.shell.u.ruledShell.begShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.ruledShell.begShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.ruledShell.begShapeEdgeData.sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.ruledShell.begShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.ruledShell.begShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) begShapeEdgeOs.Add (Shell::BegShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -292,10 +290,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // End shape edge endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideType, edgeAngleTypeNames.Get (element.shell.u.ruledShell.endShapeEdgeData.edgeTrim.sideType)); endShapeEdgeOs.Add (Shell::EndShapeEdgeTrimSideAngle, element.shell.u.ruledShell.endShapeEdgeData.edgeTrim.sideAngle); - if (element.shell.u.ruledShell.endShapeEdgeData.sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.ruledShell.endShapeEdgeData.sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.ruledShell.endShapeEdgeData.sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.ruledShell.endShapeEdgeData.sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) endShapeEdgeOs.Add (Shell::EndShapeEdgeSideMaterial, GS::UniString{attribute.header.name}); @@ -307,10 +305,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Ruled edge 1 ruledEdgeOs1.Add (Shell::RuledEdgeTrimSideType1, edgeAngleTypeNames.Get (element.shell.u.ruledShell.ruledEdgeDatas[0].edgeTrim.sideType)); ruledEdgeOs1.Add (Shell::RuledEdgeTrimSideAngle1, element.shell.u.ruledShell.ruledEdgeDatas[0].edgeTrim.sideAngle); - if (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) ruledEdgeOs1.Add (Shell::RuledEdgeSideMaterial1, GS::UniString{attribute.header.name}); @@ -322,10 +320,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Ruled edge 2 ruledEdgeOs2.Add (Shell::RuledEdgeTrimSideType2, edgeAngleTypeNames.Get (element.shell.u.ruledShell.ruledEdgeDatas[0].edgeTrim.sideType)); ruledEdgeOs2.Add (Shell::RuledEdgeTrimSideAngle2, element.shell.u.ruledShell.ruledEdgeDatas[0].edgeTrim.sideAngle); - if (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.u.ruledShell.ruledEdgeDatas[0].sideMaterial); if (NoError == ACAPI_Attribute_Get (&attribute)) ruledEdgeOs2.Add (Shell::RuledEdgeSideMaterial2, GS::UniString{attribute.header.name}); @@ -415,15 +413,8 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, if (NoError == ACAPI_Attribute_Get (&attrib)) os.Add (Shell::SectContLtype, GS::UniString{attrib.header.name}); - // Override cut fill pen - if (element.shell.shellBase.penOverride.overrideCutFillPen) { - os.Add (Shell::CutFillPen, element.shell.shellBase.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (element.shell.shellBase.penOverride.overrideCutFillBackgroundPen) { - os.Add (Shell::CutFillBackgroundPen, element.shell.shellBase.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (element.shell.shellBase, os, Shell::CutFillPen, Shell::CutFillBackgroundPen); // Outlines @@ -484,10 +475,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, // Overridden materials int countOverriddenMaterial = 0; - if (element.shell.shellBase.topMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.shellBase.topMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.shellBase.topMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.shellBase.topMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -495,10 +486,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, os.Add (Shell::TopMat, GS::UniString{attribute.header.name}); } - if (element.shell.shellBase.sidMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.shellBase.sidMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.shellBase.sidMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.shellBase.sidMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -506,10 +497,10 @@ GS::ErrCode GetShellData::SerializeElementType (const API_Element& element, os.Add (Shell::SideMat, GS::UniString{attribute.header.name}); } - if (element.shell.shellBase.botMat.overridden) { + if (IsAPIOverriddenAttributeOverridden (element.shell.shellBase.botMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.shell.shellBase.botMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute (element.shell.shellBase.botMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSkylightData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSkylightData.cpp index d7dd582f6a..a238a5531f 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSkylightData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSkylightData.cpp @@ -26,14 +26,9 @@ API_ElemTypeID GetSkylightData::GetElemTypeID () const GS::ErrCode GetSkylightData::SerializeElementType (const API_Element& element, - const API_ElementMemo& memo, + const API_ElementMemo& /*memo*/, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - os.Add (ElementBase::ParentElementId, APIGuidToString (element.skylight.owner)); os.Add (Skylight::VertexID, element.skylight.vertexID); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSlabData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSlabData.cpp index d52f93c5d5..e952c00e6c 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSlabData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSlabData.cpp @@ -1,4 +1,6 @@ #include "GetSlabData.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -28,11 +30,6 @@ GS::ErrCode GetSlabData::SerializeElementType (const API_Element& element, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - // Geometry and positioning // The index of the slab's floor API_StoryType story = Utility::GetStory (element.slab.head.floorInd); @@ -117,15 +114,9 @@ GS::ErrCode GetSlabData::SerializeElementType (const API_Element& element, if (NoError == ACAPI_Attribute_Get (&attrib)) os.Add (Slab::sectContLtype, GS::UniString{attrib.header.name}); - // Override cut fill pen - if (element.slab.penOverride.overrideCutFillPen) { - os.Add (Slab::cutFillPen, element.slab.penOverride.cutFillPen); - } - // Override cut fill backgound pen - if (element.slab.penOverride.overrideCutFillBackgroundPen) { - os.Add (Slab::cutFillBackgroundPen, element.slab.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (element.slab, os, Slab::cutFillPen, Slab::cutFillBackgroundPen); // Outlines @@ -184,10 +175,10 @@ GS::ErrCode GetSlabData::SerializeElementType (const API_Element& element, // Overridden materials int countOverriddenMaterial = 0; - if (element.slab.topMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(element.slab.topMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.slab.topMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(element.slab.topMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -195,10 +186,10 @@ GS::ErrCode GetSlabData::SerializeElementType (const API_Element& element, os.Add (Slab::topMat, GS::UniString{attribute.header.name}); } - if (element.slab.sideMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(element.slab.sideMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.slab.sideMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(element.slab.sideMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -206,10 +197,10 @@ GS::ErrCode GetSlabData::SerializeElementType (const API_Element& element, os.Add (Slab::sideMat, GS::UniString{attribute.header.name}); } - if (element.slab.botMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(element.slab.botMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = element.slab.botMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(element.slab.botMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.cpp deleted file mode 100644 index 87383d8b16..0000000000 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "GetSubElementInfo.hpp" -#include "ResourceIds.hpp" -#include "ObjectState.hpp" -#include "Utility.hpp" -#include "Objects/Point.hpp" -#include "RealNumber.h" -#include "FieldNames.hpp" -#include "TypeNameTables.hpp" -using namespace FieldNames; - - -namespace AddOnCommands { - - -GS::String GetSubElementInfo::GetName () const -{ - return GetSubelementInfoCommandName; -} - - -GS::ObjectState GetSubElementInfo::Execute (const GS::ObjectState& parameters, GS::ProcessControl& /*processControl*/) const -{ - GSErrCode err = NoError; - GS::UniString id; - parameters.Get (ElementBase::ApplicationId, id); - API_Guid elementGuid = APIGuidFromString (id.ToCStr ()); - - GS::ObjectState result; - const auto& listAdder = result.AddList (SubelementModels); - - API_Element element{}; - element.header.guid = elementGuid; - err = ACAPI_Element_Get (&element); - - if (err == NoError) { - GS::Array elementGuids = Utility::GetElementSubelements (element); - for (GS::UInt32 i = 0; i < elementGuids.GetSize (); i++) { - API_Guid currentGuid = elementGuids.Get (i); - - GS::UniString guid = APIGuidToString (currentGuid); - API_ElemType elementType = Utility::GetElementType (currentGuid); - - GS::UniString elementTypeName; - if (NoError != GetElementTypeName (elementType, elementTypeName)) - continue; - - GS::ObjectState subelementModel; - subelementModel.Add (ElementBase::ApplicationId, guid); - subelementModel.Add (ElementBase::ElementType, elementTypeName); - listAdder (subelementModel); - } - } - - return result; -} - - -} diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.hpp deleted file mode 100644 index 16c5b0b61c..0000000000 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetSubElementInfo.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef GET_SUBELEMENT_DATA_HPP -#define GET_SUBELEMENT_DATA_HPP - -#include "BaseCommand.hpp" - -namespace AddOnCommands { - - -class GetSubElementInfo : public BaseCommand { - - -public: - virtual GS::String GetName () const override; - virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override; -}; - - -} - - -#endif \ No newline at end of file diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWallData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWallData.cpp index fd5170f74b..323e01cd38 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWallData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWallData.cpp @@ -1,4 +1,6 @@ #include "GetWallData.hpp" +#include "APIMigrationHelper.hpp" +#include "CommandHelpers.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "Utility.hpp" @@ -31,11 +33,6 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - const API_WallType wall = element.wall; // Wall geometry @@ -136,7 +133,7 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, // The reference line location of the wall (outside, center, inside, core outside, core center or core inside) os.Add (Wall::ReferenceLineLocation, referenceLineLocationNames.Get (wall.referenceLineLocation)); - // The offset of the walls base line from reference line + // The offset of the wall�s base line from reference line if (wall.type != APIWtyp_Poly && wall.referenceLineLocation != APIWallRefLine_Center && wall.referenceLineLocation != APIWallRefLine_CoreCenter) { @@ -166,7 +163,7 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, // Floor Plan and Section - Cut Surfaces parameters - // The pen index and linetype name of walls cut contour line + // The pen index and linetype name of wall�s cut contour line if (wall.modelElemStructureType == API_BasicStructure) { os.Add (Wall::CutLinePenIndex, wall.contPen); @@ -178,22 +175,15 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, os.Add (Wall::CutLinetypeName, GS::UniString{attribute.header.name}); } - // Override cut fill pen - if (wall.penOverride.overrideCutFillPen) { - os.Add (Wall::OverrideCutFillPenIndex, wall.penOverride.cutFillPen); - } - - // Override cut fill backgound pen - if (wall.penOverride.overrideCutFillBackgroundPen) { - os.Add (Wall::OverrideCutFillBackgroundPenIndex, wall.penOverride.cutFillBackgroundPen); - } + // Override cut fill pen and background cut fill pen + CommandHelpers::GetCutfillPens (wall, os, Wall::OverrideCutFillPenIndex, Wall::OverrideCutFillBackgroundPenIndex); // Floor Plan and Section - Outlines parameters - // The pen index of walls uncut contour line + // The pen index of wall�s uncut contour line os.Add (Wall::UncutLinePenIndex, wall.contPen3D); - // The linetype name of walls uncut contour line + // The linetype name of wall�s uncut contour line BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_LinetypeID; attribute.header.index = wall.belowViewLineType; @@ -201,10 +191,10 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, if (NoError == ACAPI_Attribute_Get (&attribute)) os.Add (Wall::UncutLinetypeName, GS::UniString{attribute.header.name}); - // The pen index of walls overhead contour line + // The pen index of wall�s overhead contour line os.Add (Wall::OverheadLinePenIndex, wall.aboveViewLinePen); - // The linetype name of walls overhead contour line + // The linetype name of wall�s overhead contour line BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_LinetypeID; attribute.header.index = wall.aboveViewLineType; @@ -216,10 +206,10 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, // The reference overridden material name, start and end edge index int countOverriddenMaterial = 0; - if (wall.refMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(wall.refMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = wall.refMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(wall.refMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -230,10 +220,10 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, } // The opposite overridden material name, start and end edge index - if (wall.oppMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(wall.oppMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = wall.oppMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(wall.oppMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; @@ -244,10 +234,10 @@ GS::ErrCode GetWallData::SerializeElementType (const API_Element& element, } // The side overridden material name - if (wall.sidMat.overridden) { + if (IsAPIOverriddenAttributeOverridden(wall.sidMat)) { BNZeroMemory (&attribute, sizeof (API_Attribute)); attribute.header.typeID = API_MaterialID; - attribute.header.index = wall.sidMat.attributeIndex; + attribute.header.index = GetAPIOverriddenAttribute(wall.sidMat); if (NoError == ACAPI_Attribute_Get (&attribute)) countOverriddenMaterial = countOverriddenMaterial + 1; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWindowData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWindowData.cpp index c6b3e3a04d..b5d6a54189 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWindowData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetWindowData.cpp @@ -26,14 +26,9 @@ API_ElemTypeID GetWindowData::GetElemTypeID () const GS::ErrCode GetWindowData::SerializeElementType (const API_Element& element, - const API_ElementMemo& memo, + const API_ElementMemo& /*memo*/, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - os.Add (ElementBase::ParentElementId, APIGuidToString (element.window.owner)); AddOnCommands::GetDoorWindowData (element.window, os); diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetZoneData.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetZoneData.cpp index 1f1f1fe6c3..7e43a85886 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetZoneData.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetZoneData.cpp @@ -30,11 +30,6 @@ GS::ErrCode GetZoneData::SerializeElementType (const API_Element& element, const API_ElementMemo& memo, GS::ObjectState& os) const { - GS::ErrCode err = NoError; - err = GetDataCommand::SerializeElementType (element, memo, os); - if (NoError != err) - return err; - // quantities API_ElementQuantity quantity = {}; API_Quantities quantities = {}; @@ -45,7 +40,7 @@ GS::ErrCode GetZoneData::SerializeElementType (const API_Element& element, ACAPI_ELEMENT_QUANTITY_MASK_SET (mask, zone, volume); quantities.elements = &quantity; - err = ACAPI_Element_GetQuantities (element.header.guid, nullptr, &quantities, &mask); + GSErrCode err = ACAPI_Element_GetQuantities (element.header.guid, nullptr, &quantities, &mask); if (err != NoError) return err; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/SelectElements.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/SelectElements.cpp index 54f985dea7..2d9c8fe698 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/SelectElements.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/SelectElements.cpp @@ -1,9 +1,11 @@ #include "SelectElements.hpp" +#include "APIMigrationHelper.hpp" #include "ResourceIds.hpp" #include "ObjectState.hpp" #include "FieldNames.hpp" #include "APIdefs_Automate.h" + GS::String AddOnCommands::SelectElements::GetName () const { return SelectElementsCommandName; @@ -27,16 +29,16 @@ GS::ObjectState AddOnCommands::SelectElements::Execute (const GS::ObjectState& p GS::Array selectionBasket = ids.Transform ([] (const GS::UniString& idStr) { return API_Neig (APIGuidFromString (idStr.ToCStr ())); }); if (clearSelection) { - err = ACAPI_Element_DeselectAll (); + err = ACAPI_Selection_DeselectAll (); if (err != NoError) return result; } - err = ACAPI_Element_Select (selectionBasket, !deselect); + err = ACAPI_Selection_Select (selectionBasket, !deselect); if (err != NoError) return result; - ACAPI_Automate (APIDo_ZoomToSelectedID); + ACAPI_View_ZoomToSelected (); result.Add (FieldNames::ApplicationObject::Status, true); return result; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Database.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Database.cpp index 48f7de8d40..10a5acbf97 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Database.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Database.cpp @@ -1,5 +1,6 @@ -#include "Database.hpp" #include "ACAPinc.h" +#include "APIMigrationHelper.hpp" +#include "Database.hpp" using namespace Utility; @@ -45,7 +46,7 @@ void Database::SwitchToFloorPlan (void) { API_DatabaseInfo databaseInfo; BNZeroMemory (&databaseInfo, sizeof (API_DatabaseInfo)); - GSErrCode err = ACAPI_Database (APIDb_GetCurrentDatabaseID, &databaseInfo, nullptr); + GSErrCode err = ACAPI_Database_GetCurrentDatabase (&databaseInfo); if (err != NoError) databaseInfo.typeID = API_ZombieWindowID; @@ -56,5 +57,5 @@ void Database::SwitchToFloorPlan (void) /*static*/ void Database::ChangeCurrent (API_DatabaseInfo& databaseInfo) { - ACAPI_Database (APIDb_ChangeCurrentDatabaseID, &databaseInfo, nullptr); + ACAPI_Database_ChangeCurrentDatabase (&databaseInfo); } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/FieldNames.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/FieldNames.hpp index 17033d4cef..64c80772da 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/FieldNames.hpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/FieldNames.hpp @@ -44,6 +44,28 @@ static const char* System = "system"; static const char* Code = "code"; // id is reserved for Speckle id static const char* Name = "name"; } + +static const char* ElementProperties = "elementProperties"; +static const char* ComponentProperties = "componentProperties"; +static const char* SendListingParameters = "sendListingParameters"; +static const char* SendProperties = "sendProperties"; +namespace ComponentProperty +{ +static const char* Name = "name"; +static const char* PropertyGroups = "propertyGroups"; +} +namespace PropertyGroup +{ +static const char* Name = "name"; +static const char* PropertList = "propertyList"; +} +namespace Property +{ +static const char* Name = "name"; +static const char* Value = "value"; +static const char* Values = "values"; +static const char* Units = "units"; +} } static const char* Elements = "elements"; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/LibpartImportManager.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/LibpartImportManager.cpp index 47e9f15acb..50aeef8cb4 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/LibpartImportManager.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/LibpartImportManager.cpp @@ -1,5 +1,6 @@ #include "LibpartImportManager.hpp" +#include "APIMigrationHelper.hpp" #include "BuiltInLibrary.hpp" #include "FileSystem.hpp" #include "Folder.hpp" @@ -29,7 +30,7 @@ void LibpartImportManager::DeleteInstance () } -LibpartImportManager::LibpartImportManager () : runningNumber(1) +LibpartImportManager::LibpartImportManager () : runningNumber (1) { AttributeManager::GetInstance ()->GetDefaultMaterial (defaultMaterialAttribute, defaultMaterialName); GetLocation (true, libraryFolderLocation); @@ -56,7 +57,7 @@ static GSErrCode CreateSubFolder (const GS::UniString& name, IO::Location& locat TIGetTimeRecord (gsTime, &gsTimeRecord, TI_CURRENT_TIME); GS::UniString folderNamePostfix (GS::UniString::SPrintf ("%04u%02u%02u-%02u%02u%02u", (UInt32) gsTimeRecord.year, (UInt32) gsTimeRecord.month, (UInt32) gsTimeRecord.day, - (UInt32) gsTimeRecord.hour, (UInt32) gsTimeRecord.minute, (UInt32) gsTimeRecord.second)); + (UInt32) gsTimeRecord.hour, (UInt32) gsTimeRecord.minute, (UInt32) gsTimeRecord.second)); IO::Name folderName (name); folderName.Append ("_"); @@ -122,94 +123,94 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, GS::ucscpy (libPart.docu_UName, GS::UniString::SPrintf ("Speckle Object %u", runningNumber++).ToUStr ()); - ACAPI_Environment (APIEnv_OverwriteLibPartID, (void*) (Int32) true, nullptr); - err = ACAPI_LibPart_Create (&libPart); - ACAPI_Environment (APIEnv_OverwriteLibPartID, (void*) (Int32) false, nullptr); + ACAPI_LibraryManagement_OverwriteLibPart ((void*) (Int32) true); + err = ACAPI_LibraryPart_Create (&libPart); + ACAPI_LibraryManagement_OverwriteLibPart ((void*) (Int32) false); if (err == NoError) { API_LibPartSection section; GS::String line; #ifdef ServerMainVers_2600 - line.EnsureCapacity(1000); + line.EnsureCapacity (1000); #endif // Comment script section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectComText; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); line = "Speckle"; - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + ACAPI_LibraryPart_EndSection (); // Keyword section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectKeywords; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); line = "Speckle"; - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + ACAPI_LibraryPart_EndSection (); // Copyright section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectCopyright; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); line = "Speckle Systems"; // Author - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + ACAPI_LibraryPart_EndSection (); // Master script section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_Sect1DScript; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); line = ""; - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + ACAPI_LibraryPart_EndSection (); // 3D script section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_Sect3DScript; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); - line = GS::String::SPrintf("!%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("!%s", GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("! 3D Script (Generated by Speckle Connector)%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("!%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("defaultResolution = 36%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("RESOL defaultResolution%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("hiddenProfileEdge = 0%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("hiddenBodyEdge = 0%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("smoothBodyEdge = 0%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("visibleBodyEdge = 262144%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("IF (GLOB_CONTEXT %% 10 >= 2 AND GLOB_CONTEXT %% 10 <= 4) AND showOnlyContourEdgesIn3D <> 0 THEN%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("\thiddenProfileEdge = 1%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("\thiddenBodyEdge = 1%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("\tsmoothBodyEdge = 2%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("ENDIF%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("!%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("RESOL defaultResolution%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("XFORM map_xform[1][1], map_xform[2][1], map_xform[3][1], map_xform[4][1],%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("\tmap_xform[1][2], map_xform[2][2], map_xform[3][2], map_xform[4][2],%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("\tmap_xform[1][3], map_xform[2][3], map_xform[3][3], map_xform[4][3]%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); // create material GS::Array materials = modelInfo.GetMaterials (); @@ -221,13 +222,13 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, GS::Array vertices = modelInfo.GetVertices (); Box3D box = Box3D::CreateEmpty (); for (UInt32 i = 0; i < vertices.GetSize (); i++) { - line = GS::String::SPrintf ("VERT %f, %f, %f\t!#%d%s", vertices[i].GetX (), vertices[i].GetY (), vertices[i].GetZ (), i + 1, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("VERT %f, %f, %f\t!#%u%s", (float)vertices[i].GetX (), (float)vertices[i].GetY (), (float)vertices[i].GetZ (), i + 1, GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); box.Extend (Point3D (vertices[i].GetX (), vertices[i].GetY (), vertices[i].GetZ ())); } line = GS::String::SPrintf ("%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); const GS::HashTable& edges = modelInfo.GetEdges (); @@ -246,8 +247,8 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, } } - line = GS::String::SPrintf ("! Polygon #%d%s%sMATERIAL \"%s\"%s", polygonIndex, GS::EOL, GS::EOL, materialName.ToCStr ().Get (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("! Polygon #%u%s%sMATERIAL \"%s\"%s", polygonIndex, GS::EOL, GS::EOL, materialName.ToCStr ().Get (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); for (UInt32 i = 0; i < pointsCount; i++) { Int32 start = i; @@ -258,9 +259,9 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, bool smooth = false; bool hidden = true; - if (edges.ContainsKey(edge)) { + if (edges.ContainsKey (edge)) { ModelInfo::EdgeData edgeData = edges.Get (edge); - + switch (edgeData.edgeStatus) { case ModelInfo::HiddenEdge: break; @@ -276,73 +277,73 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, } } - line = GS::String::SPrintf ("EDGE %d, %d, -1, -1, %s\t!#%d%s", pointIds[start] + 1, pointIds[end] + 1, (smooth ? "smoothBodyEdge" : (hidden ? "hiddenBodyEdge" : "visibleBodyEdge")), edgeIndex + i, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("EDGE %d, %d, -1, -1, %s\t!#%u%s", pointIds[start] + 1, pointIds[end] + 1, (smooth ? "smoothBodyEdge" : (hidden ? "hiddenBodyEdge" : "visibleBodyEdge")), edgeIndex + i, GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); } - line = GS::String::SPrintf ("PGON %d, 0, -1", pointsCount); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("PGON %u, 0, -1", pointsCount); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); for (UInt32 i = 0; i < pointsCount; i++) { - line = GS::String::SPrintf (",%s%d", ((i + 1) % 10 == 0 ? GS::EOL : " "), edgeIndex + i); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf (",%s%u", ((i + 1) % 10 == 0 ? GS::EOL : " "), edgeIndex + i); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); } - line = GS::String::SPrintf ("\t!#%d%s%s", polygonIndex, GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + line = GS::String::SPrintf ("\t!#%u%s%s", polygonIndex, GS::EOL, GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); edgeIndex += pointsCount; polygonIndex++; } line = GS::String::SPrintf ("BODY 4%s%s", GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMinX (), box.GetMinY (), box.GetMinZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMinX (), box.GetMinY (), box.GetMaxZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMinX (), box.GetMaxY (), box.GetMinZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMinX (), box.GetMaxY (), box.GetMaxZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMaxX (), box.GetMinY (), box.GetMinZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMaxX (), box.GetMinY (), box.GetMaxZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", box.GetMaxX (), box.GetMaxY (), box.GetMinZ (), GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s%s", box.GetMaxX (), box.GetMaxY (), box.GetMaxZ (), GS::EOL, GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMinX (), (float)box.GetMinY (), (float)box.GetMinZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMinX (), (float)box.GetMinY (), (float)box.GetMaxZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMinX (), (float)box.GetMaxY (), (float)box.GetMinZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMinX (), (float)box.GetMaxY (), (float)box.GetMaxZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMaxX (), (float)box.GetMinY (), (float)box.GetMinZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMaxX (), (float)box.GetMinY (), (float)box.GetMaxZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s", (float)box.GetMaxX (), (float)box.GetMaxY (), (float)box.GetMinZ (), GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + line = GS::String::SPrintf ("HOTSPOT %f, %f, %f%s%s", (float)box.GetMaxX (), (float)box.GetMaxY (), (float)box.GetMaxZ (), GS::EOL, GS::EOL); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = "DEL TOP"; - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_EndSection (); // 2D script section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_Sect2DScript; - ACAPI_LibPart_NewSection (§ion); + ACAPI_LibraryPart_NewSection (§ion); line = GS::String::SPrintf ("!%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("! 2D Script (Generated by Speckle Connector)%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("!%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("PEN gs_cont_pen%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("SET FILL gs_fill_type%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); line = GS::String::SPrintf ("PROJECT2{2} 3, 270.0, 3+32, gs_back_pen, 0, 0, 0%s", GS::EOL); - ACAPI_LibPart_WriteSection (line.GetLength(), line.ToCStr()); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_WriteSection (line.GetLength (), line.ToCStr ()); + ACAPI_LibraryPart_EndSection (); // Parameter script section BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectVLScript; - ACAPI_LibPart_NewSection (§ion); - ACAPI_LibPart_EndSection (); + ACAPI_LibraryPart_NewSection (§ion); + ACAPI_LibraryPart_EndSection (); // Parameters section BNZeroMemory (§ion, sizeof (API_LibPartSection)); @@ -380,15 +381,15 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, double aa = 1.0; double bb = 1.0; GSHandle sectionHdl = nullptr; - ACAPI_LibPart_GetSect_ParamDef (&libPart, addPars, &aa, &bb, nullptr, §ionHdl); + ACAPI_LibraryPart_GetSect_ParamDef (&libPart, addPars, &aa, &bb, nullptr, §ionHdl); API_LibPartDetails details; BNZeroMemory (&details, sizeof (API_LibPartDetails)); details.object.autoHotspot = false; details.object.fixSize = true; - ACAPI_LibPart_SetDetails_ParamDef (&libPart, sectionHdl, &details); + ACAPI_LibraryPart_SetDetails_ParamDef (&libPart, sectionHdl, &details); - ACAPI_LibPart_AddSection (§ion, sectionHdl, nullptr); + ACAPI_LibraryPart_AddSection (§ion, sectionHdl, nullptr); BMKillHandle (reinterpret_cast(&arrHdl)); BMKillHandle (reinterpret_cast(&addPars)); @@ -399,7 +400,7 @@ GSErrCode LibpartImportManager::CreateLibraryPart (const ModelInfo& modelInfo, // Save the constructed library part if (err == NoError) - err = ACAPI_LibPart_Save (&libPart); + err = ACAPI_LibraryPart_Save (&libPart); } return err; @@ -414,7 +415,7 @@ GSErrCode LibpartImportManager::GetLocation (bool useEmbeddedLibrary, IO::Locati if (useEmbeddedLibrary) { Int32 embeddedLibraryIndex = -1; // get embedded library location - if (ACAPI_Environment (APIEnv_GetLibrariesID, &libInfo, &embeddedLibraryIndex) == NoError && embeddedLibraryIndex >= 0) { + if (ACAPI_LibraryManagement_GetLibraries (&libInfo, &embeddedLibraryIndex) == NoError && embeddedLibraryIndex >= 0) { try { libraryFolderLocation = new IO::Location (libInfo[embeddedLibraryIndex].location); } catch (std::bad_alloc&) { @@ -427,10 +428,10 @@ GSErrCode LibpartImportManager::GetLocation (bool useEmbeddedLibrary, IO::Locati } } else { // register our own folder and create the library part in it - if (ACAPI_Environment (APIEnv_GetLibrariesID, &libInfo) == NoError) { + if (ACAPI_LibraryManagement_GetLibraries (&libInfo, nullptr) == NoError) { IO::Location folderLoc; API_SpecFolderID specID = API_UserDocumentsFolderID; - ACAPI_Environment (APIEnv_GetSpecFolderID, &specID, &folderLoc); + ACAPI_ProjectSettings_GetSpecFolder (&specID, &folderLoc); folderLoc.AppendToLocal (IO::Name ("Speckle Library")); IO::Folder destFolder (folderLoc, IO::Folder::Create); if (destFolder.GetStatus () != NoError || !destFolder.IsWriteable ()) @@ -453,7 +454,7 @@ GSErrCode LibpartImportManager::GetLocation (bool useEmbeddedLibrary, IO::Locati return APIERR_MEMFULL; } - ACAPI_Environment (APIEnv_SetLibrariesID, &libInfo); + ACAPI_LibraryManagement_SetLibraries (&libInfo); } } diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.cpp new file mode 100644 index 0000000000..5849c1fc82 --- /dev/null +++ b/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.cpp @@ -0,0 +1,378 @@ +#include "PropertyExportManager.hpp" +#include "Utility.hpp" +#include "MD5Channel.hpp" + + +PropertyExportManager* PropertyExportManager::instance = nullptr; + +PropertyExportManager* PropertyExportManager::GetInstance () +{ + if (nullptr == instance) { + instance = new PropertyExportManager; + } + return instance; +} + + +void PropertyExportManager::DeleteInstance () +{ + if (nullptr != instance) { + delete instance; + instance = nullptr; + } +} + + +PropertyExportManager::PropertyExportManager () +{ + const GS::Guid General3DLengthPropertyId = GS::Guid ("{BA0E29BD-A795-4A93-A33F-C2C17B46C33A}"); + const GS::Guid General3DPerimeterPropertyId = GS::Guid ("{EEAD00FC-FBB0-4278-959D-C5244F66E8C1}"); + const GS::Guid GeneralAbsoluteTopLinkStoryPropertyId = GS::Guid ("{7729820D-061B-4D5B-893B-8499E17D139D}"); + const GS::Guid GeneralArchicadIFCIdPropertyId = GS::Guid ("{544CD642-5FDB-476D-B764-921825B4B681}"); + const GS::Guid GeneralAreaPropertyId = GS::Guid ("{AC5CCA52-F79B-4850-92A9-BED7CB7C3847}"); + const GS::Guid GeneralBottomElevationToFirstReferenceLevelPropertyId = GS::Guid ("{C17788DA-E680-46F7-B190-0E5BB26DA35F}"); + const GS::Guid GeneralBottomElevationToHomeStoryPropertyId = GS::Guid ("{6CA8A0E2-340D-43D4-BA4B-5F3BF4CE660B}"); + const GS::Guid GeneralBottomElevationToProjectZeroPropertyId = GS::Guid ("{6CE532E7-31EF-4623-B241-4DAC52BAC75F}"); + const GS::Guid GeneralBottomElevationToSeaLevelPropertyId = GS::Guid ("{3617F61F-BAA9-48C4-AB5F-015A105D43A1}"); + const GS::Guid GeneralBottomElevationToSecondReferenceLevelPropertyId = GS::Guid ("{F0A7B17E-A48F-4B51-8D26-9C6BC385DC90}"); + //const GS::Guid GeneralBottomSurfacePropertyId = GS::Guid ("{B2237A3A-30B9-463F-B416-262A79BE3790}"); + //const GS::Guid GeneralBuildingMaterialPropertyId = GS::Guid ("{B9179DB7-97BC-4985-94DC-06C201F79EF4}"); + //const GS::Guid GeneralBuildingMaterialsPropertyId = GS::Guid ("{44C7C173-A14B-485E-9D64-DDF95465607F}"); + //const GS::Guid GeneralBuildMatOrCompositOrProfileOrFillIndexPropertyId = GS::Guid ("{C9EDA02D-EA3A-4604-9E25-DD597361F472}"); + //const GS::Guid GeneralCollidingZonesNamesPropertyId = GS::Guid ("{1CE1F282-DAA5-4F71-BEB9-E88022AA3369}"); + //const GS::Guid GeneralComplexProfilePropertyId = GS::Guid ("{EAB6C4F7-A51F-4C13-BDBD-A72D4EFE9EC6}"); + //const GS::Guid GeneralCompositeStructurePropertyId = GS::Guid ("{20CF3744-CA2D-4FB2-ACBC-F69C619AE362}"); + const GS::Guid GeneralConditionalBottomSurfaceAreaPropertyId = GS::Guid ("{C332417B-48E4-4E89-8D39-14875A2C112F}"); + const GS::Guid GeneralConditionalTopSurfaceAreaPropertyId = GS::Guid ("{5A60DDA4-5BFC-45EC-B8E6-D635E342550B}"); + //const GS::Guid GeneralConditionalVolumePropertyId = GS::Guid ("{77786F55-28B4-4430-99B8-A00768AF86FA}"); + //const GS::Guid GeneralCoverFillPropertyId = GS::Guid ("{811D313F-43F9-416D-BC29-5732A59C970A}"); + const GS::Guid GeneralCrossSectionAreaAtBeginCutPropertyId = GS::Guid ("{094A5D1A-96EA-4485-8B7C-F1BAD5B17A26}"); + const GS::Guid GeneralCrossSectionAreaAtEndCutPropertyId = GS::Guid ("{039E12FA-9A24-4D40-9B7E-5C54F26901CE}"); + const GS::Guid GeneralCrossSectionHeightAtBeginCutPropertyId = GS::Guid ("{7A931D13-0C59-45A9-BBEF-A87EEB63C31B}"); + const GS::Guid GeneralCrossSectionHeightAtBeginPerpendicularPropertyId = GS::Guid ("{830C1AC3-4B51-4F61-86F4-8CE0F8E4B828}"); + const GS::Guid GeneralCrossSectionHeightAtEndCutPropertyId = GS::Guid ("{A7530CE2-3D5B-43A7-9768-1559ECAF9C84}"); + const GS::Guid GeneralCrossSectionHeightAtEndPerpendicularPropertyId = GS::Guid ("{39C89AA7-32C5-494D-A9B7-8018E81439FE}"); + const GS::Guid GeneralCrossSectionWidthAtBeginCutPropertyId = GS::Guid ("{44540399-FDC5-42CC-A250-9C8E58FF534E}"); + const GS::Guid GeneralCrossSectionWidthAtBeginPerpendicularPropertyId = GS::Guid ("{FE71F960-6AEF-4B5B-9E65-08CA27E07AFF}"); + const GS::Guid GeneralCrossSectionWidthAtEndCutPropertyId = GS::Guid ("{659A1AA0-72A0-465E-A45C-A619AFD2A912}"); + const GS::Guid GeneralCrossSectionWidthAtEndPerpendicularPropertyId = GS::Guid ("{3DC2D3A5-E99C-4742-BEFF-43B34F721E82}"); + //const GS::Guid GeneralEdgeSurfacePropertyId = GS::Guid ("{8781C839-32AB-4126-BA0B-F94757388438}"); + //const GS::Guid GeneralElementClassificationPropertyId = GS::Guid ("{AB85B8B9-39EB-4730-8D3D-67226BA7D607}"); + const GS::Guid GeneralElementIDPropertyId = GS::Guid ("{7E221F33-829B-4FBC-A670-E74DABCE6289}"); + const GS::Guid GeneralElevationToFirstReferenceLevelPropertyId = GS::Guid ("{5794252D-2CF1-4D9F-863B-92EC259C2870}"); + const GS::Guid GeneralElevationToProjectZeroPropertyId = GS::Guid ("{5BF6931F-82EB-40B8-B184-F51D20EC9D17}"); + const GS::Guid GeneralElevationToSeaLevelPropertyId = GS::Guid ("{E4395866-E9A1-4D9D-81FD-A187464C1132}"); + const GS::Guid GeneralElevationToSecondReferenceLevelPropertyId = GS::Guid ("{F2AF5F86-06AD-4E03-9C9B-0E7950E8B933}"); + const GS::Guid GeneralElevationToStoryPropertyId = GS::Guid ("{1F477A91-E8B9-4F47-9EE6-18EDDB569BDA}"); + const GS::Guid GeneralExternalIFCIdPropertyId = GS::Guid ("{E2C6EF45-1D1A-4D3A-99D2-E3A77A21DC75}"); + //const GS::Guid GeneralFillTypePropertyId = GS::Guid ("{BE376478-6966-4892-BEC7-4CB72ABF4003}"); + //const GS::Guid GeneralFloorPlanHolesPerimeterPropertyId = GS::Guid ("{05261268-6C0C-4FB7-A78B-15ECD5F7DF7E}"); + const GS::Guid GeneralFloorPlanPerimeterPropertyId = GS::Guid ("{174704F5-98B7-429D-85C1-7E31A5AD9936}"); + //const GS::Guid GeneralFromZoneNumberPropertyId = GS::Guid ("{1607B29C-1286-4EDF-AF50-A5CD6E555492}"); + //const GS::Guid GeneralFromZonePropertyId = GS::Guid ("{EDC44824-1A6D-407A-9E39-693066622E7D}"); + const GS::Guid GeneralGrossVolumePropertyId = GS::Guid ("{DB3A47B7-9723-47EB-B8BF-224761379150}"); + const GS::Guid GeneralGrossBottomSurfaceAreaPropertyId = GS::Guid ("{FAB63421-E32C-40C0-9238-2ECE1BB1F499}"); + const GS::Guid GeneralGrossEdgeSurfaceAreaPropertyId = GS::Guid ("{B06C9A3B-D304-45AB-A581-E6B42D104950}"); + const GS::Guid GeneralGrossTopSurfaceAreaPropertyId = GS::Guid ("{3CFB8EEE-22BB-44FC-9B50-1C73ED16AC42}"); + const GS::Guid GeneralHeightPropertyId = GS::Guid ("{C4B62357-1289-4D43-A3F6-AB02B192864C}"); + //const GS::Guid GeneralHeightPropertyId_Obsolate = GS::Guid ("{121FD4D9-1116-4D36-9CFE-6972B377BA31}"); + //const GS::Guid GeneralHoles3DPerimeterPropertyId = GS::Guid ("{8E19BE5F-D487-4BEC-9281-B34CA2355292}"); + const GS::Guid GeneralHomeOffsetPropertyId = GS::Guid ("{FD43A58A-C7AC-4265-BB3B-CF5426D157C0}"); + //const GS::Guid GeneralHomeStoryDisplayNumberPropertyId = GS::Guid ("{14D1CF3B-6A96-4E77-B84C-E39D407B1DEF}"); + //const GS::Guid GeneralHomeStoryPropertyId = GS::Guid ("{8583BC95-C85D-48A3-9C2E-1EBED328BBFE}"); + //const GS::Guid GeneralHotlinkAndElementIDPropertyId = GS::Guid ("{69A58F6F-DD3B-478D-B5EF-09A16BD0C548}"); + //const GS::Guid GeneralHotlinkMasterIDPropertyId = GS::Guid ("{F98F297A-AFA7-4B0D-824B-975C78E02995}"); + const GS::Guid GeneralInsulationSkinThicknessPropertyId = GS::Guid ("{E6927159-1AB9-47DB-9B77-4CCE95178D88}"); + //const GS::Guid GeneralLastIssueDatePropertyId = GS::Guid ("{5F677AD9-ADCB-4662-83D2-0FE3E87F12D2}"); + //const GS::Guid GeneralLastIssueIDPropertyId = GS::Guid ("{BF58FAAF-1BBE-43E3-B80A-694A9479EDD1}"); + //const GS::Guid GeneralLastIssueNamePropertyId = GS::Guid ("{6EE454EB-2982-434C-B935-13190CD5989C}"); + //const GS::Guid GeneralLayerIndexPropertyId = GS::Guid ("{25826253-26F2-4D30-BE1B-0FFBB1314903}"); + //const GS::Guid GeneralLibraryPartNamePropertyId = GS::Guid ("{B8CFC590-58A3-43CF-A159-1B23BD3E8596}"); + //const GS::Guid GeneralLinkedChangesPropertyId = GS::Guid ("{02956F1B-5058-40D1-A816-307074BA31E3}"); + //const GS::Guid GeneralListingLabelTextPropertyId_Obsolete = GS::Guid ("{455180E3-DDD9-47D2-9E62-C1B5B513ABFD}"); + //const GS::Guid GeneralLockedPropertyId = GS::Guid ("{419DA86C-86A9-4650-AD0E-965E8317D882}"); + const GS::Guid GeneralNetBottomSurfaceAreaPropertyId = GS::Guid ("{F27621A7-CFDA-4674-8D14-4184EB3D210F}"); + const GS::Guid GeneralNetEdgeSurfaceAreaPropertyId = GS::Guid ("{DEB28D76-C9B6-4D90-8260-857CD91FFA0D}"); + const GS::Guid GeneralNetTopSurfaceAreaPropertyId = GS::Guid ("{A21B3448-7E50-4661-B57A-39841DD2FA1F}"); + const GS::Guid GeneralNetVolumePropertyId = GS::Guid ("{FC8B1598-3E3B-4A4F-BBCE-277F83BC8598}"); + //const GS::Guid GeneralOpeningIDsPropertyId = GS::Guid ("{ECEFBEB5-6901-40B0-AC4B-CC16ACCCC5F5}"); + //const GS::Guid GeneralOpeningNumberPropertyId = GS::Guid ("{3E2F875B-5D53-4091-B302-D76DAD02AA70}"); + //const GS::Guid GeneralOwnerIDPropertyId = GS::Guid ("{773AE220-E624-4FBA-8B8F-D56BB8FF6875}"); + //const GS::Guid GeneralPropertyObjectNamePropertyId = GS::Guid ("{1EF4FF9C-CF55-4654-9821-F45B20BF6798}"); + //const GS::Guid GeneralRelatedZoneNamePropertyId = GS::Guid ("{B466A457-B31F-4F1E-A91C-E255886AE93A}"); + //const GS::Guid GeneralRelatedZoneNumberPropertyId = GS::Guid ("{140CAB27-7CCF-406F-B714-049FFB4B4D16}"); + const GS::Guid GeneralRelativeTopLinkStoryPropertyId = GS::Guid ("{6D644AF5-B050-446F-883E-DB89AB3365A9}"); + const GS::Guid GeneralSegmentCountPropertyId = GS::Guid ("{A2B5CD00-330B-4215-93B0-3CDB885F56DA}"); + const GS::Guid GeneralSlantAnglePropertyId = GS::Guid ("{59D1CBE9-6C29-4B97-BA57-7EC9011B8D67}"); + const GS::Guid GeneralStructureTypePropertyId = GS::Guid ("{7EC8476C-8E79-44D8-8BDE-F95C81F21EC2}"); + const GS::Guid GeneralProfileCategoryPropertyId = GS::Guid ("{75A15148-1067-4F37-96E6-1F72DAFC749F}"); + const GS::Guid GeneralSurfaceAreaPropertyId = GS::Guid ("{6AA4A58A-D32F-4AAB-BD84-E881F55D4122}"); + //const GS::Guid GeneralSurfacesPropertyId = GS::Guid ("{1194ECB8-05C5-4EA2-9CC6-8096849840C8}"); + const GS::Guid GeneralThicknessPropertyId = GS::Guid ("{A7B55E43-7C56-4C9E-836D-7A56F1D9D760}"); + const GS::Guid GeneralTopElevationToFirstReferenceLevelPropertyId = GS::Guid ("{C215559A-308B-4722-A92D-E4CB5A352080}"); + const GS::Guid GeneralTopElevationToHomeStoryPropertyId = GS::Guid ("{1ABB0A71-C54A-49BE-9281-C4D02AE5260C}"); + const GS::Guid GeneralTopElevationToProjectZeroPropertyId = GS::Guid ("{4EB49FBE-218B-4938-B806-40D20A9E5E4D}"); + const GS::Guid GeneralTopElevationToSeaLevelPropertyId = GS::Guid ("{1D554E08-F1D6-429D-B7B9-989310EB1BBF}"); + const GS::Guid GeneralTopElevationToSecondReferenceLevelPropertyId = GS::Guid ("{ABA29B82-30C9-4E6C-87B6-B47F8E71A6CD}"); + const GS::Guid GeneralTopLinkStoryPropertyId = GS::Guid ("{D01ECE7E-15FB-4B05-9B2F-112295E9DA48}"); + const GS::Guid GeneralTopOffsetPropertyId = GS::Guid ("{1606C1A4-A80B-4EA6-A179-0983C8120B46}"); + //const GS::Guid GeneralTopSurfacePropertyId = GS::Guid ("{21394C2E-9629-49A8-99B9-C7934DE3EFB0}"); + //const GS::Guid GeneralToZoneNumberPropertyId = GS::Guid ("{746EEB4F-5DC1-44AC-B4DD-EA7958B6B227}"); + //const GS::Guid GeneralToZonePropertyId = GS::Guid ("{679A16CA-D380-4945-9484-4F8510F93491}"); + const GS::Guid GeneralTypePropertyId = GS::Guid ("{A16BA200-27C1-4D1A-9C7F-4F2F9C5C6E21}"); + const GS::Guid GeneralUniqueIDPropertyId = GS::Guid ("{9C609FB7-E28E-4475-8ADC-E878E78A3858}"); + const GS::Guid GeneralWidthPropertyId = GS::Guid ("{3799B10A-61C5-4566-BF9C-EAA9CE49196E}"); + + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (General3DLengthPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (General3DPerimeterPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralAbsoluteTopLinkStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralArchicadIFCIdPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralBottomElevationToFirstReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralBottomElevationToHomeStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralBottomElevationToProjectZeroPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralBottomElevationToSeaLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralBottomElevationToSecondReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralConditionalBottomSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralConditionalTopSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionAreaAtBeginCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionAreaAtEndCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionHeightAtBeginCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionHeightAtBeginPerpendicularPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionHeightAtEndCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionHeightAtEndPerpendicularPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionWidthAtBeginCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionWidthAtBeginPerpendicularPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionWidthAtEndCutPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralCrossSectionWidthAtEndPerpendicularPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElementIDPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElevationToFirstReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElevationToProjectZeroPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElevationToSeaLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElevationToSecondReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralElevationToStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralExternalIFCIdPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralFloorPlanPerimeterPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralGrossVolumePropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralGrossBottomSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralGrossEdgeSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralGrossTopSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralHeightPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralHomeOffsetPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralInsulationSkinThicknessPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralNetBottomSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralNetEdgeSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralNetTopSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralNetVolumePropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralRelativeTopLinkStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralSegmentCountPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralSlantAnglePropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralStructureTypePropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralProfileCategoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralSurfaceAreaPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralThicknessPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopElevationToFirstReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopElevationToHomeStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopElevationToProjectZeroPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopElevationToSeaLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopElevationToSecondReferenceLevelPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopLinkStoryPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTopOffsetPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralTypePropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralUniqueIDPropertyId)); + propertyGroupFilter.elementPropertiesFilter.Add (GSGuid2APIGuid (GeneralWidthPropertyId)); + + propertyGroupFilter.componentPropertyGroupFilter.Add (APIGuidFromString ("BF31D3E0-A2B1-4543-A3DA-C1191D059FD8")); // Component_BuiltInPropertyGroupId + propertyGroupFilter.componentPropertyGroupFilter.Add (APIGuidFromString ("3CF63E55-AA52-4AB4-B1C3-0920B2F352BF")); // BuildingMaterial_BuiltInPropertyGroupId + + complexElementsToSkipFromComponentListing.Add (API_CurtainWallID); + complexElementsToSkipFromComponentListing.Add (API_StairID); + complexElementsToSkipFromComponentListing.Add (API_RailingID); +} + + +GSErrCode FilterOutDefinitionsByDefinitions (GS::Array& definitions, const GS::Array& definitionsFilter) +{ + if (definitions.IsEmpty ()) + return NoError; + + if (definitionsFilter.IsEmpty ()) + return ErrParam; + + GS::Array filteredDefinitions; + for (auto definition : definitions) { + + bool found = false; + for (auto filterDefinition : definitionsFilter) { + if (definition.guid == filterDefinition.guid) { + found = true; + break; + } + } + + if (!found) + filteredDefinitions.Push (definition); + } + + definitions = filteredDefinitions; + + return NoError; +} + + +GSErrCode FilterDefinitionsByDefinitionIds (GS::Array& definitions, const GS::HashSet& definitionsFilter) +{ + if (definitions.IsEmpty ()) + return NoError; + + if (definitionsFilter.IsEmpty ()) { + definitions.Clear (); + return NoError; + } + + GS::Array filteredDefinitions; + for (auto definition : definitions) { + if (definitionsFilter.Contains (definition.guid)) { + filteredDefinitions.Push (definition); + } + } + + definitions = filteredDefinitions; + + return NoError; +} + + +GSErrCode FilterDefinitionsByPropertyGroup (GS::Array& definitions, const GS::HashSet& propertyGroupsFilter) +{ + if (definitions.IsEmpty ()) + return NoError; + + if (propertyGroupsFilter.IsEmpty ()) { + definitions.Clear (); + return NoError; + } + + GS::Array filteredDefinitions; + for (auto definition : definitions) { + if (propertyGroupsFilter.Contains (definition.groupGuid)) { + filteredDefinitions.Push (definition); + } + } + + definitions = filteredDefinitions; + + return NoError; +} + + +GS::UInt64 GenerateFingerPrint (const API_ElemType& elementType, const bool& sendProperties, const bool& sendListingParameters, const GS::Array>& systemItemPairs) +{ + IO::MD5Channel md5Channel; + MD5::FingerPrint checkSum; + + md5Channel.Write (elementType.typeID); + md5Channel.Write (elementType.variationID); + md5Channel.Write (sendProperties); + md5Channel.Write (sendListingParameters); + + for (auto id : systemItemPairs) { + md5Channel.Write (APIGuid2GSGuid (id.first)); + md5Channel.Write (APIGuid2GSGuid (id.second)); + } + + md5Channel.Finish (&checkSum); + return checkSum.GetUInt64Value (); +} + + +GSErrCode PropertyExportManager::GetElementDefinitions (const API_Element& element, const bool& sendProperties, const bool& sendListingParameters, const GS::Array>& systemItemPairs, GS::Array& elementDefinitions, GS::Array>>& componentsDefinitions) +{ + GSErrCode err = NoError; + + API_ElemType elementType = Utility::GetElementType (element.header); + + GS::Array elementUserDefinedDefinitions; + + // element-level properties + { + GS::UInt64 fingerPrint = GenerateFingerPrint (elementType, sendProperties, sendListingParameters, systemItemPairs); + if (cache.ContainsKey (fingerPrint)) { + elementDefinitions = cache.Get (fingerPrint).first; + elementUserDefinedDefinitions = cache.Get (fingerPrint).second; + } + else { + if (sendProperties) { + err = ACAPI_Element_GetPropertyDefinitions (element.header.guid, API_PropertyDefinitionFilter_UserDefined, elementUserDefinedDefinitions); + if (err != NoError) + return err; + } + + GS::Array elementUserLevelBuiltInDefinitions; + if (sendListingParameters) { + err = ACAPI_Element_GetPropertyDefinitions (element.header.guid, API_PropertyDefinitionFilter_UserLevelBuiltIn, elementUserLevelBuiltInDefinitions); + if (err != NoError) + return err; + + err = FilterDefinitionsByDefinitionIds (elementUserLevelBuiltInDefinitions, propertyGroupFilter.elementPropertiesFilter); + if (err != NoError) + return err; + } + + elementDefinitions = elementUserDefinedDefinitions; + elementDefinitions.Append (elementUserLevelBuiltInDefinitions); + + cache.Add (fingerPrint, GS::Pair, GS::Array> (elementDefinitions, elementUserDefinedDefinitions)); + } + } + + // components properties + // because of performance reasons components are skipped for complex elements + if (complexElementsToSkipFromComponentListing.Contains (elementType)) + return NoError; + + GS::Array components; + err = ACAPI_Element_GetComponents (element.header.guid, components); + if (err != NoError) + return err; + + componentsDefinitions.Clear (); + for (auto& component : components) { + GS::Array componentUserDefinedDefinitions; + + if (sendProperties) { +#ifdef ServerMainVers_2700 + err = ACAPI_Element_GetPropertyDefinitions (component, API_PropertyDefinitionFilter_UserDefined, componentUserDefinedDefinitions); +#else + err = ACAPI_ElemComponent_GetPropertyDefinitions (component, API_PropertyDefinitionFilter_UserDefined, componentUserDefinedDefinitions); +#endif + if (err != NoError) + continue; + + err = FilterOutDefinitionsByDefinitions (componentUserDefinedDefinitions, elementUserDefinedDefinitions); + if (err != NoError) + continue; + } + + GS::Array componentUserLevelBuiltInDefinitions; + if (sendListingParameters) { +#ifdef ServerMainVers_2700 + err = ACAPI_Element_GetPropertyDefinitions (component, API_PropertyDefinitionFilter_UserLevelBuiltIn, componentUserLevelBuiltInDefinitions); +#else + err = ACAPI_ElemComponent_GetPropertyDefinitions (component, API_PropertyDefinitionFilter_UserLevelBuiltIn, componentUserLevelBuiltInDefinitions); +#endif + if (err != NoError) + continue; + + err = FilterDefinitionsByPropertyGroup (componentUserLevelBuiltInDefinitions, propertyGroupFilter.componentPropertyGroupFilter); + if (err != NoError) + continue; + } + + componentUserDefinedDefinitions.Append (componentUserLevelBuiltInDefinitions); + + componentsDefinitions.Push (GS::Pair> (component, componentUserDefinedDefinitions)); + } + + return NoError; +} diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.hpp new file mode 100644 index 0000000000..9710da6832 --- /dev/null +++ b/ConnectorArchicad/AddOn/Sources/AddOn/PropertyExportManager.hpp @@ -0,0 +1,36 @@ +#ifndef PROPERTY_EXPORT_MANAGER_HPP +#define PROPERTY_EXPORT_MANAGER_HPP + +#include "APIEnvir.h" +#include "ACAPinc.h" + +#include "Utility.hpp" + + +class PropertyExportManager { +private: + static PropertyExportManager* instance; + + struct PropertyGroupFilter { + GS::HashSet elementPropertiesFilter; + GS::HashSet componentPropertyGroupFilter; + }; + + PropertyGroupFilter propertyGroupFilter; + GS::HashSet complexElementsToSkipFromComponentListing; + + GS::HashTable, GS::Array>> cache; + +protected: + PropertyExportManager (); + +public: + PropertyExportManager (PropertyExportManager&) = delete; + void operator=(const PropertyExportManager&) = delete; + static PropertyExportManager* GetInstance (); + static void DeleteInstance (); + + GSErrCode GetElementDefinitions (const API_Element& element, const bool& sendProperties, const bool& sendListingParameters, const GS::Array>& systemItemPairs, GS::Array& elementsDefinitions, GS::Array < GS::Pair>>& componentsDefinitions); +}; + +#endif diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/ResourceIds.hpp b/ConnectorArchicad/AddOn/Sources/AddOn/ResourceIds.hpp index c1354d0cde..147706b24e 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/ResourceIds.hpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/ResourceIds.hpp @@ -30,7 +30,6 @@ #define GetShellDataCommandName "GetShellData"; #define GetSkylightCommandName "GetSkylightData"; #define GetProjectInfoCommandName "GetProjectInfo"; -#define GetSubelementInfoCommandName "GetSubelementInfo"; #define CreateDirectShapeCommandName "CreateDirectShape"; #define CreateWallCommandName "CreateWall"; #define CreateDoorCommandName "CreateDoor"; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/TypeNameTables.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/TypeNameTables.cpp index 63652d462c..52c35275b6 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/TypeNameTables.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/TypeNameTables.cpp @@ -115,6 +115,10 @@ const GS::HashTable relationToZoneNames { APIZRel_Boundary, "Zone Boundary"}, { APIZRel_ReduceArea, "Reduce Zone Area Only"}, { APIZRel_None, "No Effect on Zones"} +#ifdef ServerMainVers_2700 + , + { APIZRel_SubtractFromZone, "Subtract from Zones"} +#endif }; diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Utility.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Utility.cpp index 9c1b1e4b14..e03f40e364 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Utility.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Utility.cpp @@ -1,3 +1,4 @@ +#include "APIMigrationHelper.hpp" #include "Utility.hpp" #include "ObjectState.hpp" #include "RealNumber.h" @@ -137,7 +138,9 @@ GS::ErrCode GetNonLocalizedElementTypeName (const API_Elem_Head& header, GS::Uni GS::ErrCode GetLocalizedElementTypeName (const API_Elem_Head& header, GS::UniString& typeName) { -#ifdef ServerMainVers_2600 +#ifdef ServerMainVers_2700 + return ACAPI_Element_GetElemTypeName (header.type, typeName); +#elif ServerMainVers_2600 return ACAPI_Goodies_GetElemTypeName (header.type, typeName); #else ResourceStrings::ElementTypeStringItems elementTypeStringItem; @@ -204,14 +207,14 @@ GSErrCode GetBaseElementData (API_Element& element, API_ElementMemo* memo, API_S BNZeroMemory (&libPart, sizeof (API_LibPart)); #ifdef ServerMainVers_2600 - err = ACAPI_Goodies_GetMarkerParent (element.header.type, libPart); + err = ACAPI_LibraryPart_GetMarkerParent (element.header.type, libPart); #else err = ACAPI_Goodies (APIAny_GetMarkerParentID, &element.header.typeID, &libPart); #endif if (err != NoError) return err; - err = ACAPI_LibPart_Search (&libPart, false, true); + err = ACAPI_LibraryPart_Search (&libPart, false, true); if (libPart.location != nullptr) delete libPart.location; @@ -223,7 +226,7 @@ GSErrCode GetBaseElementData (API_Element& element, API_ElementMemo* memo, API_S double a = .0, b = .0; Int32 addParNum = 0; API_AddParType** markAddPars; - err = ACAPI_LibPart_GetParams (libPart.index, &a, &b, &addParNum, &markAddPars); + err = ACAPI_LibraryPart_GetParams (libPart.index, &a, &b, &addParNum, &markAddPars); if (err != NoError) return err; @@ -271,7 +274,7 @@ GS::Array GetStoryItems () GS::Array stories; API_StoryInfo storyInfo{}; - GSErrCode err = ACAPI_Environment (APIEnv_GetStorySettingsID, &storyInfo, nullptr); + GSErrCode err = ACAPI_ProjectSetting_GetStorySettings (&storyInfo /* , nullptr */); if (err != NoError) { return stories; } @@ -330,7 +333,7 @@ void SetStoryLevel (const double& inLevel, const short& floorIndex, double& leve static API_StoryType GetActualStoryItem () { API_StoryInfo storyInfo{}; - GSErrCode err = ACAPI_Environment (APIEnv_GetStorySettingsID, &storyInfo, nullptr); + GSErrCode err = ACAPI_ProjectSetting_GetStorySettings (&storyInfo); if (err != NoError) { return API_StoryType{}; } @@ -364,7 +367,7 @@ void SetStoryLevelAndFloor (const double& inLevel, short& floorInd, double& leve API_WindowInfo windowInfo; BNZeroMemory (&windowInfo, sizeof (API_WindowInfo)); - GSErrCode err = ACAPI_Database (APIDb_GetCurrentWindowID, &windowInfo, nullptr); + GSErrCode err = ACAPI_Window_GetCurrentWindow(&windowInfo); if (err == NoError && (windowInfo.typeID != APIWind_FloorPlanID && windowInfo.typeID != APIWind_3DModelID)) floorInd += GetActualStoryItem ().index; } @@ -379,19 +382,19 @@ GS::Array GetElementSubelements (API_Element& element) if (elementType == API_WallID) { if (element.wall.hasDoor) { GS::Array doors; - GSErrCode err = ACAPI_Element_GetConnectedElements (element.header.guid, API_DoorID, &doors); + GSErrCode err = ACAPI_Grouping_GetConnectedElements (element.header.guid, API_DoorID, &doors); if (err == NoError) result.Append (doors); } if (element.wall.hasWindow) { GS::Array windows; - GSErrCode err = ACAPI_Element_GetConnectedElements (element.header.guid, API_WindowID, &windows); + GSErrCode err = ACAPI_Grouping_GetConnectedElements (element.header.guid, API_WindowID, &windows); if (err == NoError) result.Append (windows); } } else if ((elementType == API_RoofID) || (elementType == API_ShellID)) { GS::Array skylights; - GSErrCode err = ACAPI_Element_GetConnectedElements (element.header.guid, API_SkylightID, &skylights); + GSErrCode err = ACAPI_Grouping_GetConnectedElements (element.header.guid, API_SkylightID, &skylights); if (err == NoError) result.Append (skylights); } @@ -416,8 +419,8 @@ GSErrCode GetSegmentData (const API_AssemblySegmentData& segmentData, GS::Object API_Attribute attrib; switch (segmentData.modelElemStructureType) { case API_CompositeStructure: - DBASSERT (segment.modelElemStructureType != API_CompositeStructure) - break; + DBASSERT (segmentData.modelElemStructureType != API_CompositeStructure); + break; case API_BasicStructure: BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_BuildingMaterialID; @@ -541,16 +544,16 @@ GSErrCode GetOneSchemeData (const API_AssemblySegmentSchemeData& schemeData, GS: GSErrCode GetAllSchemeData (API_AssemblySegmentSchemeData* schemeData, GS::ObjectState& out) { - if (schemeData == nullptr) return Error; + if (schemeData == nullptr) + return Error; GSSize schemesCount = BMGetPtrSize (reinterpret_cast(schemeData)) / sizeof (API_AssemblySegmentSchemeData); - DBASSERT (schemesCount == elem.column.nSchemes) - for (GSSize idx = 0; idx < schemesCount; ++idx) { - GS::ObjectState currentScheme; - Utility::GetOneSchemeData (schemeData[idx], currentScheme); - out.Add (GS::String::SPrintf (AssemblySegment::SchemeName, idx + 1), currentScheme); - } + for (GSSize idx = 0; idx < schemesCount; ++idx) { + GS::ObjectState currentScheme; + Utility::GetOneSchemeData (schemeData[idx], currentScheme); + out.Add (GS::String::SPrintf (AssemblySegment::SchemeName, idx + 1), currentScheme); + } return NoError; } diff --git a/ConnectorArchicad/AddOn/Sources/AddOnResources/RINT/AddOn.grc b/ConnectorArchicad/AddOn/Sources/AddOnResources/RINT/AddOn.grc index e268d6d4e7..17c257fa00 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOnResources/RINT/AddOn.grc +++ b/ConnectorArchicad/AddOn/Sources/AddOnResources/RINT/AddOn.grc @@ -6,7 +6,7 @@ } 'STR#' ID_ADDON_MENU "Strings for the Menu" { -/* [ 1] */ "ALPHA Speckle Connector ^E3 ^ES ^EE ^EI ^ED ^ET ^10001" +/* [ 1] */ "Speckle Connector ^E3 ^ES ^EE ^EI ^ED ^ET ^10001" } 'STR#' ID_LOG_MESSAGES "Messages for conversion log" { diff --git a/ConnectorArchicad/ConnectorArchicad.slnf b/ConnectorArchicad/ConnectorArchicad.slnf index d5c96d396d..c495478dc5 100644 --- a/ConnectorArchicad/ConnectorArchicad.slnf +++ b/ConnectorArchicad/ConnectorArchicad.slnf @@ -4,11 +4,11 @@ "projects": [ "ConnectorArchicad\\ConnectorArchicad\\ConnectorArchicad.csproj", "Core\\Core\\Core.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorArchicad/ConnectorArchicad/Assets/icon.ico b/ConnectorArchicad/ConnectorArchicad/Assets/icon.ico new file mode 100644 index 0000000000..0f8ddd8508 Binary files /dev/null and b/ConnectorArchicad/ConnectorArchicad/Assets/icon.ico differ diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/AsyncCommandProcessor.cs b/ConnectorArchicad/ConnectorArchicad/Communication/AsyncCommandProcessor.cs index c0a20ce18f..eeae281e6b 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/AsyncCommandProcessor.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/AsyncCommandProcessor.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Speckle.Core.Logging; namespace Archicad.Communication; @@ -27,8 +28,9 @@ internal class AsyncCommandProcessor { return Task.Run(command.Execute, token); } - catch (Exception e) + catch (Exception ex) when (ex is TaskCanceledException or ObjectDisposedException) { + SpeckleLog.Logger.Error(ex, "Could not communicate with Archicad."); return null; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_CreateObject.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_CreateObject.cs index fd17b2586c..1502f17c2d 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_CreateObject.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_CreateObject.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Speckle.Core.Models; using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; using Archicad.Model; namespace Archicad.Communication.Commands; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_FinishReceiveTransaction.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_FinishReceiveTransaction.cs index 0d18b25ff5..c74979e226 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_FinishReceiveTransaction.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_FinishReceiveTransaction.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Data; using System.Threading.Tasks; using Speckle.Newtonsoft.Json; -using Speckle.Core.Models; -using Objects.BuiltElements.Archicad; namespace Archicad.Communication.Commands; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetBeamData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetBeamData.cs index 36f7fd5716..12d5d7778d 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetBeamData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetBeamData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetBeamData : ICommand +sealed internal class GetBeamData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetBeamData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetBeamData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetBeamData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["beams"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetColumnData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetColumnData.cs index e4e9d62fe6..858b59bf1b 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetColumnData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetColumnData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetColumnData : ICommand +sealed internal class GetColumnData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetColumnData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetColumnData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetColumnData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["columns"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDataBase.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDataBase.cs new file mode 100644 index 0000000000..1e37dc0a27 --- /dev/null +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDataBase.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using Speckle.Newtonsoft.Json; + +namespace ConnectorArchicad.Communication.Commands; + +internal class GetDataBase +{ + [JsonObject(MemberSerialization.OptIn)] + internal class Parameters + { + [JsonProperty("applicationIds")] + protected IEnumerable ApplicationIds { get; } + + [JsonProperty("sendProperties")] + protected bool SendProperties { get; } + + [JsonProperty("sendListingParameters")] + protected bool SendListingParameters { get; } + + public Parameters(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + { + ApplicationIds = applicationIds; + SendProperties = sendProperties; + SendListingParameters = sendListingParameters; + } + } + + protected IEnumerable ApplicationIds { get; } + protected bool SendProperties { get; } + protected bool SendListingParameters { get; } + + public GetDataBase(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + { + ApplicationIds = applicationIds; + SendProperties = sendProperties; + SendListingParameters = sendListingParameters; + } +} diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDoorData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDoorData.cs index 18c8a4fdcd..966ae0adfa 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDoorData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetDoorData.cs @@ -1,48 +1,21 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Core.Kits; -using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetDoorData : ICommand> +sealed internal class GetDoorData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - [JsonObject(MemberSerialization.OptIn)] - private sealed class Result - { - [JsonProperty("doors")] - public IEnumerable Datas { get; private set; } - } - - private IEnumerable ApplicationIds { get; } - - public GetDoorData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetDoorData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } - public async Task> Execute() + public async Task Execute() { - Result result = await HttpCommandExecutor.Execute( + dynamic result = await HttpCommandExecutor.Execute( "GetDoorData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); - //foreach (var subelement in result.Datas) - //subelement.units = Units.Meters; - return result.Datas; + return (Speckle.Newtonsoft.Json.Linq.JArray)result["doors"]; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementBaseData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementBaseData.cs index 5b70119fe9..56fe20729e 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementBaseData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementBaseData.cs @@ -3,23 +3,12 @@ using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; using Objects.BuiltElements.Archicad; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetElementBaseData : ICommand> +sealed internal class GetElementBaseData : GetDataBase, ICommand> { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - [JsonObject(MemberSerialization.OptIn)] private sealed class Result { @@ -27,18 +16,14 @@ private sealed class Result public IEnumerable Datas { get; private set; } } - private IEnumerable ApplicationIds { get; } - - public GetElementBaseData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetElementBaseData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task> Execute() { Result result = await HttpCommandExecutor.Execute( "GetElementBaseData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); foreach (var directShape in result.Datas) { diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementIds.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementIds.cs index aa13354f2c..811370c72c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementIds.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementIds.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; using Speckle.Newtonsoft.Json.Converters; -using Objects.BuiltElements.Archicad; namespace Archicad.Communication.Commands; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementType.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementType.cs index a53ebb6e53..95e3234160 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementType.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetElementType.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; -using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; namespace Archicad.Communication.Commands; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetFloorData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetFloorData.cs index 2f0181ac02..578b5907b6 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetFloorData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetFloorData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -internal sealed class GetFloorData : ICommand +internal sealed class GetFloorData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetFloorData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetFloorData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetSlabData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["slabs"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetGridElementData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetGridElementData.cs index 24f5506ff8..527f232a07 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetGridElementData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetGridElementData.cs @@ -1,25 +1,12 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; -using Objects.BuiltElements; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetGridElementData : ICommand> +sealed internal class GetGridElementData : GetDataBase, ICommand> { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - [JsonObject(MemberSerialization.OptIn)] private sealed class Result { @@ -27,18 +14,15 @@ private sealed class Result public IEnumerable Datas { get; private set; } } - private IEnumerable ApplicationIds { get; } - - public GetGridElementData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetGridElementData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, false, false) // common GridLine class in Objects kit has no Archicad-related properties + { } public async Task> Execute() { Result result = await HttpCommandExecutor.Execute( "GetGridElementData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return result.Datas; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetObjectData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetObjectData.cs index 5e13efaad4..aac5def320 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetObjectData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetObjectData.cs @@ -2,24 +2,12 @@ using System.Threading.Tasks; using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetObjectData : ICommand> +sealed internal class GetObjectData : GetDataBase, ICommand> { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - [JsonObject(MemberSerialization.OptIn)] private sealed class Result { @@ -27,18 +15,14 @@ private sealed class Result public IEnumerable Datas { get; private set; } } - private IEnumerable ApplicationIds { get; } - - public GetObjectData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetObjectData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task> Execute() { Result result = await HttpCommandExecutor.Execute( "GetObjectData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); foreach (var @object in result.Datas) { diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoofData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoofData.cs index dc8dadf112..2b49d17e0f 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoofData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoofData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -internal sealed class GetRoofData : ICommand +internal sealed class GetRoofData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetRoofData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetRoofData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetRoofData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["roofs"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoomData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoomData.cs index 654a5349e2..b760969cf0 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoomData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetRoomData.cs @@ -1,25 +1,12 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Core.Kits; using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetRoomData : ICommand> +sealed internal class GetRoomData : GetDataBase, ICommand> { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - [JsonObject(MemberSerialization.OptIn)] private sealed class Result { @@ -27,16 +14,15 @@ private sealed class Result public IEnumerable Rooms { get; private set; } } - private IEnumerable ApplicationIds { get; } - - public GetRoomData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetRoomData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task> Execute() { - var result = await HttpCommandExecutor.Execute("GetRoomData", new Parameters(ApplicationIds)); + var result = await HttpCommandExecutor.Execute( + "GetRoomData", + new Parameters(ApplicationIds, SendProperties, SendListingParameters) + ); return result.Rooms; } diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetShellData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetShellData.cs index b2a9c9f065..868e91a59e 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetShellData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetShellData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -internal sealed class GetShellData : ICommand +internal sealed class GetShellData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetShellData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetShellData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetShellData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["shells"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSkylightData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSkylightData.cs index 50cfe77f77..f6e8afc1a7 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSkylightData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSkylightData.cs @@ -1,48 +1,21 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Objects.BuiltElements.Archicad; -using Speckle.Core.Kits; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetSkylightData : ICommand> +sealed internal class GetSkylightData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - [JsonObject(MemberSerialization.OptIn)] - private sealed class Result - { - [JsonProperty("skylights")] - public IEnumerable Datas { get; private set; } - } - - private IEnumerable ApplicationIds { get; } - - public GetSkylightData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetSkylightData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } - public async Task> Execute() + public async Task Execute() { - Result result = await HttpCommandExecutor.Execute( + dynamic result = await HttpCommandExecutor.Execute( "GetSkylightData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); - //foreach (var subelement in result.Datas) - //subelement.units = Units.Meters; - return result.Datas; + return (Speckle.Newtonsoft.Json.Linq.JArray)result["skylights"]; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSubelementInfo.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSubelementInfo.cs deleted file mode 100644 index 2b0da5a7ad..0000000000 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetSubelementInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Speckle.Core.Kits; -using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; - -namespace Archicad.Communication.Commands; - -sealed internal class GetSubElementInfo : ICommand> -{ - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationId")] - private string ApplicationId { get; } - - public Parameters(string applicationId) - { - ApplicationId = applicationId; - } - } - - [JsonObject(MemberSerialization.OptIn)] - private sealed class Result - { - [JsonProperty("subelementModels")] - public IEnumerable Datas { get; private set; } - } - - private string ApplicationId { get; } - - public GetSubElementInfo(string applicationId) - { - ApplicationId = applicationId; - } - - public async Task> Execute() - { - Result result = await HttpCommandExecutor.Execute( - "GetSubelementInfo", - new Parameters(ApplicationId) - ); - return result.Datas; - } -} diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWallData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWallData.cs index 103a7f9551..89b32fb908 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWallData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWallData.cs @@ -1,35 +1,19 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Newtonsoft.Json; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetWallData : ICommand +sealed internal class GetWallData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - private IEnumerable ApplicationIds { get; } - - public GetWallData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetWallData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } public async Task Execute() { dynamic result = await HttpCommandExecutor.Execute( "GetWallData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); return (Speckle.Newtonsoft.Json.Linq.JArray)result["walls"]; diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWindowData.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWindowData.cs index 8fb5267582..470382b87c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWindowData.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_GetWindowData.cs @@ -1,48 +1,21 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Speckle.Core.Kits; -using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.Archicad; +using ConnectorArchicad.Communication.Commands; namespace Archicad.Communication.Commands; -sealed internal class GetWindowData : ICommand> +sealed internal class GetWindowData : GetDataBase, ICommand { - [JsonObject(MemberSerialization.OptIn)] - public sealed class Parameters - { - [JsonProperty("applicationIds")] - private IEnumerable ApplicationIds { get; } - - public Parameters(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } - } - - [JsonObject(MemberSerialization.OptIn)] - private sealed class Result - { - [JsonProperty("windows")] - public IEnumerable Datas { get; private set; } - } - - private IEnumerable ApplicationIds { get; } - - public GetWindowData(IEnumerable applicationIds) - { - ApplicationIds = applicationIds; - } + public GetWindowData(IEnumerable applicationIds, bool sendProperties, bool sendListingParameters) + : base(applicationIds, sendProperties, sendListingParameters) { } - public async Task> Execute() + public async Task Execute() { - Result result = await HttpCommandExecutor.Execute( + dynamic result = await HttpCommandExecutor.Execute( "GetWindowData", - new Parameters(ApplicationIds) + new Parameters(ApplicationIds, SendProperties, SendListingParameters) ); - //foreach (var subelement in result.Datas) - //subelement.units = Units.Meters; - return result.Datas; + return (Speckle.Newtonsoft.Json.Linq.JArray)result["windows"]; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_SelectElements.cs b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_SelectElements.cs index 56d1db191d..138fc659b0 100644 --- a/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_SelectElements.cs +++ b/ConnectorArchicad/ConnectorArchicad/Communication/Commands/Command_SelectElements.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Runtime.Serialization; using System.Threading.Tasks; using Speckle.Newtonsoft.Json; diff --git a/ConnectorArchicad/ConnectorArchicad/ConnectorArchicad.csproj b/ConnectorArchicad/ConnectorArchicad/ConnectorArchicad.csproj index e900ee978f..e83aa31a00 100644 --- a/ConnectorArchicad/ConnectorArchicad/ConnectorArchicad.csproj +++ b/ConnectorArchicad/ConnectorArchicad/ConnectorArchicad.csproj @@ -1,15 +1,20 @@ - Exe + WinExe net6.0 enable ConnectorArchicad + Assets\icon.ico 1 + + + + diff --git a/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs b/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs index 3dc7e6aa50..8a34225426 100644 --- a/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs +++ b/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs @@ -9,7 +9,6 @@ using DesktopUI2.Models; using DesktopUI2.Models.Filters; using DesktopUI2.ViewModels; -using Speckle.Core.Api; using Speckle.Core.Credentials; using Speckle.Core.Kits; using Speckle.Core.Logging; @@ -174,22 +173,14 @@ public override async Task ReceiveStream(StreamState state, Progres } } } - catch (Exception ex) + catch (SpeckleException ex) { - // log - if (ex is not OperationCanceledException) - { - SpeckleLog.Logger.Error("Conversion to native failed."); - } - - // throw - switch (ex) - { - case OperationCanceledException: - throw new OperationCanceledException(ex.Message); - default: - throw new SpeckleException(ex.Message, ex); - } + SpeckleLog.Logger.Error(ex, "Conversion to native failed."); + throw; + } + catch (OperationCanceledException) + { + throw; } return state; @@ -213,7 +204,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod throw new InvalidOperationException("Expected selection filter to be non-null"); } - var commitObject = await ElementConverterManager.Instance.ConvertToSpeckle(state.Filter, progress); + var commitObject = await ElementConverterManager.Instance.ConvertToSpeckle(state, progress); if (commitObject == null) { @@ -224,6 +215,8 @@ public override async Task SendStream(StreamState state, ProgressViewMod var context = Archicad.Helpers.Timer.Context.Peek; using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.SendToServer)) { + progress.Value = 0; + progress.Max = 0; return await Speckle.Core.Api.Helpers.Send( IdentifyStream(state), commitObject, diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ConversionOptions.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ConversionOptions.cs index b426e11b12..68e3c9617c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ConversionOptions.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ConversionOptions.cs @@ -1,7 +1,7 @@ -using System; using System.Collections.Generic; using DesktopUI2.Models.Settings; -using DesktopUI2.Views.Controls.StreamEditControls; +using DynamicData; +using static Archicad.Launcher.ArchicadBinding; namespace Archicad; @@ -11,16 +11,27 @@ public ConversionOptions(List settings) { foreach (var setting in settings) { - if (setting.Slug.Equals("receive - parametric")) + switch (settingSlugs.IndexOf(setting.Slug)) { - if (bool.Parse(setting.Selection ?? "False")) - { - ReceiveParametric = true; - } + case (int)SettingSlugs.SendProperties: + SendProperties = ((CheckBoxSetting)setting).IsChecked; + break; + + case (int)SettingSlugs.SendListingParameters: + SendListingParameters = ((CheckBoxSetting)setting).IsChecked; + break; + + case (int)SettingSlugs.ReceiveParametric: + ReceiveParametric = ((CheckBoxSetting)setting).IsChecked; + break; + + default: + break; } } - ; } + public bool SendProperties { get; set; } + public bool SendListingParameters { get; set; } public bool ReceiveParametric { get; set; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ConverterArchicad.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ConverterArchicad.cs index 1ff153fe6a..29506c6a58 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ConverterArchicad.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ConverterArchicad.cs @@ -2,11 +2,9 @@ using System.Collections.Generic; using System.Linq; using Archicad; -using Objects.Geometry; using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; -using static Speckle.Core.Models.ApplicationObject; namespace Objects.Converter.Archicad; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs index 8112141ef5..1dcf566e77 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs @@ -35,23 +35,26 @@ CancellationToken token switch (tc.current) { case Objects.BuiltElements.Archicad.ArchicadBeam archiBeam: + Archicad.Converters.Utils.ConvertToArchicadDTOs(archiBeam); beams.Add(archiBeam); break; case Objects.BuiltElements.Beam beam: // upgrade (if not Archicad beam): Objects.BuiltElements.Beam --> Objects.BuiltElements.Archicad.ArchicadBeam { - var baseLine = (Line)beam.baseLine; - var newBeam = new Objects.BuiltElements.Archicad.ArchicadBeam + if (beam.baseLine is Line baseLine) { - id = beam.id, - applicationId = beam.applicationId, - archicadLevel = Archicad.Converters.Utils.ConvertLevel(beam.level), - begC = Utils.ScaleToNative(baseLine.start), - endC = Utils.ScaleToNative(baseLine.end) - }; - - beams.Add(newBeam); + beams.Add( + new Objects.BuiltElements.Archicad.ArchicadBeam + { + id = beam.id, + applicationId = beam.applicationId, + archicadLevel = Archicad.Converters.Utils.ConvertLevel(beam.level), + begC = Utils.ScaleToNative(baseLine.start), + endC = Utils.ScaleToNative(baseLine.end) + } + ); + } } break; @@ -65,12 +68,20 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetBeamData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetBeamData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -89,7 +100,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); // downgrade (always): Objects.BuiltElements.Archicad.ArchicadBeam --> Objects.BuiltElements.Beam { diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs index 306343175f..d3b1018bb7 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs @@ -35,24 +35,31 @@ CancellationToken token switch (tc.current) { case Objects.BuiltElements.Archicad.ArchicadColumn archicadColumn: + Archicad.Converters.Utils.ConvertToArchicadDTOs( + archicadColumn + ); columns.Add(archicadColumn); break; case Objects.BuiltElements.Column column: - var baseLine = (Line)column.baseLine; - Objects.BuiltElements.Archicad.ArchicadColumn newColumn = - new() - { - id = column.id, - applicationId = column.applicationId, - archicadLevel = Archicad.Converters.Utils.ConvertLevel(column.level), - origoPos = Utils.ScaleToNative(baseLine.start), - height = Math.Abs( - Utils.ScaleToNative(baseLine.end.z, baseLine.end.units) - - Utils.ScaleToNative(baseLine.start.z, baseLine.start.units) - ) - }; - columns.Add(newColumn); + { + if (column.baseLine is Line baseLine) + { + columns.Add( + new Objects.BuiltElements.Archicad.ArchicadColumn + { + id = column.id, + applicationId = column.applicationId, + archicadLevel = Archicad.Converters.Utils.ConvertLevel(column.level), + origoPos = Utils.ScaleToNative(baseLine.start), + height = Math.Abs( + Utils.ScaleToNative(baseLine.end.z, baseLine.end.units) + - Utils.ScaleToNative(baseLine.start.z, baseLine.start.units) + ) + } + ); + } + } break; } } @@ -63,11 +70,19 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetColumnData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetColumnData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -86,7 +101,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); column.units = Units.Meters; column.displayValue = Operations.ModelConverter.MeshesToSpeckle( diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs index cf2915958b..c47a607798 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs @@ -6,12 +6,9 @@ using Archicad.Communication; using Archicad.Model; using Archicad.Operations; -using DynamicData; -using Objects.BuiltElements; using Objects.Geometry; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; -using Speckle.Newtonsoft.Json.Linq; namespace Archicad.Converters; @@ -79,11 +76,19 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetElementBaseData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetElementBaseData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs index 6a937fc4a1..134a841e62 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs @@ -5,9 +5,6 @@ using System.Threading.Tasks; using Archicad.Communication; using Archicad.Model; -using Objects.BuiltElements; -using Objects.BuiltElements.Revit; -using Objects.Geometry; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; @@ -37,6 +34,7 @@ CancellationToken token { case Objects.BuiltElements.Archicad.ArchicadDoor archicadDoor: archicadDoor.parentApplicationId = tc.parent.current.id; + Archicad.Converters.Utils.ConvertToArchicadDTOs(archicadDoor); doors.Add(archicadDoor); break; //case Objects.BuiltElements.Opening window: @@ -57,15 +55,25 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); - IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetDoorData(elementModels.Select(e => e.applicationId)) + + Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( + new Communication.Commands.GetDoorData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), + token ); - var openings = new List(); - if (data is null) + List openings = new(); + if (jArray is null) { return openings; } @@ -75,12 +83,14 @@ public async Task> ConvertToSpeckle(IEnumerable e.applicationId == subelement.applicationId).model + Objects.BuiltElements.Archicad.ArchicadDoor door = + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); + door.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == door.applicationId).model ); - openings.Add(subelement); + openings.Add(door); } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs index c3b67f21e2..6f378fa2ff 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs @@ -5,8 +5,9 @@ using System.Threading.Tasks; using Archicad.Communication; using Objects; -using Speckle.Core.Models; using Speckle.Core.Kits; +using Speckle.Core.Logging; +using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; namespace Archicad.Converters; @@ -34,20 +35,29 @@ CancellationToken token switch (tc.current) { case Objects.BuiltElements.Archicad.ArchicadFloor archiFloor: + Archicad.Converters.Utils.ConvertToArchicadDTOs(archiFloor); floors.Add(archiFloor); break; case Objects.BuiltElements.Floor floor: - Objects.BuiltElements.Archicad.ArchicadFloor newFloor = - new() + { + try { - id = floor.id, - applicationId = floor.applicationId, - archicadLevel = Archicad.Converters.Utils.ConvertLevel(floor.level), - shape = Utils.PolycurvesToElementShape(floor.outline, floor.voids) - }; - - floors.Add(newFloor); + floors.Add( + new Objects.BuiltElements.Archicad.ArchicadFloor + { + id = floor.id, + applicationId = floor.applicationId, + archicadLevel = Archicad.Converters.Utils.ConvertLevel(floor.level), + shape = Utils.PolycurvesToElementShape(floor.outline, floor.voids) + } + ); + } + catch (SpeckleException ex) + { + SpeckleLog.Logger.Error(ex, "Polycurves conversion failed."); + } + } break; } } @@ -60,10 +70,18 @@ CancellationToken token ; } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetFloorData(elements.Select(e => e.applicationId)), + new Communication.Commands.GetFloorData( + elements.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -82,7 +100,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); slab.units = Units.Meters; slab.displayValue = Operations.ModelConverter.MeshesToSpeckle( diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs index d4c075f86a..ee02fe0ec9 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs @@ -74,11 +74,19 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetGridElementData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetGridElementData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/IElementConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/IElementConverter.cs index ddcec831ee..3f03df9a12 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/IElementConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/IElementConverter.cs @@ -17,7 +17,11 @@ public interface IConverter #region --- Functions --- - Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token); + Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions state + ); Task> ConvertToArchicad(IEnumerable elements, CancellationToken token); diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ObjectConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ObjectConverter.cs index af19245732..088c62ddb5 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ObjectConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ObjectConverter.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Numerics; using System.Threading; using System.Threading.Tasks; using Archicad.Communication; using Archicad.Model; using Archicad.Operations; -using Objects.BuiltElements.Revit; using Objects.Geometry; using Objects.Other; using Speckle.Core.Kits; @@ -247,7 +245,11 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions state + ) { // Objects not stored on the server return new List(); diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs index 2d423c6047..0820db005c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs @@ -5,9 +5,9 @@ using System.Threading.Tasks; using Archicad.Communication; using Objects; -using Objects.BuiltElements; -using Speckle.Core.Models; using Speckle.Core.Kits; +using Speckle.Core.Logging; +using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; namespace Archicad.Converters; @@ -36,21 +36,33 @@ CancellationToken token switch (tc.current) { case Objects.BuiltElements.Archicad.ArchicadRoof archiRoof: + Archicad.Converters.Utils.ConvertToArchicadDTOs(archiRoof); roofs.Add(archiRoof); break; case Objects.BuiltElements.Archicad.ArchicadShell archiShell: + Archicad.Converters.Utils.ConvertToArchicadDTOs(archiShell); shells.Add(archiShell); break; case Objects.BuiltElements.Roof roof: - roofs.Add( - new Objects.BuiltElements.Archicad.ArchicadRoof + + { + try { - id = roof.id, - applicationId = roof.applicationId, - archicadLevel = Archicad.Converters.Utils.ConvertLevel(roof.level), - shape = Utils.PolycurvesToElementShape(roof.outline, roof.voids) + roofs.Add( + new Objects.BuiltElements.Archicad.ArchicadRoof + { + id = roof.id, + applicationId = roof.applicationId, + archicadLevel = Archicad.Converters.Utils.ConvertLevel(roof.level), + shape = Utils.PolycurvesToElementShape(roof.outline, roof.voids) + } + ); } - ); + catch (SpeckleException ex) + { + SpeckleLog.Logger.Error(ex, "Polycurves conversion failed."); + } + } break; } } @@ -77,10 +89,18 @@ CancellationToken token return result is null ? new List() : result; } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetRoofData(elements.Select(e => e.applicationId)), + new Communication.Commands.GetRoofData( + elements.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -96,7 +116,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); roof.units = Units.Meters; roof.displayValue = Operations.ModelConverter.MeshesToSpeckle( @@ -118,7 +138,11 @@ public async Task> ConvertToSpeckle(IEnumerable e.applicationId)), + new Communication.Commands.GetShellData( + elements.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -134,7 +158,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); shell.units = Units.Meters; shell.displayValue = Operations.ModelConverter.MeshesToSpeckle( diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs index 792b261899..f43f306400 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs @@ -5,12 +5,11 @@ using System.Threading.Tasks; using Archicad.Communication; using Archicad.Model; -using DynamicData; using Objects; -using Objects.BuiltElements; using Objects.BuiltElements.Archicad; using Objects.Geometry; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; @@ -65,21 +64,27 @@ CancellationToken token case Objects.BuiltElements.Room speckleRoom: { - Archicad.Room archicadRoom = - new() - { - // Speckle base properties - id = speckleRoom.id, - applicationId = speckleRoom.applicationId, - // Speckle general properties - name = speckleRoom.name, - number = speckleRoom.number, - // Archicad properties - level = Archicad.Converters.Utils.ConvertLevel(speckleRoom.level), - shape = Utils.PolycurvesToElementShape(speckleRoom.outline, speckleRoom.voids) - }; - - rooms.Add(archicadRoom); + try + { + rooms.Add( + new Archicad.Room + { + // Speckle base properties + id = speckleRoom.id, + applicationId = speckleRoom.applicationId, + // Speckle general properties + name = speckleRoom.name, + number = speckleRoom.number, + // Archicad properties + level = Archicad.Converters.Utils.ConvertLevel(speckleRoom.level), + shape = Utils.PolycurvesToElementShape(speckleRoom.outline, speckleRoom.voids) + } + ); + } + catch (SpeckleException ex) + { + SpeckleLog.Logger.Error(ex, "Polycurves conversion failed."); + } } break; } @@ -91,11 +96,19 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetRoomData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetRoomData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -126,6 +139,8 @@ public async Task> ConvertToSpeckle(IEnumerable( + archicadSkylight + ); skylights.Add(archicadSkylight); break; //case Objects.BuiltElements.Opening skylight: @@ -56,16 +56,25 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { // Get subelements var elementModels = elements as ElementModelData[] ?? elements.ToArray(); - IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetSkylightData(elementModels.Select(e => e.applicationId)) + Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( + new Communication.Commands.GetSkylightData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), + token ); - var openings = new List(); - if (data is null) + List openings = new(); + if (jArray is null) { return openings; } @@ -75,12 +84,15 @@ public async Task> ConvertToSpeckle(IEnumerable e.applicationId == subelement.applicationId).model + Objects.BuiltElements.Archicad.ArchicadSkylight skylight = + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); + + skylight.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == skylight.applicationId).model ); - openings.Add(subelement); + openings.Add(skylight); } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/Utils.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/Utils.cs index ba1b6aed5d..792d1992e7 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/Utils.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/Utils.cs @@ -3,7 +3,6 @@ using System.Reflection; using Archicad.Model; using Objects; -using Objects.BuiltElements; using Objects.BuiltElements.Archicad; using Objects.Geometry; using Speckle.Core.Kits; @@ -152,28 +151,84 @@ public static ElementShape PolycurvesToElementShape(ICurve outline, List return shape; } - public static T ConvertDTOs(dynamic jObject) + public static T ConvertToSpeckleDTOs(dynamic jObject) { - Objects.BuiltElements.Archicad.ArchicadLevel level = - jObject.level.ToObject(); + Objects.BuiltElements.Archicad.ArchicadLevel level = null; + if (jObject.level != null) + { + level = jObject.level.ToObject(); + jObject.Remove("level"); + } + + List elementProperties = null; + if (jObject.elementProperties != null) + { + elementProperties = jObject.elementProperties.ToObject>(); + jObject.Remove("elementProperties"); + } + + List componentProperties = null; + if (jObject.componentProperties != null) + { + componentProperties = jObject.componentProperties.ToObject< + List + >(); + jObject.Remove("componentProperties"); + } - jObject.Remove("level"); T speckleObject = jObject.ToObject(); - PropertyInfo prop = speckleObject.GetType().GetProperty("archicadLevel"); - prop.SetValue(speckleObject, level); + if (level != null) + { + PropertyInfo propLevel = speckleObject.GetType().GetProperty("archicadLevel"); + propLevel.SetValue(speckleObject, level); + } + + if (elementProperties != null) + { + PropertyInfo propElementProperties = speckleObject.GetType().GetProperty("elementProperties"); + propElementProperties.SetValue(speckleObject, PropertyGroup.ToBase(elementProperties)); + } + + if (componentProperties != null) + { + PropertyInfo propComponentProperties = speckleObject.GetType().GetProperty("componentProperties"); + propComponentProperties.SetValue(speckleObject, ComponentProperties.ToBase(componentProperties)); + } return speckleObject; } - public static Objects.BuiltElements.Archicad.ArchicadLevel ConvertLevel(Objects.BuiltElements.Level level) + public static T ConvertToArchicadDTOs(dynamic @object) { - return new Objects.BuiltElements.Archicad.ArchicadLevel + if (@object.elementProperties != null) { - id = level.id, - applicationId = level.applicationId, - elevation = level.elevation * Units.GetConversionFactor(level.units, Units.Meters), - name = level.name - }; + @object.elementProperties = null; + } + + if (@object.componentProperties != null) + { + @object.componentProperties = null; + } + + if (@object.GetType().GetProperty("elements") != null) + { + @object.elements = null; + } + + return @object; + } + + public static Objects.BuiltElements.Archicad.ArchicadLevel ConvertLevel(Objects.BuiltElements.Level level) + { + return (level == null) + ? null + : new Objects.BuiltElements.Archicad.ArchicadLevel + { + id = level.id, + applicationId = level.applicationId, + elevation = level.elevation * Units.GetConversionFactor(level.units, Units.Meters), + name = level.name + }; } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs index 4bd34d7aef..cc92a1b85a 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Archicad.Communication; using Archicad.Model; -using Objects.BuiltElements; using Objects.BuiltElements.Archicad; using Objects.BuiltElements.Revit; using Objects.Geometry; @@ -38,24 +37,25 @@ CancellationToken token switch (tc.current) { case Objects.BuiltElements.Archicad.ArchicadWall archiWall: + Archicad.Converters.Utils.ConvertToArchicadDTOs(archiWall); walls.Add(archiWall); break; case Objects.BuiltElements.Wall wall: - var baseLine = (Line)wall.baseLine; - - ArchicadWall newWall = - new() - { - id = wall.id, - applicationId = wall.applicationId, - archicadLevel = Archicad.Converters.Utils.ConvertLevel(wall.level), - startPoint = Utils.ScaleToNative(baseLine.start), - endPoint = Utils.ScaleToNative(baseLine.end), - height = Utils.ScaleToNative(wall.height, wall.units), - flipped = (tc.current is RevitWall revitWall) ? revitWall.flipped : false - }; - - walls.Add(newWall); + if (wall.baseLine is Line baseLine) + { + walls.Add( + new ArchicadWall + { + id = wall.id, + applicationId = wall.applicationId, + archicadLevel = Archicad.Converters.Utils.ConvertLevel(wall.level), + startPoint = Utils.ScaleToNative(baseLine.start), + endPoint = Utils.ScaleToNative(baseLine.end), + height = Utils.ScaleToNative(wall.height, wall.units), + flipped = (tc.current is RevitWall revitWall) ? revitWall.flipped : false + } + ); + } break; } } @@ -66,12 +66,20 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { var elementModels = elements as ElementModelData[] ?? elements.ToArray(); Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetWallData(elementModels.Select(e => e.applicationId)), + new Communication.Commands.GetWallData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), token ); @@ -90,7 +98,7 @@ public async Task> ConvertToSpeckle(IEnumerable(jToken); + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); wall.units = Units.Meters; wall.displayValue = Operations.ModelConverter.MeshesToSpeckle( diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs index 497ac33805..4ae1483147 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs @@ -5,9 +5,6 @@ using System.Threading.Tasks; using Archicad.Communication; using Archicad.Model; -using Objects.BuiltElements.Archicad; -using Objects.BuiltElements.Revit; -using Objects.Geometry; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; @@ -37,6 +34,9 @@ CancellationToken token { case Objects.BuiltElements.Archicad.ArchicadWindow archicadWindow: archicadWindow.parentApplicationId = tc.parent.current.id; + Archicad.Converters.Utils.ConvertToArchicadDTOs( + archicadWindow + ); windows.Add(archicadWindow); break; //case Objects.BuiltElements.Opening window: @@ -56,16 +56,25 @@ CancellationToken token return result is null ? new List() : result.ToList(); } - public async Task> ConvertToSpeckle(IEnumerable elements, CancellationToken token) + public async Task> ConvertToSpeckle( + IEnumerable elements, + CancellationToken token, + ConversionOptions conversionOptions + ) { // Get subelements var elementModels = elements as ElementModelData[] ?? elements.ToArray(); - IEnumerable data = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetWindowData(elementModels.Select(e => e.applicationId)) + Speckle.Newtonsoft.Json.Linq.JArray jArray = await AsyncCommandProcessor.Execute( + new Communication.Commands.GetWindowData( + elementModels.Select(e => e.applicationId), + conversionOptions.SendProperties, + conversionOptions.SendListingParameters + ), + token ); List openings = new(); - if (data is null) + if (jArray is null) { return openings; } @@ -75,12 +84,15 @@ public async Task> ConvertToSpeckle(IEnumerable e.applicationId == subelement.applicationId).model + Objects.BuiltElements.Archicad.ArchicadWindow window = + Archicad.Converters.Utils.ConvertToSpeckleDTOs(jToken); + + window.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == window.applicationId).model ); - openings.Add(subelement); + openings.Add(window); } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManager.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManager.cs index 10b7e51289..330860564c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManager.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManager.cs @@ -5,22 +5,21 @@ using System.Threading; using System.Threading.Tasks; using Archicad.Communication; -using DesktopUI2.Models.Filters; using DesktopUI2.ViewModels; -using Objects.BuiltElements.Archicad; using Speckle.Core.Logging; using Speckle.Core.Models; using Beam = Objects.BuiltElements.Beam; using Ceiling = Objects.BuiltElements.Ceiling; using Column = Objects.BuiltElements.Column; using Door = Objects.BuiltElements.Archicad.ArchicadDoor; +using Fenestration = Objects.BuiltElements.Archicad.ArchicadFenestration; using Floor = Objects.BuiltElements.Floor; using Roof = Objects.BuiltElements.Roof; -using Room = Objects.BuiltElements.Archicad.ArchicadRoom; using Wall = Objects.BuiltElements.Wall; using Window = Objects.BuiltElements.Archicad.ArchicadWindow; using Skylight = Objects.BuiltElements.Archicad.ArchicadSkylight; using GridLine = Objects.BuiltElements.GridLine; +using DesktopUI2.Models; namespace Archicad; @@ -52,20 +51,22 @@ private ElementConverterManager() #region --- Functions --- - public async Task ConvertToSpeckle(ISelectionFilter filter, ProgressViewModel progress) + public async Task ConvertToSpeckle(StreamState state, ProgressViewModel progress) { var objectToCommit = new Collection("Archicad model", "model"); - IEnumerable elementIds = filter.Selection; - if (filter.Slug == "all") + var conversionOptions = new ConversionOptions(state.Settings); + + IEnumerable elementIds = state.Filter.Selection; + if (state.Filter.Slug == "all") { elementIds = AsyncCommandProcessor .Execute(new Communication.Commands.GetElementIds(Communication.Commands.GetElementIds.ElementFilter.All)) ?.Result; } - else if (filter.Slug == "elementType") + else if (state.Filter.Slug == "elementType") { - var elementTypes = filter.Summary.Split(",").Select(elementType => elementType.Trim()).ToList(); + var elementTypes = state.Filter.Summary.Split(",").Select(elementType => elementType.Trim()).ToList(); elementIds = AsyncCommandProcessor .Execute( new Communication.Commands.GetElementIds( @@ -81,32 +82,61 @@ private ElementConverterManager() SpeckleLog.Logger.Debug("Conversion started (element types: {0})", SelectedObjects.Count); + progress.Max = SelectedObjects.Sum(x => x.Value.Count()); + progress.Value = 0; + + List allObjects = new(); foreach (var (element, guids) in SelectedObjects) // For all kind of selected objects (like window, door, wall, etc.) { SpeckleLog.Logger.Debug("{0}: {1}", element, guids.Count()); - var objects = await ConvertOneTypeToSpeckle( - guids, - ElementTypeProvider.GetTypeByName(element), - progress.CancellationToken - ); // Deserialize all objects with hiven type + Type elemenType = ElementTypeProvider.GetTypeByName(element); + var objects = await ConvertOneTypeToSpeckle(guids, elemenType, progress, conversionOptions); // Deserialize all objects with given type + allObjects.AddRange(objects); - if (objects.Count() > 0) + // subelements translated into "elements" property of the parent + if (typeof(Fenestration).IsAssignableFrom(elemenType)) { - var elementCollection = new Collection(element, "Element Type"); - elementCollection.applicationId = element; - elementCollection.elements = objects; - objectToCommit.elements.Add(elementCollection); + Collection elementCollection = null; - // itermediate solution for the OneClick Send report - for (int i = 0; i < objects.Count(); i++) + foreach (Base item in objects) { - if (!progress.Report.ReportObjects.ContainsKey(objects[i].applicationId)) + Base parent = allObjects.Find(x => x.applicationId == ((Fenestration)item).parentApplicationId); + + if (parent == null) + { + // parent skipped, so add to collection + if (elementCollection == null) + { + elementCollection = new Collection(element, "Element Type"); + elementCollection.applicationId = element; + objectToCommit.elements.Add(elementCollection); + } + + elementCollection.elements.Add(item); + } + else { - progress.Report.ReportObjects.Add(objects[i].applicationId, new ApplicationObject("", "")); + if (parent["elements"] == null) + { + parent["elements"] = new List() { item }; + } + else + { + var elements = parent["elements"] as List; + elements.Add(item); + } } } } + // parents translated as new collections + else + { + Collection elementCollection = new(element, "Element Type"); + elementCollection.applicationId = element; + elementCollection.elements = objects; + objectToCommit.elements.Add(elementCollection); + } } SpeckleLog.Logger.Debug("Conversion done"); @@ -244,22 +274,28 @@ CancellationToken token public async Task?> ConvertOneTypeToSpeckle( IEnumerable applicationIds, Type elementType, - CancellationToken token + ProgressViewModel progress, + ConversionOptions conversionOptions ) { - var rawModels = await GetModelForElements(applicationIds, token); // Model data, like meshes + var rawModels = await GetModelForElements(applicationIds, progress.CancellationToken); // Model data, like meshes var elementConverter = ElementConverterManager.Instance.GetConverterForElement(elementType, null, false); // Object converter - var convertedObjects = await elementConverter.ConvertToSpeckle(rawModels, token); // Deserialization + var convertedObjects = await elementConverter.ConvertToSpeckle( + rawModels, + progress.CancellationToken, + conversionOptions + ); // Deserialization - foreach (var convertedObject in convertedObjects) + foreach (Base convertedObject in convertedObjects) { - var subElementsAsBases = await ConvertSubElementsToSpeckle(convertedObject, token); - if (subElementsAsBases.Count() > 0) - { - convertedObject["elements"] = subElementsAsBases; - } + ApplicationObject applicationObject = new(convertedObject.applicationId, elementType.Name); + applicationObject.Update(status: ApplicationObject.State.Created); + + progress.Report.Log(applicationObject); } + progress.Value = progress.Value + convertedObjects.Count(); + return convertedObjects; } @@ -274,96 +310,4 @@ CancellationToken token ); return retval; } - - public async Task?> ConvertSubElementsToSpeckle(Base convertedObject, CancellationToken token) - { - var subElementsAsBases = new List(); - - if ( - convertedObject - is not ( - Objects.BuiltElements.Archicad.ArchicadWall - or Objects.BuiltElements.Archicad.ArchicadRoof - or Objects.BuiltElements.Archicad.ArchicadShell - ) - ) - { - return subElementsAsBases; - } - - var subElements = await GetAllSubElements(convertedObject.applicationId); - if (subElements.Count() == 0) - { - return subElementsAsBases; - } - - var subElementsByGuid = await GetElementsType(subElements.Select(e => e.applicationId), token); - var mutualSubElements = GetAllMutualSubElements(subElementsByGuid); - - foreach (var (element, guids) in mutualSubElements) - { - if (guids.Count() == 0) - { - continue; - } - - var convertedSubElements = await ConvertOneTypeToSpeckle( - guids, - ElementTypeProvider.GetTypeByName(element), - token - ); - subElementsAsBases = subElementsAsBases.Concat(convertedSubElements).ToList(); // Update list with new values - } - RemoveSubElements(mutualSubElements); // Remove subelements from SelectedObjects (where we stored all selected objects) - - return subElementsAsBases; - } - - private async Task?> GetAllSubElements(string apllicationId) - { - IEnumerable? currentSubElements = await AsyncCommandProcessor.Execute( - new Communication.Commands.GetSubElementInfo(apllicationId), - CancellationToken.None - ); - - return currentSubElements; - } - - private Dictionary> GetAllMutualSubElements( - Dictionary> allSubElementsByGuid - ) - { - Dictionary> mutualSubElements = new(); - - foreach (var (element, guids) in allSubElementsByGuid) - { - mutualSubElements[element] = GetMutualSubElementsByType(element, guids); - } - - return mutualSubElements; - } - - private IEnumerable GetMutualSubElementsByType(string elementType, IEnumerable applicationIds) - { - if (!SelectedObjects.ContainsKey(elementType)) - { - return new List(); - } - - return SelectedObjects[elementType].Where(guid => applicationIds.Contains(guid)); - } - - public void RemoveSubElements(Dictionary> mutualSubElements) - { - foreach (var (element, guids) in mutualSubElements) - { - if (guids.Count() == 0) - { - continue; - } - - var guidsToKeep = SelectedObjects[element].Where(guid => !guids.Contains(guid)); - SelectedObjects[element] = guidsToKeep.ToList(); - } - } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManagerReceive.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManagerReceive.cs index 5ab5e5eb7a..5953b29563 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManagerReceive.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ElementConverterManagerReceive.cs @@ -26,14 +26,14 @@ CancellationToken token var elementConverter = GetConverterForElement(elementType, conversionOptions, true); return await elementConverter.ConvertToArchicad(elements, token); } - catch (OperationCanceledException) + catch (Exception ex) when (ex is SpeckleException or ArgumentNullException or ObjectDisposedException) { - throw; + SpeckleLog.Logger.Warning(ex, "Failed to convert element type {elementType}", elementType.ToString()); + return null; } - catch (Exception) + catch (OperationCanceledException) { - SpeckleLog.Logger.Warning("Failed to convert element type {elementType}", elementType.ToString()); - return null; + throw; } } @@ -67,6 +67,9 @@ ProgressViewModel progress var dict = convertedElements .Where(obj => (!string.IsNullOrEmpty(obj.OriginalId))) .ToDictionary(obj => obj.OriginalId, obj => obj); + + progress.Value += convertedElements.Count(); + foreach (var contextObject in converter.ContextObjects) { if (dict.ContainsKey(contextObject.OriginalId)) @@ -91,7 +94,7 @@ public async Task ConvertToNative(StreamState state, Base commitObject, Pr Objects.Converter.Archicad.ConverterArchicad converter = new(conversionOptions); List flattenObjects = FlattenCommitObject(commitObject, converter); - + progress.Max = flattenObjects.Count; converter.SetContextObjects(flattenObjects); foreach (var applicationObject in converter.ContextObjects) diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ElementTypeProvider.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ElementTypeProvider.cs index d83d1e3260..da11c33ced 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ElementTypeProvider.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ElementTypeProvider.cs @@ -5,9 +5,7 @@ using DirectShape = Objects.BuiltElements.Archicad.DirectShape; using Door = Objects.BuiltElements.Archicad.ArchicadDoor; using Floor = Objects.BuiltElements.Archicad.ArchicadFloor; -using GridElement = Archicad.GridElement; using Roof = Objects.BuiltElements.Archicad.ArchicadRoof; -using Room = Archicad.Room; using Shell = Objects.BuiltElements.Archicad.ArchicadShell; using Wall = Objects.BuiltElements.Archicad.ArchicadWall; using Window = Objects.BuiltElements.Archicad.ArchicadWindow; diff --git a/ConnectorArchicad/ConnectorArchicad/Elements/Object.cs b/ConnectorArchicad/ConnectorArchicad/Elements/Object.cs index fcfb383549..e3b6e91435 100644 --- a/ConnectorArchicad/ConnectorArchicad/Elements/Object.cs +++ b/ConnectorArchicad/ConnectorArchicad/Elements/Object.cs @@ -1,14 +1,7 @@ using Objects.Geometry; using Objects.BuiltElements.Archicad; -using Objects.Utils; using Speckle.Core.Kits; -using Speckle.Core.Models; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Speckle.Newtonsoft.Json; -using Archicad.Model; namespace Archicad; diff --git a/ConnectorArchicad/ConnectorArchicad/Elements/Room.cs b/ConnectorArchicad/ConnectorArchicad/Elements/Room.cs index ad906ce600..14a9516a99 100644 --- a/ConnectorArchicad/ConnectorArchicad/Elements/Room.cs +++ b/ConnectorArchicad/ConnectorArchicad/Elements/Room.cs @@ -25,6 +25,8 @@ public class Room // Element base public string? elementType { get; set; } public List? classifications { get; set; } + public List? elementProperties { get; set; } + public List? componentProperties { get; set; } public ArchicadLevel? level { get; set; } public string? layer { get; set; } diff --git a/ConnectorArchicad/ConnectorArchicad/Program.cs b/ConnectorArchicad/ConnectorArchicad/Program.cs index 4f592b5ae7..20b4a9f94c 100644 --- a/ConnectorArchicad/ConnectorArchicad/Program.cs +++ b/ConnectorArchicad/ConnectorArchicad/Program.cs @@ -1,6 +1,3 @@ -using System; -using System.IO; -using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.ReactiveUI; @@ -40,19 +37,7 @@ public static void Main(string[] args) Bindings = new ArchicadBinding(archicadVersion); Setup.Init(Bindings.GetHostAppNameVersion(), Bindings.GetHostAppName()); - CreateOrFocusSpeckle(args); - // BuildAvaloniaApp().StartWithClassicDesktopLifetime(args, Avalonia.Controls.ShutdownMode.OnMainWindowClose); - } - - public static void CreateOrFocusSpeckle(string[] args) - { - if (MainWindow == null) - { - BuildAvaloniaApp().Start(AppMain, args); - } - - MainWindow.Show(); - MainWindow.Activate(); + BuildAvaloniaApp().Start(AppMain, args); } public static AppBuilder BuildAvaloniaApp() => @@ -77,7 +62,7 @@ public static AppBuilder BuildAvaloniaApp() => private static void AppMain(Application app, string[] args) { var viewModel = new MainViewModel(Bindings); - MainWindow = new MainWindow { DataContext = viewModel }; + MainWindow = new MainWindow { DataContext = viewModel, CancelClosing = false }; app.Run(MainWindow); } diff --git a/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Selection.cs b/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Selection.cs index fda8c4e9c5..d927e5f488 100644 --- a/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Selection.cs +++ b/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Selection.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Linq; using Archicad.Communication; namespace Archicad.Launcher; diff --git a/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Settings.cs b/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Settings.cs index d9641a4a1e..7a9132de8d 100644 --- a/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Settings.cs +++ b/ConnectorArchicad/ConnectorArchicad/UI/ConnectorBinding.Settings.cs @@ -1,18 +1,47 @@ using System.Collections.Generic; -using System.Linq; using DesktopUI2.Models.Settings; namespace Archicad.Launcher; public partial class ArchicadBinding { + public enum SettingSlugs + { + SendProperties = 0, + SendListingParameters = 1, + ReceiveParametric = 2 + } + + static public string[] settingSlugs = + { + "filter - properties", + "filter - listing parameters", + "receive - parametric" + }; + public override List GetSettings() { return new List { new CheckBoxSetting { - Slug = "receive - parametric", + Slug = settingSlugs[(int)SettingSlugs.SendProperties], + Name = "Send Properties", + Icon = "Link", + IsChecked = false, + Description = "Send Properties created in the Property Manager" + }, + new CheckBoxSetting + { + Slug = settingSlugs[(int)SettingSlugs.SendListingParameters], + Name = "Send Listing Parameters", + Icon = "Link", + IsChecked = false, + Description = "Send general and tool-specific parameters available for the fields of Element Schedules" + }, + new CheckBoxSetting + { + Slug = settingSlugs[(int)SettingSlugs.ReceiveParametric], Name = "Receive parametric elements", Icon = "Link", IsChecked = false, diff --git a/ConnectorAutocadCivil/ConnectorAdvanceSteel.slnf b/ConnectorAutocadCivil/ConnectorAdvanceSteel.slnf index 365a290f91..85714a7a42 100644 --- a/ConnectorAutocadCivil/ConnectorAdvanceSteel.slnf +++ b/ConnectorAutocadCivil/ConnectorAdvanceSteel.slnf @@ -9,7 +9,7 @@ "ConnectorAutocadCivil\\ConnectorAutocad2024\\ConnectorAutocad2024.csproj", "ConnectorAutocadCivil\\ConnectorAutocadCivil\\ConnectorAutocadCivilShared.shproj", "Core\\Core\\Core.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "DesktopUI2\\AvaloniaHwndHost\\AvaloniaHwndHost.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil.slnf b/ConnectorAutocadCivil/ConnectorAutocadCivil.slnf index 72900fe54e..b6dc9fe55a 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil.slnf +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil.slnf @@ -12,7 +12,7 @@ "ConnectorAutocadCivil\\ConnectorCivil2023\\ConnectorCivil2023.csproj", "ConnectorAutocadCivil\\ConnectorCivil2024\\ConnectorCivil2024.csproj", "Core\\Core\\Core.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "DesktopUI2\\AvaloniaHwndHost\\AvaloniaHwndHost.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", @@ -26,7 +26,7 @@ "Objects\\Converters\\ConverterAutocadCivil\\ConverterCivil2023\\ConverterCivil2023.csproj", "Objects\\Converters\\ConverterAutocadCivil\\ConverterCivil2024\\ConverterCivil2024.csproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/DocumentUtils/TransactionContext.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/DocumentUtils/TransactionContext.cs index 97ac9e654f..ca29013e57 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/DocumentUtils/TransactionContext.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/DocumentUtils/TransactionContext.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; using Autodesk.AutoCAD.ApplicationServices; using Document = Autodesk.AutoCAD.ApplicationServices.Document; diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/App.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/App.cs index 6924657a22..672409c495 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/App.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/App.cs @@ -2,6 +2,7 @@ using Autodesk.Windows; using Speckle.ConnectorAutocadCivil.UI; using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; @@ -28,17 +29,22 @@ public class App : IExtensionApplication public RibbonControl ribbon; #region Initializing and termination + + [SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Is top level plugin catch" + )] public void Initialize() { - try - { - //Advance Steel addon is initialized after ribbon creation - bool advanceSteel = false; + //Advance Steel addon is initialized after ribbon creation + bool advanceSteel = false; #if ADVANCESTEEL - advanceSteel = true; + advanceSteel = true; #endif - - ribbon = ComponentManager.Ribbon; + ribbon = ComponentManager.Ribbon; + try + { if (ribbon != null && !advanceSteel) //the assembly was loaded using netload { Create(); @@ -63,10 +69,15 @@ public void Initialize() bindings.RegisterAppEvents(); SpeckleAutocadCommand.Bindings = bindings; } - catch (System.Exception e) + catch (System.Exception ex) { + SpeckleLog.Logger.Fatal( + ex, + "Add-in initialize context (true = application, false = doc): {isApplicationContext}", + Application.DocumentManager.IsApplicationContext + ); Forms.MessageBox.Show( - $"Add-in initialize context (true = application, false = doc): {Application.DocumentManager.IsApplicationContext.ToString()}. Error encountered: {e.ToString()}" + $"Add-in initialize context (true = application, false = doc): {Application.DocumentManager.IsApplicationContext.ToString()}. Error encountered: {ex}" ); } } @@ -133,14 +144,17 @@ public void Create() RibbonButton oneClickSendButton = CreateButton("Send", "SpeckleSend", panel, null, oneClickTip, "send"); // help and resources buttons - RibbonSplitButton helpButton = new(); - helpButton.Text = "Help & Resources"; - helpButton.Image = LoadPngImgSource("help16.png"); - helpButton.LargeImage = LoadPngImgSource("help32.png"); - helpButton.ShowImage = true; - helpButton.ShowText = true; - helpButton.Size = RibbonItemSize.Large; - helpButton.Orientation = Orientation.Vertical; + RibbonSplitButton helpButton = + new() + { + Text = "Help & Resources", + Image = LoadPngImgSource("help16.png"), + LargeImage = LoadPngImgSource("help32.png"), + ShowImage = true, + ShowText = true, + Size = RibbonItemSize.Large, + Orientation = Orientation.Vertical + }; panel.Items.Add(helpButton); RibbonToolTip communityTip = CreateToolTip( @@ -162,14 +176,12 @@ public void Terminate() { } private RibbonTab FindOrMakeTab(string name) { // check to see if tab exists - RibbonTab tab = ribbon.Tabs.Where(o => o.Title.Equals(name)).FirstOrDefault(); + RibbonTab tab = ribbon.Tabs.FirstOrDefault(o => o.Title.Equals(name)); // if not, create a new one if (tab == null) { - tab = new RibbonTab(); - tab.Title = name; - tab.Id = name; + tab = new RibbonTab { Title = name, Id = name }; ribbon.Tabs.Add(tab); } @@ -189,12 +201,14 @@ private RibbonPanelSource CreateButtonPanel(string name, RibbonTab tab) private RibbonToolTip CreateToolTip(string title, string content) { - RibbonToolTip toolTip = new(); - - //toolTip.Command = ""; - toolTip.Title = title; - toolTip.Content = content; - toolTip.IsHelpEnabled = true; // Without this "Press F1 for help" does not appear in the tooltip + RibbonToolTip toolTip = + new() + { + //toolTip.Command = ""; + Title = title, + Content = content, + IsHelpEnabled = true // Without this "Press F1 for help" does not appear in the tooltip + }; return toolTip; } @@ -208,18 +222,19 @@ private RibbonButton CreateButton( string imageName = "" ) { - var button = new RibbonButton(); - - // ribbon panel source info assignment - button.Text = name; - button.Id = name; - button.ShowImage = true; - button.ShowText = true; - button.ToolTip = tooltip; - button.HelpSource = new System.Uri("https://speckle.guide/user/autocadcivil.html"); - button.Size = RibbonItemSize.Large; - button.Image = LoadPngImgSource(imageName + "16.png"); - button.LargeImage = LoadPngImgSource(imageName + "32.png"); + var button = new RibbonButton + { + // ribbon panel source info assignment + Text = name, + Id = name, + ShowImage = true, + ShowText = true, + ToolTip = tooltip, + HelpSource = new System.Uri("https://speckle.guide/user/autocadcivil.html"), + Size = RibbonItemSize.Large, + Image = LoadPngImgSource(imageName + "16.png"), + LargeImage = LoadPngImgSource(imageName + "32.png") + }; // add ribbon button pannel to the ribbon panel source if (sourcePanel != null) @@ -239,21 +254,55 @@ private RibbonButton CreateButton( return button; } + /// + /// Retrieve the png image source + /// + /// + /// private ImageSource LoadPngImgSource(string sourceName) { - try + if (!string.IsNullOrEmpty(sourceName) && sourceName.ToLower().EndsWith(".png")) { - string resource = this.GetType() - .Assembly.GetManifestResourceNames() + Assembly assembly = Assembly.GetExecutingAssembly(); + string resource = GetType().Assembly + .GetManifestResourceNames() .Where(o => o.EndsWith(sourceName)) .FirstOrDefault(); - Assembly assembly = Assembly.GetExecutingAssembly(); - Stream stream = assembly.GetManifestResourceStream(resource); - PngBitmapDecoder decoder = new(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); - ImageSource source = decoder.Frames[0]; - return source; + + if (string.IsNullOrEmpty(resource)) + { + return null; + } + + Stream stream = null; + try + { + stream = assembly.GetManifestResourceStream(resource); + } + catch (FileLoadException flEx) + { + SpeckleLog.Logger.Error(flEx, "Could not load app image source: {exceptionMessage}"); + } + catch (FileNotFoundException fnfEx) + { + SpeckleLog.Logger.Error(fnfEx, "Could not find app image source: {exceptionMessage}"); + } + catch (NotImplementedException niEx) + { + SpeckleLog.Logger.Error(niEx, "App image source could not be loaded: {exceptionMessage}"); + } + + if (stream is not null) + { + PngBitmapDecoder decoder = new(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); + if (decoder.Frames.Count > 0) + { + ImageSource source = decoder.Frames[0]; + return source; + } + } } - catch { } + return null; } @@ -272,8 +321,7 @@ public ButtonCommandHandler(string commandParameter) public void Execute(object parameter) { - RibbonButton btn = parameter as RibbonButton; - if (btn != null) + if (parameter is RibbonButton) { switch (commandParameter) { @@ -289,6 +337,8 @@ public void Execute(object parameter) case "SpeckleDocs": SpeckleAutocadCommand.SpeckleDocs(); break; + default: + break; } } } diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/SpeckleAutocadCommand.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/SpeckleAutocadCommand.cs index 0ca03ba939..0472abc882 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/SpeckleAutocadCommand.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/Entry/SpeckleAutocadCommand.cs @@ -4,8 +4,6 @@ using System.Runtime.InteropServices; using System.Threading; -using Autodesk.AutoCAD.ApplicationServices; - #if ADVANCESTEEL using Autodesk.AdvanceSteel.Runtime; #else @@ -18,10 +16,11 @@ using Avalonia.Controls; using Avalonia.ReactiveUI; -using DesktopUI2; using DesktopUI2.ViewModels; using DesktopUI2.Views; using Speckle.ConnectorAutocadCivil.UI; +using Speckle.Core.Logging; +using Exception = System.Exception; #if ADVANCESTEEL [assembly: CommandClass(typeof(Speckle.ConnectorAutocadCivil.Entry.SpeckleAutocadCommand))] @@ -66,11 +65,16 @@ public static void InitAvalonia() BuildAvaloniaApp().Start(AppMain, null); } + [SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Is top level plugin catch" + )] public static void CreateOrFocusSpeckle(bool showWindow = true) { if (MainWindow == null) { - var viewModel = new MainViewModel(Bindings); + MainViewModel viewModel = new(Bindings); MainWindow = new MainWindow { DataContext = viewModel }; } @@ -97,7 +101,10 @@ public static void CreateOrFocusSpeckle(bool showWindow = true) } } } - catch { } + catch (Exception ex) + { + SpeckleLog.Logger.Fatal(ex, "Failed to create or focus Speckle window"); + } } private static void AppMain(Avalonia.Application app, string[] args) @@ -117,7 +124,10 @@ public static void SpeckleCommunity() true ); } - catch { } + catch (System.Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Could not execute opening browser link for Speckle Community: {exceptionMessage}"); + } } [CommandMethod("SpeckleTutorials", CommandFlags.ActionMacro)] @@ -132,7 +142,10 @@ public static void SpeckleTutorials() true ); } - catch { } + catch (System.Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Could not execute opening browser link for Speckle Tutorials: {exceptionMessage}"); + } } [CommandMethod("SpeckleDocs", CommandFlags.ActionMacro)] @@ -147,38 +160,9 @@ public static void SpeckleDocs() true ); } - catch { } - } -} - -/* -[CommandMethod("SpeckleSchema", CommandFlags.UsePickSet | CommandFlags.Transparent)] -public static void SetSchema() -{ - var ids = new List(); - PromptSelectionResult selection = Doc.Editor.GetSelection(); - if (selection.Status == PromptStatus.OK) - ids = selection.Value.GetObjectIds().ToList(); - foreach (var id in ids) - { - // decide schema here, assumption or user input. - string schema = ""; - switch (id.ObjectClass.DxfName) - { - case "LINE": - schema = "Column"; - break; - } - - // add schema to object XData - using (Transaction tr = Doc.TransactionManager.StartTransaction()) + catch (System.Exception ex) when (!ex.IsFatal()) { - DBObject obj = tr.GetObject(id, OpenMode.ForWrite); - if (obj.XData == null) - obj.XData = new ResultBuffer(new TypedValue(Convert.ToInt32(DxfCode.Text), schema)); - else - obj.XData.Add(new TypedValue(Convert.ToInt32(DxfCode.Text), schema)); + SpeckleLog.Logger.Error(ex, "Could not execute opening browser link for Speckle Docs: {exceptionMessage}"); } } } -*/ diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/Storage/SpeckleStreamManager.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/Storage/SpeckleStreamManager.cs index c46e1bc48e..925c384367 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/Storage/SpeckleStreamManager.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/Storage/SpeckleStreamManager.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using DesktopUI2.Models; using Speckle.ConnectorAutocadCivil.DocumentUtils; +using Speckle.Core.Logging; using Speckle.Newtonsoft.Json; namespace Speckle.ConnectorAutocadCivil.Storage; @@ -23,8 +23,8 @@ namespace Speckle.ConnectorAutocadCivil.Storage; /// public static class SpeckleStreamManager { - readonly static string SpeckleExtensionDictionary = "Speckle"; - readonly static string SpeckleStreamStates = "StreamStates"; + static readonly string SpeckleExtensionDictionary = "Speckle"; + static readonly string SpeckleStreamStates = "StreamStates"; /// /// Returns all the speckle stream states present in the current document. @@ -43,13 +43,14 @@ public static List ReadState(Document doc) using (TransactionContext.StartTransaction(doc)) { Transaction tr = doc.Database.TransactionManager.TopTransaction; - var NOD = (DBDictionary)tr.GetObject(doc.Database.NamedObjectsDictionaryId, OpenMode.ForRead); - if (!NOD.Contains(SpeckleExtensionDictionary)) + var namedObjectsDict = (DBDictionary)tr.GetObject(doc.Database.NamedObjectsDictionaryId, OpenMode.ForRead); + if (!namedObjectsDict.Contains(SpeckleExtensionDictionary)) { return streams; } - var speckleDict = tr.GetObject(NOD.GetAt(SpeckleExtensionDictionary), OpenMode.ForRead) as DBDictionary; + var speckleDict = + tr.GetObject(namedObjectsDict.GetAt(SpeckleExtensionDictionary), OpenMode.ForRead) as DBDictionary; if (speckleDict == null || speckleDict.Count == 0) { return streams; @@ -61,19 +62,24 @@ public static List ReadState(Document doc) return streams; } - var record = tr.GetObject(id, OpenMode.ForRead) as Xrecord; - var value = GetXrecordData(record); - - try + if (tr.GetObject(id, OpenMode.ForRead) is Xrecord record) { - //Try to decode here because there is old data - value = Base64Decode(value); + string value = GetXrecordData(record); + if (!string.IsNullOrEmpty(value)) + { + //Try to decode here because there is old data + if (TryBase64Decode(value, out value)) + { + streams = JsonConvert.DeserializeObject>(value); + } + else + { + SpeckleLog.Logger.Error("Could not decode Base64 encoded StreamState Xrecord string"); + } + } } - catch (Exception e) { } - - streams = JsonConvert.DeserializeObject>(value); - return streams; + return streams ?? new(); } } @@ -81,7 +87,7 @@ public static List ReadState(Document doc) /// Writes the stream states to the current document. /// /// - /// + /// public static void WriteStreamStateList(Document doc, List streamStates) { if (doc == null) @@ -105,8 +111,8 @@ public static void WriteStreamStateList(Document doc, List streamSt NOD.SetAt(SpeckleExtensionDictionary, speckleDict); tr.AddNewlyCreatedDBObject(speckleDict, true); } - var xRec = new Xrecord(); - var value = JsonConvert.SerializeObject(streamStates) as string; + Xrecord xRec = new(); + string value = JsonConvert.SerializeObject(streamStates); xRec.Data = CreateResultBuffer(value); speckleDict.SetAt(SpeckleStreamStates, xRec); tr.AddNewlyCreatedDBObject(xRec, true); @@ -145,14 +151,49 @@ private static string GetXrecordData(Xrecord pXrecord) private static string Base64Encode(string plainText) { - var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); - return System.Convert.ToBase64String(plainTextBytes); + var plainTextBytes = Encoding.UTF8.GetBytes(plainText); + return Convert.ToBase64String(plainTextBytes); } - private static string Base64Decode(string base64EncodedData) + /// + /// Decodes base64 encoded string. + /// + /// + /// The decoded string + /// True on success, false on failure + private static bool TryBase64Decode(string base64EncodedData, out string decodedString) { - var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); - return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); + decodedString = null; + if (string.IsNullOrWhiteSpace(base64EncodedData)) + { + return false; + } + + byte[] base64EncodedBytes; + try + { + base64EncodedBytes = Convert.FromBase64String(base64EncodedData); + } + catch (FormatException fEx) + { + SpeckleLog.Logger.Error(fEx, "Could not decode saved stream with invalid format: {exceptionMessage}"); + return false; + } + + if (base64EncodedBytes == null) + { + return false; + } + + try + { + decodedString = Encoding.UTF8.GetString(base64EncodedBytes); + return true; + } + catch (DecoderFallbackException) + { + return false; + } } private static IEnumerable SplitString(string text, int chunkSize) diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Events.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Events.cs index c8dcc79864..8dd352013e 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Events.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Events.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using DesktopUI2; +using DesktopUI2.Models; using DesktopUI2.ViewModels; using Speckle.ConnectorAutocadCivil.Entry; +using Speckle.Core.Logging; #if ADVANCESTEEL using ASFilerObject = Autodesk.AdvanceSteel.CADAccess.FilerObject; @@ -24,59 +27,54 @@ public void RegisterAppEvents() public void Application_LayerChanged(object sender, EventArgs e) { - if (UpdateSelectedStream != null) - { - UpdateSelectedStream(); - } + UpdateSelectedStream?.Invoke(); } //checks whether to refresh the stream list in case the user changes active view and selects a different document private void Application_WindowActivated(object sender, DocumentWindowActivatedEventArgs e) { - try + if (e.DocumentWindow?.Document == null || UpdateSavedStreams == null) { - if (e.DocumentWindow.Document == null || UpdateSavedStreams == null) - { - return; - } + return; + } - var streams = GetStreamsInFile(); + try + { + List streams = GetStreamsInFile(); UpdateSavedStreams(streams); - - MainViewModel.GoHome(); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Failed to get and update current streams in file: {exceptionMessage}", ex.Message); + } + + MainViewModel.GoHome(); } private void Application_DocumentActivated(object sender, DocumentCollectionEventArgs e) { - try + // Triggered when a document window is activated. This will happen automatically if a document is newly created or opened. + if (e.Document == null) { - // Triggered when a document window is activated. This will happen automatically if a document is newly created or opened. - if (e.Document == null) - { - if (SpeckleAutocadCommand.MainWindow != null) - { - SpeckleAutocadCommand.MainWindow.Hide(); - } + SpeckleAutocadCommand.MainWindow?.Hide(); - MainViewModel.GoHome(); - return; - } + MainViewModel.GoHome(); + return; + } - var streams = GetStreamsInFile(); + try + { + List streams = GetStreamsInFile(); if (streams.Count > 0) { SpeckleAutocadCommand.CreateOrFocusSpeckle(); } - - if (UpdateSavedStreams != null) - { - UpdateSavedStreams(streams); - } - + UpdateSavedStreams?.Invoke(streams); MainViewModel.GoHome(); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Failed to get and update current streams in file: {exceptionMessage}", ex.Message); + } } } diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Receive.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Receive.cs index 78ff8af3fb..eb2d0ddda7 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Receive.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Receive.cs @@ -6,13 +6,13 @@ using System.Text; using System.Threading.Tasks; using Autodesk.AutoCAD.ApplicationServices; -using Autodesk.AutoCAD.Colors; using Autodesk.AutoCAD.DatabaseServices; using DesktopUI2; using DesktopUI2.Models; using DesktopUI2.ViewModels; using Speckle.Core.Api; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; using static Speckle.ConnectorAutocadCivil.Utils; @@ -32,7 +32,7 @@ public override async Task ReceiveStream(StreamState state, Progres throw new InvalidOperationException("No Document is open"); } - var converter = KitManager.GetDefaultKit().LoadConverter(Utils.VersionedAppName); + var converter = KitManager.GetDefaultKit().LoadConverter(VersionedAppName); var stream = await state.Client.StreamGet(state.StreamId); @@ -40,7 +40,7 @@ public override async Task ReceiveStream(StreamState state, Progres state.LastCommit = commit; Base commitObject = await ConnectorHelpers.ReceiveCommit(commit, state, progress); - await ConnectorHelpers.TryCommitReceived(state, commit, Utils.VersionedAppName, progress.CancellationToken); + await ConnectorHelpers.TryCommitReceived(state, commit, VersionedAppName, progress.CancellationToken); // invoke conversions on the main thread via control try @@ -125,15 +125,12 @@ string id } // delete existing commit layers - try - { - DeleteBlocksWithPrefix(commitPrefix, tr); - } - catch + bool success = DeleteBlocksWithPrefix(commitPrefix, tr, out List failedBlocks); + if (!success) { converter.Report.LogOperationError( new Exception( - $"Failed to remove existing layers or blocks starting with {commitPrefix} before importing new geometry." + $"Failed to remove {failedBlocks.Count} existing layers or blocks starting with {commitPrefix} before importing new geometry." ) ); } @@ -172,16 +169,18 @@ string id string layer = null; // try to see if there's a collection object first - var collection = commitObjs - .Where(o => o.Container == container && o.Descriptor.Contains("Collection")) - .FirstOrDefault(); + var collection = commitObjs.FirstOrDefault( + o => o.Container == container && o.Descriptor.Contains("Collection") + ); if (collection != null) { var storedCollection = StoredObjects[collection.OriginalId]; storedCollection["path"] = path; // needed by converter converter.Report.Log(collection); // Log object so converter can access - var convertedCollection = converter.ConvertToNative(storedCollection) as List; - if (convertedCollection != null && convertedCollection.Count > 0) + if ( + converter.ConvertToNative(storedCollection) is List convertedCollection + && convertedCollection.Count > 0 + ) { layer = (convertedCollection.First() as LayerTableRecord)?.Name; commitObjs[commitObjs.IndexOf(collection)] = converter.Report.ReportObjects[collection.OriginalId]; @@ -190,7 +189,7 @@ string id // otherwise create the layer here (old commits before collections implementations, or from apps not supporting collections) else { - if (GetOrMakeLayer(path, tr, out string cleanName)) + if (Doc.GetOrMakeLayer(path, tr, out string cleanName)) { layer = cleanName; } @@ -210,7 +209,7 @@ string id // conversion - foreach (var commitObj in commitObjs) + foreach (ApplicationObject commitObj in commitObjs) { // handle user cancellation if (progress.CancellationToken.IsCancellationRequested) @@ -221,39 +220,42 @@ string id // convert base (or base fallback values) and store in appobj converted prop if (commitObj.Convertible) { - converter.Report.Log(commitObj); // Log object so converter can access - try + if (StoredObjects.TryGetValue(commitObj.OriginalId, out Base obj)) { - commitObj.Converted = ConvertObject(commitObj, converter); + converter.Report.Log(commitObj); // Log object so converter can access + commitObj.Converted = ConvertObject(obj, converter); } - catch (Exception e) + else { - commitObj.Log.Add($"Failed conversion: {e.Message}"); + commitObj.Update(status: ApplicationObject.State.Failed, logItem: "Object not found in StoredObjects"); } } else { - foreach (var fallback in commitObj.Fallback) + foreach (ApplicationObject fallback in commitObj.Fallback) { - try + if (StoredObjects.TryGetValue(fallback.OriginalId, out Base obj)) { - fallback.Converted = ConvertObject(fallback, converter); + converter.Report.Log(fallback); // Log object so converter can access + fallback.Converted = ConvertObject(obj, converter); + commitObj.Log.AddRange(fallback.Log); } - catch (Exception e) + else { - commitObj.Log.Add($"Fallback {fallback.applicationId} failed conversion: {e.Message}"); + commitObj.Log.Add( + $"Fallback object {fallback.OriginalId} not found in StoredObjects and was not converted." + ); } - commitObj.Log.AddRange(fallback.Log); } } // if the object wasnt converted, log fallback status - if (commitObj.Converted == null || commitObj.Converted.Count == 0) + if (commitObj.Converted.Count == 0) { - var convertedFallback = commitObj.Fallback.Where(o => o.Converted != null || o.Converted.Count > 0); - if (convertedFallback != null && convertedFallback.Count() > 0) + var convertedFallbackCount = commitObj.Fallback.Where(o => o.Converted.Count != 0).Count(); + if (convertedFallbackCount > 0) { - commitObj.Update(logItem: $"Creating with {convertedFallback.Count()} fallback values"); + commitObj.Update(logItem: $"Creating with {convertedFallbackCount} fallback values"); } else { @@ -448,9 +450,14 @@ StringBuilder LayerIdRecurse(TraversalContext context, StringBuilder stringBuild return objectsToConvert; } - private List ConvertObject(ApplicationObject appObj, ISpeckleConverter converter) + /// + /// Converts a Base into its Speckle equivalents + /// + /// + /// + /// A list of converted objects, or an empty list if no objects were converted. + private List ConvertObject(Base obj, ISpeckleConverter converter) { - var obj = StoredObjects[appObj.OriginalId]; var convertedList = new List(); var converted = converter.ConvertToNative(obj); @@ -491,57 +498,50 @@ private void BakeObject( var obj = StoredObjects[appObj.OriginalId]; int bakedCount = 0; bool remove = - appObj.Status == ApplicationObject.State.Created - || appObj.Status == ApplicationObject.State.Updated - || appObj.Status == ApplicationObject.State.Failed - ? false - : true; + appObj.Status + is not ApplicationObject.State.Created + and not ApplicationObject.State.Updated + and not ApplicationObject.State.Failed; foreach (var convertedItem in appObj.Converted) { switch (convertedItem) { case Entity o: - - if (o == null) - { - continue; - } - var res = o.Append(layer); if (res.IsValid) { // handle display - fallback to rendermaterial if no displaystyle exists - Base display = obj[@"displayStyle"] as Base; - if (display == null) + if (obj[@"displayStyle"] is not Base display) { display = obj[@"renderMaterial"] as Base; } if (display != null) { - Utils.SetStyle(display, o, LineTypeDictionary); + SetStyle(display, o, LineTypeDictionary); } // add property sets if this is Civil3D #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 + if (obj["propertySets"] is IReadOnlyList list) + { + List> propertySets = new(); + foreach (var listObj in list) + { + propertySets.Add(listObj as Dictionary); + } + try { - if (obj["propertySets"] is IReadOnlyList list) - { - var propertySets = new List>(); - foreach (var listObj in list) - { - propertySets.Add(listObj as Dictionary); - } - - o.SetPropertySets(Doc, propertySets); - } + o.SetPropertySets(Doc, propertySets); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Error(e, "Could not set property sets: {exceptionMessage}"); appObj.Log.Add($"Could not attach property sets: {e.Message}"); } + } #endif // set application id @@ -603,73 +603,48 @@ private void BakeObject( { foreach (var objId in toRemove) { - try + DBObject objToRemove = tr.GetObject(objId, OpenMode.ForWrite); + + if (!objToRemove.IsErased) { - DBObject objToRemove = tr.GetObject(objId, OpenMode.ForWrite); objToRemove.Erase(); } - catch (Exception e) - { - if (!e.Message.Contains("eWasErased")) // this couldve been previously received and deleted - { - if (parent != null) - { - parent.Log.Add(e.Message); - } - else - { - appObj.Log.Add(e.Message); - } - } - } } appObj.Status = toRemove.Count > 0 ? ApplicationObject.State.Updated : ApplicationObject.State.Created; } } } - private void DeleteBlocksWithPrefix(string prefix, Transaction tr) - { - BlockTable blockTable = tr.GetObject(Doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable; - foreach (ObjectId blockId in blockTable) - { - BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead); - if (block.Name.StartsWith(prefix)) - { - block.UpgradeOpen(); - block.Erase(); - } - } - } - - private bool GetOrMakeLayer(string layerName, Transaction tr, out string cleanName) + private bool DeleteBlocksWithPrefix(string prefix, Transaction tr, out List failedBlocks) { - cleanName = Utils.RemoveInvalidChars(layerName); - try + failedBlocks = new List(); + bool success = true; + if (tr.GetObject(Doc.Database.BlockTableId, OpenMode.ForRead) is BlockTable blockTable) { - LayerTable layerTable = tr.GetObject(Doc.Database.LayerTableId, OpenMode.ForRead) as LayerTable; - if (layerTable.Has(cleanName)) - { - return true; - } - else + foreach (ObjectId blockId in blockTable) { - layerTable.UpgradeOpen(); - var _layer = new LayerTableRecord(); - - // Assign the layer properties - _layer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByColor, 7); // white - _layer.Name = cleanName; - - // Append the new layer to the layer table and the transaction - layerTable.Add(_layer); - tr.AddNewlyCreatedDBObject(_layer, true); + if (tr.GetObject(blockId, OpenMode.ForRead) is BlockTableRecord block) + { + if (block.Name.StartsWith(prefix) && !block.IsErased) + { + try + { + block.UpgradeOpen(); + block.Erase(); + } + catch (Exception e) when (!e.IsFatal()) + { + SpeckleLog.Logger.Error( + e, + $"Could not delete existing block of name {block.Name} before creating new blocks with prefix {prefix}" + ); + failedBlocks.Add(block.Name); + success = false; + } + } + } } } - catch - { - return false; - } - return true; + return success; } } diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Selection.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Selection.cs index b06e876eaa..cb75cc08bb 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Selection.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Selection.cs @@ -71,13 +71,14 @@ public override List GetSelectionFilters() }; } - public override void SelectClientObjects(List args, bool deselect = false) + public override void SelectClientObjects(List objs, bool deselect = false) { - var editor = Application.DocumentManager.MdiActiveDocument.Editor; - var currentSelection = editor.SelectImplied().Value?.GetObjectIds()?.ToList() ?? new List(); - foreach (var arg in args) + if (objs is not null && objs.Count > 0) { - try + Editor editor = Application.DocumentManager.MdiActiveDocument.Editor; + + var currentSelection = editor.SelectImplied()?.Value?.GetObjectIds()?.ToList() ?? new List(); + foreach (var arg in objs) { if (Utils.GetHandle(arg, out Handle handle)) { @@ -85,10 +86,7 @@ public override void SelectClientObjects(List args, bool deselect = fals { if (deselect) { - if (currentSelection.Contains(id)) - { - currentSelection.Remove(id); - } + currentSelection.Remove(id); } else { @@ -100,18 +98,18 @@ public override void SelectClientObjects(List args, bool deselect = fals } } } - catch { } - } - if (currentSelection.Count == 0) - { - editor.SetImpliedSelection(new ObjectId[0]); - } - else - { - Autodesk.AutoCAD.Internal.Utils.SelectObjects(currentSelection.ToArray()); - } - Autodesk.AutoCAD.Internal.Utils.FlushGraphics(); + if (currentSelection.Count == 0) + { + editor.SetImpliedSelection(System.Array.Empty()); + } + else + { + Autodesk.AutoCAD.Internal.Utils.SelectObjects(currentSelection.ToArray()); + } + + Autodesk.AutoCAD.Internal.Utils.FlushGraphics(); + } } private List GetObjectsFromFilter(ISelectionFilter filter, ISpeckleConverter converter) diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Send.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Send.cs index 287a8f193c..231f8542bf 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Send.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.Send.cs @@ -40,7 +40,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod var deletedElements = new List(); foreach (var selectedId in state.SelectedObjectIds) { - if (Utils.GetHandle(selectedId, out Handle handle)) + if (GetHandle(selectedId, out Handle handle)) { if (Doc.Database.TryGetObjectId(handle, out ObjectId id)) { @@ -61,9 +61,9 @@ public override async Task SendStream(StreamState state, ProgressViewMod ); } - var modelName = $"{Utils.AppName} Model"; + var modelName = $"{AppName} Model"; var commitObject = new Collection(modelName, modelName.ToLower()); - commitObject["units"] = Utils.GetUnits(Doc); // TODO: check whether commits base needs units attached + commitObject["units"] = GetUnits(Doc); // TODO: check whether commits base needs units attached int convertedCount = 0; @@ -84,9 +84,9 @@ public override async Task SendStream(StreamState state, ProgressViewMod progress.Report.Merge(converter.Report); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - progress.Report.LogOperationError(e); + progress.Report.LogOperationError(ex); } if (convertedCount == 0) @@ -102,7 +102,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod commitObject, progress.CancellationToken, transports, - onProgressAction: dict => progress.Update(dict), + onProgressAction: progress.Update, onErrorAction: ConnectorHelpers.DefaultSendErrorHandler, disposeTransports: true ); @@ -114,8 +114,8 @@ public override async Task SendStream(StreamState state, ProgressViewMod streamId = streamId, objectId = commitObjId, branchName = state.BranchName, - message = state.CommitMessage ?? $"Pushed {convertedCount} elements from {Utils.AppName}.", - sourceApplication = Utils.VersionedAppName + message = state.CommitMessage ?? $"Pushed {convertedCount} elements from {AppName}.", + sourceApplication = VersionedAppName }; if (state.PreviousCommitId != null) @@ -191,7 +191,7 @@ ref int convertedCount DBObject obj = null; string layer = null; string applicationId = null; - if (Utils.GetHandle(autocadObjectHandle, out Handle hn)) + if (GetHandle(autocadObjectHandle, out Handle hn)) { obj = hn.GetObject(tr, out string type, out layer, out applicationId); } @@ -203,7 +203,7 @@ ref int convertedCount // create applicationobject for reporting Base converted = null; - var descriptor = Utils.ObjectDescriptor(obj); + var descriptor = ObjectDescriptor(obj); ApplicationObject reportObj = new(autocadObjectHandle, descriptor) { applicationId = autocadObjectHandle }; if (!converter.CanConvertToSpeckle(obj)) @@ -264,7 +264,7 @@ bool isOldApplicationId(string appId) return false; } - return appId.Length == 5 ? true : false; + return appId.Length == 5; } if (isOldApplicationId(applicationId)) { @@ -303,9 +303,9 @@ bool isOldApplicationId(string appId) convertedCount++; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { - //TODO: Log to serilog failed conversions + SpeckleLog.Logger.Error(e, $"Failed object conversion"); reportObj.Update(status: ApplicationObject.State.Failed, logItem: $"{e.Message}"); progress.Report.Log(reportObj); continue; @@ -326,8 +326,7 @@ bool isOldApplicationId(string appId) else { var layerRecord = (LayerTableRecord)tr.GetObject(layerTable[layerPath], OpenMode.ForRead); - var collection = converter.ConvertToSpeckle(layerRecord) as Collection; - if (collection != null) + if (converter.ConvertToSpeckle(layerRecord) is Collection collection) { collection.elements = commitLayerObjects[layerPath]; commitCollections.Add(layerPath, collection); diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.cs index eb537087b0..28cfb74fbe 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/UI/ConnectorBindingsAutocadCivil.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using Autodesk.AutoCAD.ApplicationServices; @@ -8,6 +9,7 @@ using Speckle.ConnectorAutocadCivil.Storage; using Speckle.Core.Kits; using Speckle.Core.Models; +using Speckle.Core.Logging; #if ADVANCESTEEL using ASFilerObject = Autodesk.AdvanceSteel.CADAccess.FilerObject; @@ -86,17 +88,38 @@ public override string GetHostAppNameVersion() => private string GetDocPath(Document doc) => HostApplicationServices.Current.FindFile(doc?.Name, doc?.Database, FindFileHint.Default); + /// + /// Retrieves the hashed id of Doc from its path and name (saved) or name and timestamp (if not saved). + /// + /// The hashed Doc id, or null on failure. + /// Used as a prefix to an object's id to create a more unique applicationId. public override string GetDocumentId() { - string path = null; + if (Doc is null) + { + return null; + } + + string name = Doc.Name; + string docString; + try { - path = GetDocPath(Doc); + // get the path (unsaved files will not have a path) + string path = GetDocPath(Doc); + docString = path + name; + } + catch (Exception e) when (!e.IsFatal()) // is there a way to check if the doc is saved before attempting to retrieve the doc path? + { + // get the timestamp if path is null + // this is because new unsaved docs have a high chance of having the same name + // resulting in non-unique application ids + string time = DateTime.Now.ToString(); + docString = name + time; } - catch { } - var docString = $"{(path != null ? path : "")}{(Doc != null ? Doc.Name : "")}"; + var hash = !string.IsNullOrEmpty(docString) - ? Core.Models.Utilities.HashString(docString, Core.Models.Utilities.HashingFunctions.MD5) + ? Utilities.HashString(docString, Utilities.HashingFunctions.MD5) : null; return hash; } @@ -162,7 +185,7 @@ public override List GetCustomStreamMenuItems() public override void ResetDocument() { - Doc.Editor.SetImpliedSelection(new ObjectId[0]); + Doc.Editor.SetImpliedSelection(System.Array.Empty()); Autodesk.AutoCAD.Internal.Utils.FlushGraphics(); } } diff --git a/ConnectorAutocadCivil/ConnectorAutocadCivil/Utils.cs b/ConnectorAutocadCivil/ConnectorAutocadCivil/Utils.cs index afe5e3832a..a4965491a4 100644 --- a/ConnectorAutocadCivil/ConnectorAutocadCivil/Utils.cs +++ b/ConnectorAutocadCivil/ConnectorAutocadCivil/Utils.cs @@ -12,6 +12,7 @@ using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.ConnectorAutocadCivil.DocumentUtils; +using Speckle.Core.Logging; #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 using Autodesk.Aec.ApplicationServices; @@ -142,7 +143,7 @@ public static List GetHandles(this SelectionSet selection) /// public static ObjectId Append(this Entity entity, string layer = null) { - var db = (entity.Database == null) ? Application.DocumentManager.MdiActiveDocument.Database : entity.Database; + var db = entity.Database ?? Application.DocumentManager.MdiActiveDocument.Database; Transaction tr = db.TransactionManager.TopTransaction; if (tr == null) { @@ -226,7 +227,7 @@ out string applicationId /// Get visibility of a DBObject /// /// - /// + /// True if the object is visible, or false if not. Returns true on failure to retrieve object visibility property. public static bool Visible(this DBObject obj) { bool isVisible = true; @@ -254,34 +255,76 @@ public static bool Visible(this DBObject obj) } else { - PropertyInfo prop = obj.GetType().GetProperty("Visible"); try { - isVisible = (bool)prop.GetValue(obj); + PropertyInfo prop = obj.GetType().GetProperty("Visible"); + if (prop.GetValue(obj) is bool visible) + { + isVisible = visible; + } } - catch { } + catch (AmbiguousMatchException) { } // will return true on failure to retrieve object visibility property. } return isVisible; } + public static bool GetOrMakeLayer(this Document doc, string layerName, Transaction tr, out string cleanName) + { + cleanName = RemoveInvalidChars(layerName); + if (tr.GetObject(doc.Database.LayerTableId, OpenMode.ForRead) is LayerTable layerTable) + { + if (layerTable.Has(cleanName)) + { + return true; + } + else + { + layerTable.UpgradeOpen(); + LayerTableRecord newLayer = + new() + { + Color = Color.FromColorIndex(ColorMethod.ByColor, 7), // white + Name = cleanName + }; + + // Append the new layer to the layer table and the transaction + try + { + layerTable.Add(newLayer); + } + catch (Exception e) when (!e.IsFatal()) + { + // Objects on this layer will be placed on the default layer instead + SpeckleLog.Logger.Error(e, $"Could not add new layer {cleanName} to the layer table"); + return false; + } + tr.AddNewlyCreatedDBObject(newLayer, true); + } + } + return true; + } + + #endregion + + #region property sets #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 private static Autodesk.Aec.PropertyData.DataType? GetPropertySetType(object prop) { switch (prop) { - case IEnumerable _: - case IEnumerable _: - case IEnumerable _: - case IEnumerable _: + case IEnumerable: + case IEnumerable: + case IEnumerable: + case IEnumerable: return Autodesk.Aec.PropertyData.DataType.List; - case string _: + case string: return Autodesk.Aec.PropertyData.DataType.Text; - case int _: + case int: return Autodesk.Aec.PropertyData.DataType.Integer; - case double _: + case double: return Autodesk.Aec.PropertyData.DataType.Real; - case bool _: + case bool: return Autodesk.Aec.PropertyData.DataType.TrueFalse; default: @@ -289,60 +332,123 @@ public static bool Visible(this DBObject obj) } } - public static void SetPropertySets(this Entity entity, Document doc, List> propertySetDicts) + public static PropertySetDefinition CreatePropertySet(Dictionary propertySetDict, Document doc) { - // create a dictionary for property sets for this object - var name = $"Speckle {entity.Handle} Property Set"; - int count = 0; - foreach (var propertySetDict in propertySetDicts) - { - // create the property set definition for this set. - var propSetDef = new PropertySetDefinition(); - propSetDef.SetToStandard(doc.Database); - propSetDef.SubSetDatabaseDefaults(doc.Database); - var propSetDefName = name += $" - {count}"; - propSetDef.Description = "Property Set Definition added with Speckle"; - propSetDef.AppliesToAll = true; - - // Create the definition for each property - foreach (var entry in propertySetDict) + PropertySetDefinition propSetDef = new(); + propSetDef.SetToStandard(doc.Database); + propSetDef.SubSetDatabaseDefaults(doc.Database); + propSetDef.Description = "Property Set Definition added with Speckle"; + propSetDef.AppliesToAll = true; + + // Create the definition for each property + foreach (var entry in propertySetDict) + { + if (GetPropertySetType(entry.Value) is Autodesk.Aec.PropertyData.DataType dataType) { - var propDef = new PropertyDefinition(); + var propDef = new PropertyDefinition + { + DataType = dataType, + Name = entry.Key, + DefaultData = entry.Value + }; + propDef.SetToStandard(doc.Database); propDef.SubSetDatabaseDefaults(doc.Database); - propDef.Name = entry.Key; - var dataType = GetPropertySetType(entry.Value); - if (dataType != null) + propSetDef.Definitions.Add(propDef); + } + else + { + SpeckleLog.Logger.Error( $"Could not determine property set entry type of {entry.Value}. Property set entry not added to property set definitions."); + } + } + + return propSetDef; + } + + /// + /// Finds a property set by its ObjectId on a given object. + /// + /// The object to find the property set on. + /// The property set ObjectId to find on the object. + /// True if the property set with the given ObjectId was found, or false otherwise. + public static bool ObjectHasPropertySet(DBObject obj, ObjectId propertySetId) + { + ObjectId temporaryId = ObjectId.Null; + + try + { + temporaryId = PropertyDataServices.GetPropertySet(obj, propertySetId); + } + catch (Autodesk.AutoCAD.Runtime.Exception e) when (!e.IsFatal()) + { + // This will throw if the property set does not exist on the object. + // afaik, trycatch is necessary because there is no way to preemptively check if the set already exists. + // More than likely a runtime exception with message: eKeyNotFound. + } + + return temporaryId != ObjectId.Null; + } + + /// + /// Creates a property set on a given object. + /// Requires that the property set exists in the current database and + /// that the property set applies to the object. + /// + /// The object to create the property set on. + /// The objectID of the property set to create on the object + /// True if the property set was created on the object, or false if there was a failure. + public static void AddPropertySetToObject(DBObject obj, ObjectId propertySetId) + { + try + { + if (!ObjectHasPropertySet(obj, propertySetId)) + { + if (!obj.IsWriteEnabled) { - propDef.DataType = (Autodesk.Aec.PropertyData.DataType)dataType; + obj.UpgradeOpen(); } - propDef.DefaultData = entry.Value; - propSetDef.Definitions.Add(propDef); + PropertyDataServices.AddPropertySet(obj, propertySetId); } + } + catch (Autodesk.AutoCAD.Runtime.Exception e) + { + throw new InvalidOperationException($"Could not create property set on object {obj.Id}", e); + } + } + + public static void SetPropertySets(this Entity entity, Document doc, List> propertySetDicts) + { + // create a dictionary for property sets for this object + var name = $"Speckle {entity.Handle} Property Set"; + int count = 0; + using DictionaryPropertySetDefinitions dictPropSetDef = new(doc.Database); - // add the property sets to the object + // add property sets to object + using Transaction tr = doc.Database.TransactionManager.StartTransaction(); + foreach (Dictionary propertySetDict in propertySetDicts) + { try { + // create the property set definition for this set + PropertySetDefinition propSetDef = CreatePropertySet(propertySetDict, doc); + var propSetDefName = name += $" - {count}"; // add property set to the database - // todo: add logging if the property set couldnt be added because a def already exists - using (Transaction tr = doc.Database.TransactionManager.StartTransaction()) - { - var dictPropSetDef = new DictionaryPropertySetDefinitions(doc.Database); - dictPropSetDef.AddNewRecord(propSetDefName, propSetDef); - tr.AddNewlyCreatedDBObject(propSetDef, true); - - entity.UpgradeOpen(); - PropertyDataServices.AddPropertySet(entity, propSetDef.ObjectId); - tr.Commit(); - } + dictPropSetDef.AddNewRecord(propSetDefName, propSetDef); + tr.AddNewlyCreatedDBObject(propSetDef, true); + // add property set to the object + AddPropertySetToObject(entity, propSetDef.ObjectId); } - catch { } + catch (Autodesk.AutoCAD.Runtime.Exception) { } + + count++; } + + tr.Commit(); } /// - /// Get the property sets of DBObject + /// Get the property sets of DBObject /// /// /// @@ -354,9 +460,13 @@ public static List> GetPropertySets(this DBObject obj { propertySets = PropertyDataServices.GetPropertySets(obj); } - catch (Exception e) - { } - if (propertySets == null) + catch (Autodesk.AutoCAD.Runtime.Exception e) + { + // This may throw if property sets do not exist on the object. + // afaik, trycatch is necessary because there is no way to preemptively check if the set already exists. + } + + if (propertySets is null) { return sets; } @@ -377,9 +487,9 @@ public static List> GetPropertySets(this DBObject obj foreach (PropertySetData data in propertySet.PropertySetData) { - if (propDefs.ContainsKey(data.Id)) + if (propDefs.TryGetValue(data.Id, out PropertyDefinition value)) { - setDictionary.Add(propDefs[data.Id].Name, data.GetData()); + setDictionary.Add(value.Name, data.GetData()); } else { @@ -404,14 +514,14 @@ private static Dictionary CleanDictionary(Dictionary _: - case IEnumerable _: - case IEnumerable _: - case IEnumerable _: + case double: + case bool: + case int: + case string: + case IEnumerable: + case IEnumerable: + case IEnumerable: + case IEnumerable: target[key] = obj; continue; @@ -430,6 +540,7 @@ private static Dictionary CleanDictionary(Dictionary /// Gets the handles of all visible document objects that can be converted to Speckle @@ -457,12 +568,11 @@ public static List ConvertibleObjects(this Document doc, ISpeckleConvert } return objs; } - #endregion #region application id public static class ApplicationIdManager { - readonly static string ApplicationIdKey = "applicationId"; + static readonly string ApplicationIdKey = "applicationId"; /// /// Creates the application id xdata table in the doc if it doesn't already exist @@ -475,17 +585,16 @@ public static bool AddApplicationIdXDataToDoc(Document doc, Transaction tr) { try { - using (RegAppTableRecord regAppRecord = new()) - { - regAppRecord.Name = ApplicationIdKey; - regAppTable.UpgradeOpen(); - regAppTable.Add(regAppRecord); - regAppTable.DowngradeOpen(); - tr.AddNewlyCreatedDBObject(regAppRecord, true); - } + using RegAppTableRecord regAppRecord = new(); + regAppRecord.Name = ApplicationIdKey; + regAppTable.UpgradeOpen(); + regAppTable.Add(regAppRecord); + regAppTable.DowngradeOpen(); + tr.AddNewlyCreatedDBObject(regAppRecord, true); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Error(e, "Could not create the RegAppTableRecord for application ids in the Doc."); return false; } } @@ -520,7 +629,7 @@ public static string GetFromXData(Entity obj) /// This is used because the persistent id of the db object in the file is almost guaranteed to not be unique between files /// /// - /// + /// /// public static bool SetObjectCustomApplicationId( DBObject obj, @@ -544,7 +653,7 @@ public static bool SetObjectCustomApplicationId( obj.XData = rb; } - catch (Exception e) + catch (Autodesk.AutoCAD.Runtime.Exception) { return false; } @@ -606,16 +715,17 @@ string fileNameHash } } } - if (foundObjects.Any()) + + if (foundObjects.Count != 0) { return foundObjects; } // if no matching xdata appids were found, loop through handles instead var autocadAppIdParts = appId.Split('-'); - if (autocadAppIdParts.Count() == 2 && autocadAppIdParts.FirstOrDefault().StartsWith(fileNameHash)) + if (autocadAppIdParts.Length == 2 && autocadAppIdParts.FirstOrDefault().StartsWith(fileNameHash)) { - if (Utils.GetHandle(autocadAppIdParts.Last(), out Handle handle)) + if (GetHandle(autocadAppIdParts.Last(), out Handle handle)) { if (doc.Database.TryGetObjectId(handle, out ObjectId id)) { @@ -629,7 +739,6 @@ string fileNameHash } #endregion - /// /// Returns a descriptive string for reporting /// @@ -639,7 +748,7 @@ public static string ObjectDescriptor(DBObject obj) { if (obj == null) { - return String.Empty; + return string.Empty; } var simpleType = obj.GetType().Name; @@ -681,14 +790,31 @@ public static string GetUnits(Document doc) public static bool GetHandle(string str, out Handle handle) { handle = new Handle(); + if (string.IsNullOrEmpty(str)) + { + return false; + } + + long l; try { - handle = new Handle(Convert.ToInt64(str, 16)); + l = Convert.ToInt64(str, 16); + } + catch (ArgumentException) + { + return false; + } + catch (FormatException) + { + return false; } - catch + catch (OverflowException) { return false; } + + handle = new Handle(l); + return true; } @@ -707,15 +833,10 @@ public static LineWeight GetLineWeight(double weight) public static void SetStyle(Base styleBase, Entity entity, Dictionary lineTypeDictionary) { - var units = styleBase["units"] as string; var color = styleBase["color"] as int?; - if (color == null) - { - color = styleBase["diffuse"] as int?; // in case this is from a rendermaterial base - } + color ??= styleBase["diffuse"] as int?; // in case this is from a rendermaterial base var transparency = styleBase["opacity"] as double?; - var lineType = styleBase["linetype"] as string; var lineWidth = styleBase["lineweight"] as double?; if (color != null) @@ -730,17 +851,19 @@ public static void SetStyle(Base styleBase, Entity entity, Dictionary ReadState(cSapModel model) { var strings = ReadSpeckleFile(model); - if (strings == "") - { - return new List(); - } - try - { - return JsonConvert.DeserializeObject>(strings); - } - catch (Exception e) + if (string.IsNullOrEmpty(strings)) { return new List(); } + + return JsonConvert.DeserializeObject>(strings); } /// @@ -60,11 +54,8 @@ public static void ClearStreamStateList(cSapModel model) } FileStream fileStream = new(_speckleFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); - try - { - fileStream.SetLength(0); - } - catch { } + + fileStream.SetLength(0); } /// @@ -86,23 +77,16 @@ private static void GetOrCreateSpeckleFilePath(cSapModel model) string CSIFileName = Path.GetFileNameWithoutExtension(CSIModelfilePath); string speckleFolderPath = Path.Combine(CSIModelFolder, "speckle"); string speckleFilePath = Path.Combine(CSIModelFolder, "speckle", $"{CSIFileName}.txt"); - try + + if (!Directory.Exists(speckleFolderPath)) { - if (!Directory.Exists(speckleFolderPath)) - { - Directory.CreateDirectory(speckleFolderPath); - } - if (!File.Exists(speckleFilePath)) - { - File.CreateText(speckleFilePath); - } - _speckleFilePath = speckleFilePath; + Directory.CreateDirectory(speckleFolderPath); } - catch + if (!File.Exists(speckleFilePath)) { - _speckleFilePath = null; - return; + File.CreateText(speckleFilePath); } + _speckleFilePath = speckleFilePath; } /// @@ -122,17 +106,9 @@ private static string ReadSpeckleFile(cSapModel model) } FileStream fileStream = new(_speckleFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - try - { - using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) - { - return streamReader.ReadToEnd(); - } - } - catch - { - return ""; - } + + using var streamReader = new StreamReader(fileStream, Encoding.UTF8); + return streamReader.ReadToEnd(); } /// diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.ClientOperations.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.ClientOperations.cs index f2ca88aa1a..b41578d497 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.ClientOperations.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.ClientOperations.cs @@ -1,13 +1,9 @@ -using System; using System.Collections.Generic; using DesktopUI2; using DesktopUI2.Models; -using DesktopUI2.ViewModels; -using Speckle.Core.Logging; using ConnectorCSI.Storage; -using System.Linq; -using System.Threading.Tasks; -using DesktopUI2.Models.Settings; +using Speckle.Core.Logging; +using System; namespace Speckle.ConnectorCSI.UI; @@ -27,7 +23,15 @@ public override void WriteStreamsToFile(List streams) public override List GetStreamsInFile() { - return Model == null ? new List() : StreamStateManager.ReadState(Model); + try + { + return Model == null ? new List() : StreamStateManager.ReadState(Model); + } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Error when retreiving streams in file"); + return new(); + } } #endregion diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Recieve.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Recieve.cs index b599546ed1..7c53935a18 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Recieve.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Recieve.cs @@ -5,20 +5,15 @@ using Speckle.ConnectorCSI.Util; using Speckle.Core.Api; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; -using Speckle.Core.Transports; using System; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Resources; using System.Threading.Tasks; using Serilog.Context; -using Speckle.Core.Logging; using Speckle.Core.Models.GraphTraversal; -using Speckle.Core.Logging; using Speckle.Core.Kits.ConverterInterfaces; namespace Speckle.ConnectorCSI.UI; @@ -112,7 +107,6 @@ public override async Task ReceiveStream(StreamState state, Progres return state; } - [SuppressMessage("Design", "CA1031:Do not catch general exception types")] private List ConvertReceivedObjects(ISpeckleConverter converter, ProgressViewModel progress) { List conversionResults = new(); @@ -146,7 +140,7 @@ private List ConvertReceivedObjects(ISpeckleConverter convert log: conversionResult.Log ); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { ConnectorHelpers.LogConversionException(ex); diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Selection.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Selection.cs index e8d5a972b5..922759878c 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Selection.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Selection.cs @@ -1,7 +1,6 @@ using DesktopUI2; using DesktopUI2.Models.Filters; using Speckle.ConnectorCSI.Util; -using System; using System.Collections.Generic; using System.Linq; @@ -67,7 +66,7 @@ public override List GetSelectionFilters() ); } - string[] groupNames = new string[0]; + string[] groupNames = System.Array.Empty(); int numNames = 0; Model.GroupDef.GetNameList(ref numNames, ref groupNames); if (groupNames.Any()) diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Send.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Send.cs index 9fb9657f91..494e5915be 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Send.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Send.cs @@ -9,7 +9,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Serilog.Context; @@ -81,7 +80,6 @@ public override async Task SendStream(StreamState state, ProgressViewMod return await SendCommitObj(state, progress, commitObj, conversionProgressDict); } - [SuppressMessage("Design", "CA1031:Do not catch general exception types")] public void BuildSendCommitObj( ISpeckleConverter converter, List selectedObjIds, @@ -129,7 +127,7 @@ ref ConcurrentDictionary conversionProgressDict logItem: $"Sent as {ConnectorCSIUtils.SimplifySpeckleType(converted.speckle_type)}" ); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { ConnectorHelpers.LogConversionException(ex); @@ -159,8 +157,9 @@ ConcurrentDictionary conversionProgressDict commitObj["@Model"] = converter.ConvertToSpeckle(("Model", "CSI")); reportObj.Update(status: ApplicationObject.State.Created); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "Error when attempting to retreive commit object"); reportObj.Update(status: ApplicationObject.State.Failed, logItem: ex.Message); } progress.Report.Log(reportObj); @@ -174,8 +173,9 @@ ConcurrentDictionary conversionProgressDict commitObj["AnalysisResults"] = converter.ConvertToSpeckle(("AnalysisResults", "CSI")); reportObj.Update(status: ApplicationObject.State.Created); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "Error when attempting to retreive analysis results"); reportObj.Update(status: ApplicationObject.State.Failed, logItem: ex.Message); } progress.Report.Log(reportObj); diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Settings.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Settings.cs index d990675744..74bf98825d 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Settings.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.Settings.cs @@ -1,9 +1,7 @@ using ConnectorCSIShared.Util; using DesktopUI2; using DesktopUI2.Models.Settings; -using System; using System.Collections.Generic; -using System.Text; namespace Speckle.ConnectorCSI.UI; diff --git a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.cs b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.cs index 12a6d9e447..52edef22a8 100644 --- a/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.cs +++ b/ConnectorCSI/ConnectorCSIShared/UI/ConnectorBindingsCSI.cs @@ -1,13 +1,9 @@ using System; using System.Collections.Generic; using DesktopUI2; -using DesktopUI2.Models; using Speckle.Core.Models; -using Speckle.ConnectorCSI.Util; -using System.Timers; using CSiAPIv1; using Speckle.Core.Kits; -using System.Threading.Tasks; namespace Speckle.ConnectorCSI.UI; diff --git a/ConnectorCSI/ConnectorCSIShared/Util/ConnectorCSIUtils.cs b/ConnectorCSI/ConnectorCSIShared/Util/ConnectorCSIUtils.cs index af7a8d02d8..baca0fc375 100644 --- a/ConnectorCSI/ConnectorCSIShared/Util/ConnectorCSIUtils.cs +++ b/ConnectorCSI/ConnectorCSIShared/Util/ConnectorCSIUtils.cs @@ -42,7 +42,10 @@ public static void GetObjectIDsTypesAndNames(cSapModel model) { names = GetAllNamesOfObjectType(model, objectType); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Error thrown from method {method}", nameof(GetAllNamesOfObjectType)); + } if (names.Count > 0) { foreach (string name in names) @@ -107,9 +110,7 @@ public static List GetAllNamesOfObjectType(cSapModel model, string objec case "NodeLoading": return GetAllPointNames(model); case "Model": - var names = new string[] { }; - names.Append(model.GetModelFilename()); - return names.ToList(); + return new List { model.GetModelFilename() }; case "ColumnResults": return GetColumnNames(model); case "BeamResults": @@ -131,31 +132,19 @@ public static List GetAllNamesOfObjectType(cSapModel model, string objec public static List GetAllPointNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PointObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PointObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllFrameNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.FrameObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.FrameObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetColumnNames(cSapModel model) @@ -240,31 +229,19 @@ public static List GetAllElementNames(cSapModel model) public static List GetAllTendonNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.TendonObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.TendonObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllAreaNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.AreaObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.AreaObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllWallNames(cSapModel model) @@ -314,345 +291,207 @@ public static List GetAllFloorNames(cSapModel model) public static List GetAllLinkNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.LinkObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.LinkObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropMaterialNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropMaterial.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropMaterial.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropRebarNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropRebar.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropRebar.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropFrameNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropFrame.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropFrame.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllLoadCaseNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.LoadCases.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.LoadCases.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllGroupNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.GroupDef.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.GroupDef.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllGridNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.GridSys.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.GridSys.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllComboNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.RespCombo.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.RespCombo.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllConstraintNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.ConstraintDef.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.ConstraintDef.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllLoadPatternNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.LoadPatterns.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.LoadPatterns.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllSteelDesignNames(cSapModel model) { var name = ""; - try - { - model.DesignSteel.GetCode(ref name); - return new List() { name }; - } - catch - { - return null; - } + + model.DesignSteel.GetCode(ref name); + return new List() { name }; } public static List GetAllConcreteDesignNames(cSapModel model) { var name = ""; - try - { - model.DesignConcrete.GetCode(ref name); - return new List() { name }; - } - catch - { - return null; - } + + model.DesignConcrete.GetCode(ref name); + return new List() { name }; } public static List GetAllStoryNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.Story.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.Story.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllDiaphragmNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.Diaphragm.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.Diaphragm.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllLineNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.LineElm.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.LineElm.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPierLabelNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PierLabel.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PierLabel.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropAreaSpringNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropAreaSpring.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropAreaSpring.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropLineSpringNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropLineSpring.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropLineSpring.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropPointSpringNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropPointSpring.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropPointSpring.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllSpandrelLabelNames(cSapModel model) { int num = 0; - var names = new string[] { }; - var isMultiStory = new bool[] { }; - try - { - model.SpandrelLabel.GetNameList(ref num, ref names, ref isMultiStory); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + var isMultiStory = Array.Empty(); + + model.SpandrelLabel.GetNameList(ref num, ref names, ref isMultiStory); + return names.ToList(); } public static List GetAllTowerNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.Tower.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.Tower.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropTendonNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropTendon.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropTendon.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllPropLinkNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PropLink.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PropLink.GetNameList(ref num, ref names); + return names.ToList(); } #endregion @@ -660,8 +499,8 @@ public static List GetAllPropLinkNames(cSapModel model) public static List<(string, string)> SelectedObjects(cSapModel model) { int num = 0; - var types = new int[] { }; - var names = new string[] { }; + var types = Array.Empty(); + var names = Array.Empty(); model.SelectObj.GetSelected(ref num, ref types, ref names); var typesAndNames = new List<(string, string)>(); if (num < 1) diff --git a/ConnectorCSI/ConnectorCSIShared/Util/ResultUtils.cs b/ConnectorCSI/ConnectorCSIShared/Util/ResultUtils.cs index ee0ab1b3f6..ab9c0f4e31 100644 --- a/ConnectorCSI/ConnectorCSIShared/Util/ResultUtils.cs +++ b/ConnectorCSI/ConnectorCSIShared/Util/ResultUtils.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using CSiAPIv1; namespace ConnectorCSIShared.Util; diff --git a/ConnectorCSI/ConnectorSAP2000/Properties/AssemblyInfo.cs b/ConnectorCSI/ConnectorSAP2000/Properties/AssemblyInfo.cs index 0c2e52ed9d..58ae925778 100644 --- a/ConnectorCSI/ConnectorSAP2000/Properties/AssemblyInfo.cs +++ b/ConnectorCSI/ConnectorSAP2000/Properties/AssemblyInfo.cs @@ -1,5 +1,3 @@ -using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // Setting ComVisible to false makes the types in this assembly not visible diff --git a/ConnectorCSI/DriverCSharp/Program.cs b/ConnectorCSI/DriverCSharp/Program.cs index 259504b593..be6fc1d362 100644 --- a/ConnectorCSI/DriverCSharp/Program.cs +++ b/ConnectorCSI/DriverCSharp/Program.cs @@ -1,10 +1,13 @@ using System; -using System.Diagnostics; -using System.Linq; +using Speckle.Core.Logging; using System.Windows.Forms; using CSiAPIv1; using SpeckleConnectorCSI; +#if DEBUG +using System.Diagnostics; +#endif + namespace DriverCSharp; class Program @@ -16,55 +19,47 @@ class Program static int Main(string[] args) { + try + { #if DEBUG - Debugger.Launch(); + Debugger.Launch(); #endif - //MessageBox.Show("Starting DriverCSharp"); + //MessageBox.Show("Starting DriverCSharp"); - // dimension the SapObject as cOAPI type - cOAPI mySapObject = null; + // dimension the SapObject as cOAPI type + cOAPI mySapObject = null; - // Use ret to check if functions return successfully (ret = 0) or fail (ret = nonzero) - int ret = -1; + // Use ret to check if functions return successfully (ret = 0) or fail (ret = nonzero) + int ret = -1; - // create API helper object - cHelper myHelper = null; + // create API helper object + cHelper myHelper = null; - try - { myHelper = new Helper(); - } - catch (Exception ex) - { - MessageBox.Show("Cannot create an instance of the Helper object: " + ex.Message); - ret = -1; - return ret; - } - // attach to a running program instance - try - { + // attach to a running program instance + // get the active SapObject // determine program type string progID = null; string[] arguments = Environment.GetCommandLineArgs(); - if (arguments.Count() > 1) + if (arguments.Length > 1) { string arg = arguments[1]; - if (string.Compare(arg, "SAP2000", true) == 0) + if (string.Equals(arg, "SAP2000", StringComparison.CurrentCultureIgnoreCase)) { progID = ProgID_SAP2000; } - else if (string.Compare(arg, "ETABS", true) == 0) + else if (string.Equals(arg, "ETABS", StringComparison.CurrentCultureIgnoreCase)) { progID = ProgID_ETABS; } - else if (string.Compare(arg, "SAFE", true) == 0) + else if (string.Equals(arg, "SAFE", StringComparison.CurrentCultureIgnoreCase)) { progID = ProgID_SAFE; } - else if (string.Compare(arg, "CSiBridge", true) == 0) + else if (string.Equals(arg, "CSiBridge", StringComparison.CurrentCultureIgnoreCase)) { progID = ProgID_CSiBridge; } @@ -77,47 +72,33 @@ static int Main(string[] args) else { // missing/unknown program type, try one by one - try - { - progID = ProgID_SAP2000; - mySapObject = myHelper.GetObject(progID); - } - catch (Exception ex) { } + progID = ProgID_SAP2000; + mySapObject = myHelper.GetObject(progID); if (mySapObject == null) { - try - { - progID = ProgID_ETABS; - mySapObject = myHelper.GetObject(progID); - } - catch (Exception ex) { } + progID = ProgID_ETABS; + mySapObject = myHelper.GetObject(progID); } if (mySapObject == null) { - try - { - progID = ProgID_CSiBridge; - mySapObject = myHelper.GetObject(progID); - } - catch (Exception ex) { } + progID = ProgID_CSiBridge; + mySapObject = myHelper.GetObject(progID); } } - } - catch (Exception ex) - { - MessageBox.Show("No running instance of the program found or failed to attach: " + ex.Message); - ret = -2; - return ret; - } + if (mySapObject is null) + { + MessageBox.Show("No running instance of the program found"); + + ret = -2; + return ret; + } - // Get a reference to cSapModel to access all API classes and functions - cSapModel mySapModel = mySapObject.SapModel; + // Get a reference to cSapModel to access all API classes and functions + cSapModel mySapModel = mySapObject.SapModel; - // call Speckle plugin - try - { + // call Speckle plugin cPlugin p = new(); cPluginCallback cb = new PluginCallback(); @@ -130,12 +111,11 @@ static int Main(string[] args) return cb.ErrorFlag; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { - MessageBox.Show("Failed to call plugin: " + ex.Message); - - ret = -3; - return ret; + SpeckleLog.Logger.Fatal(ex, "Failed to initialize plugin"); + MessageBox.Show("Failed to initialize plugin: " + ex.Message); + return -3; } } } diff --git a/ConnectorCore/BatchUploader.OperationDriver/BatchUploadOperationDriver.cs b/ConnectorCore/BatchUploader.OperationDriver/BatchUploadOperationDriver.cs index b3266f2c97..ae1335ef2d 100644 --- a/ConnectorCore/BatchUploader.OperationDriver/BatchUploadOperationDriver.cs +++ b/ConnectorCore/BatchUploader.OperationDriver/BatchUploadOperationDriver.cs @@ -7,6 +7,7 @@ using Speckle.BatchUploader.Sdk.Interfaces; using Speckle.Core.Api; using Speckle.Core.Credentials; +using Speckle.Core.Logging; namespace Speckle.BatchUploader.OperationDriver; @@ -73,9 +74,11 @@ private async Task ProcessJob(Guid jobId) var jobDescription = await _client.GetJobDescription(jobId).ConfigureAwait(false); await _applicationController.OpenDocument(jobDescription.FilePath).ConfigureAwait(false); + Account defaultAccount = AccountManager.GetDefaultAccount() ?? throw new SpeckleException("No default account"); + var state = new StreamState() { - Client = new Client(AccountManager.GetDefaultAccount()), //TODO + Client = new Client(defaultAccount), BranchName = jobDescription.Branch, StreamId = jobDescription.Stream, Filter = new AllSelectionFilter diff --git a/ConnectorCore/BatchUploader.OperationDriver/BatchUploader.OperationDriver.csproj b/ConnectorCore/BatchUploader.OperationDriver/BatchUploader.OperationDriver.csproj index 458f9088b5..80c9a82419 100644 --- a/ConnectorCore/BatchUploader.OperationDriver/BatchUploader.OperationDriver.csproj +++ b/ConnectorCore/BatchUploader.OperationDriver/BatchUploader.OperationDriver.csproj @@ -7,6 +7,10 @@ 10 Speckle.BatchUploader.OperationDriver + + + true + diff --git a/ConnectorCore/BatchUploader.Sdk/BatchUploader.Sdk.csproj b/ConnectorCore/BatchUploader.Sdk/BatchUploader.Sdk.csproj index db6da0358e..8ac8087f32 100644 --- a/ConnectorCore/BatchUploader.Sdk/BatchUploader.Sdk.csproj +++ b/ConnectorCore/BatchUploader.Sdk/BatchUploader.Sdk.csproj @@ -13,6 +13,10 @@ $(PackageTags) revit uploader batch true + + + true + diff --git a/ConnectorDynamo/ConnectorDynamo.slnf b/ConnectorDynamo/ConnectorDynamo.slnf index 7bf2cb30df..4ea38401a6 100644 --- a/ConnectorDynamo/ConnectorDynamo.slnf +++ b/ConnectorDynamo/ConnectorDynamo.slnf @@ -6,7 +6,7 @@ "ConnectorDynamo\\ConnectorDynamoFunctions\\ConnectorDynamoFunctions.csproj", "ConnectorDynamo\\ConnectorDynamo\\ConnectorDynamo.csproj", "Core\\Core\\Core.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "Objects\\Converters\\ConverterDxf\\ConverterDxf\\ConverterDxf.csproj", "Objects\\Converters\\ConverterDynamo\\ConverterDynamoRevit2021\\ConverterDynamoRevit2021.csproj", @@ -23,7 +23,13 @@ "Objects\\Converters\\ConverterRevit\\ConverterRevit2024\\ConverterRevit2024.csproj", "Objects\\Converters\\ConverterRevit\\ConverterRevitShared\\ConverterRevitShared.shproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj", + "ConnectorRevit\\RevitSharedResources2020\\RevitSharedResources2020.csproj", + "ConnectorRevit\\RevitSharedResources2021\\RevitSharedResources2021.csproj", + "ConnectorRevit\\RevitSharedResources2022\\RevitSharedResources2022.csproj", + "ConnectorRevit\\RevitSharedResources2023\\RevitSharedResources2023.csproj", + "ConnectorRevit\\RevitSharedResources2024\\RevitSharedResources2024.csproj", + "ConnectorRevit\\RevitSharedResources\\RevitSharedResources.shproj" ] } -} \ No newline at end of file +} diff --git a/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsUi.xaml.cs b/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsUi.xaml.cs index eecd8d095b..53ba8494cf 100644 --- a/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsUi.xaml.cs +++ b/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsUi.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Speckle.ConnectorDynamo.AccountsNode; diff --git a/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsViewCustomization.cs b/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsViewCustomization.cs index 20b99ab0e7..a2ec9a6536 100644 --- a/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsViewCustomization.cs +++ b/ConnectorDynamo/ConnectorDynamo/AccountsNode/AccountsViewCustomization.cs @@ -1,8 +1,6 @@ using System; -using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Models; -using Dynamo.Scheduler; using Dynamo.ViewModels; using Dynamo.Wpf; using System.Threading.Tasks; diff --git a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStream.cs b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStream.cs index 40f25e3941..f15414ffbd 100644 --- a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStream.cs +++ b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStream.cs @@ -10,6 +10,7 @@ using Speckle.Core.Api; using Speckle.Core.Credentials; using Speckle.Core.Logging; +using Speckle.Core.Models.Extensions; using Account = Speckle.Core.Credentials.Account; namespace Speckle.ConnectorDynamo.CreateStreamNode; @@ -146,7 +147,7 @@ internal void DoCreateStream() CreateEnabled = false; SelectedUserId = SelectedAccount.userInfo.id; - this.Name = "Stream Created"; + Name = "Stream Created"; Analytics.TrackEvent( SelectedAccount, @@ -156,22 +157,10 @@ internal void DoCreateStream() OnNodeModified(true); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { - //someone improve this pls :) - if (ex.InnerException != null && ex.InnerException.InnerException != null) - { - Error(ex.InnerException.InnerException.Message); - } - - if (ex.InnerException != null) - { - Error(ex.InnerException.Message); - } - else - { - Error(ex.Message); - } + SpeckleLog.Logger.Error(ex, "Failed to create stream"); + Error("Failed to create stream: " + ex.ToFormattedString()); } } diff --git a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamUi.xaml.cs b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamUi.xaml.cs index 053a339788..ba52c1298d 100644 --- a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamUi.xaml.cs +++ b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamUi.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Speckle.ConnectorDynamo.CreateStreamNode; diff --git a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamViewCustomization.cs b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamViewCustomization.cs index 39f8d56ce3..bc03bd4d7b 100644 --- a/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamViewCustomization.cs +++ b/ConnectorDynamo/ConnectorDynamo/CreateStreamNode/CreateStreamViewCustomization.cs @@ -1,15 +1,12 @@ using System; -using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Models; -using Dynamo.Scheduler; using Dynamo.ViewModels; using Dynamo.Wpf; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; -using Speckle.Core.Credentials; namespace Speckle.ConnectorDynamo.CreateStreamNode; diff --git a/ConnectorDynamo/ConnectorDynamo/DebounceTimer.cs b/ConnectorDynamo/ConnectorDynamo/DebounceTimer.cs index 352b9327c4..09de924457 100644 --- a/ConnectorDynamo/ConnectorDynamo/DebounceTimer.cs +++ b/ConnectorDynamo/ConnectorDynamo/DebounceTimer.cs @@ -1,6 +1,5 @@ using System; using System.Timers; -using System.Windows.Threading; namespace Speckle.ConnectorDynamo; diff --git a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/Receive.cs b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/Receive.cs index 9bea337c71..ddeeba7815 100644 --- a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/Receive.cs +++ b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/Receive.cs @@ -325,15 +325,15 @@ void ErrorAction(string transportName, Exception e) Message = ""; } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { if (!_cancellationToken.IsCancellationRequested) { _cancellationToken.Cancel(); - var msg = e.ToFormattedString(); + var msg = ex.ToFormattedString(); Message = msg.Contains("401") || msg.Contains("don't have access") ? "Not authorized" : "Error"; Warning(msg); - _errors.Add(e); + _errors.Add(ex); throw; } } @@ -383,7 +383,7 @@ internal void LoadInputs(EngineController engine) CommitId = inputStream.CommitId }; } - catch + catch (Exception ex) when (!ex.IsFatal()) { // ignored } @@ -396,7 +396,7 @@ internal void LoadInputs(EngineController engine) var url = GetInputAs(engine, 0); newStream = new StreamWrapper(url); } - catch + catch (Exception ex) when (!ex.IsFatal()) { // ignored } @@ -520,7 +520,7 @@ private void CheckIfBehind() Message = "Up to date"; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Error( ex, @@ -547,7 +547,7 @@ private void GetExpiredObjectCount(string objectId) Message = "Updates available"; _objectCount = count; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Error( ex, diff --git a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveUi.xaml.cs b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveUi.xaml.cs index b40114dd20..27ee4bfe3b 100644 --- a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveUi.xaml.cs +++ b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveUi.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Speckle.ConnectorDynamo.ReceiveNode; diff --git a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveViewCustomization.cs b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveViewCustomization.cs index a051576a5f..89acd2cc77 100644 --- a/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveViewCustomization.cs +++ b/ConnectorDynamo/ConnectorDynamo/ReceiveNode/ReceiveViewCustomization.cs @@ -1,10 +1,7 @@ -using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Models; -using Dynamo.Scheduler; using Dynamo.ViewModels; using Dynamo.Wpf; -using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; diff --git a/ConnectorDynamo/ConnectorDynamo/SendNode/Send.cs b/ConnectorDynamo/ConnectorDynamo/SendNode/Send.cs index a254820695..5f880d5537 100644 --- a/ConnectorDynamo/ConnectorDynamo/SendNode/Send.cs +++ b/ConnectorDynamo/ConnectorDynamo/SendNode/Send.cs @@ -259,11 +259,11 @@ internal void DoSend(EngineController engine) { @base = converter.ConvertRecursivelyToSpeckle(_data); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { Message = "Conversion error"; - Warning(e.ToFormattedString()); - throw new SpeckleException("Conversion error", e); + Warning(ex.ToFormattedString()); + throw new SpeckleException("Conversion error", ex); } Message = "Sending..."; @@ -312,13 +312,13 @@ void ErrorAction(string transportName, Exception e) Message = ""; } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { if (!_cancellationToken.IsCancellationRequested) { _cancellationToken.Cancel(); - Message = e.InnerException != null ? e.InnerException.Message : e.Message; - throw new SpeckleException(e.Message, e); + Message = ex.InnerException != null ? ex.InnerException.Message : ex.Message; + throw new SpeckleException(ex.Message, ex); } } finally @@ -367,8 +367,9 @@ internal void LoadInputs(EngineController engine) { _data = GetInputAs(engine, 0, true); } - catch + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Warning(ex, "Data input is invalid"); ResetNode(true); Message = "Data input is invalid"; return; @@ -396,16 +397,17 @@ internal void LoadInputs(EngineController engine) _transports = transportsDict.Keys.ToList(); _branchNames = transportsDict; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Warning(ex, "Send operation failed"); //ignored ResetNode(true); - Warning(e.InnerException?.Message ?? e.Message); + Warning(ex.ToFormattedString()); Message = "Not authorized"; return; } - if (_transports == null || !_transports.Any()) + if (_transports == null || _transports.Count == 0) { ResetNode(true); Message = "Stream is invalid"; @@ -417,7 +419,7 @@ internal void LoadInputs(EngineController engine) { _commitMessage = InPorts[2].Connectors.Any() ? GetInputAs(engine, 2) : ""; //IsConnected not working because has default value } - catch + catch (Exception ex) when (!ex.IsFatal()) { Message = "Message is invalid, will skip it"; } diff --git a/ConnectorDynamo/ConnectorDynamo/SendNode/SendUi.xaml.cs b/ConnectorDynamo/ConnectorDynamo/SendNode/SendUi.xaml.cs index d30d55182d..f87f507a06 100644 --- a/ConnectorDynamo/ConnectorDynamo/SendNode/SendUi.xaml.cs +++ b/ConnectorDynamo/ConnectorDynamo/SendNode/SendUi.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Speckle.ConnectorDynamo.SendNode; diff --git a/ConnectorDynamo/ConnectorDynamo/SendNode/SendViewCustomization.cs b/ConnectorDynamo/ConnectorDynamo/SendNode/SendViewCustomization.cs index 0992deb509..8c8e888296 100644 --- a/ConnectorDynamo/ConnectorDynamo/SendNode/SendViewCustomization.cs +++ b/ConnectorDynamo/ConnectorDynamo/SendNode/SendViewCustomization.cs @@ -1,10 +1,7 @@ -using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Models; -using Dynamo.Scheduler; using Dynamo.ViewModels; using Dynamo.Wpf; -using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; diff --git a/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewUi.xaml.cs b/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewUi.xaml.cs index 3e353bdc73..195ff5ad02 100644 --- a/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewUi.xaml.cs +++ b/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewUi.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Speckle.ConnectorDynamo.ViewNode; diff --git a/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewViewCustomization.cs b/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewViewCustomization.cs index cc3f9cbe92..35cc05f0f0 100644 --- a/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewViewCustomization.cs +++ b/ConnectorDynamo/ConnectorDynamo/ViewNode/ViewViewCustomization.cs @@ -1,7 +1,5 @@ -using Dynamo.Configuration; using Dynamo.Controls; using Dynamo.Models; -using Dynamo.Scheduler; using Dynamo.ViewModels; using Dynamo.Wpf; using System.Threading.Tasks; diff --git a/ConnectorDynamo/ConnectorDynamoExtension/SpeckleExtension.cs b/ConnectorDynamo/ConnectorDynamoExtension/SpeckleExtension.cs index b72d99cb70..f73c9b5139 100644 --- a/ConnectorDynamo/ConnectorDynamoExtension/SpeckleExtension.cs +++ b/ConnectorDynamo/ConnectorDynamoExtension/SpeckleExtension.cs @@ -35,7 +35,10 @@ public void Loaded(ViewLoadedParams viewLoadedParams) Setup.Init(HostApplications.Dynamo.GetVersion(HostAppVersion.vRevit), HostApplications.Dynamo.Slug); } - catch (Exception e) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Fatal(ex, "Failed to load Speckle extension"); + } } private void Rdm_RevitDocumentChanged(object sender, EventArgs e) diff --git a/ConnectorDynamo/ConnectorDynamoExtension/SpeckleWatchHandler.cs b/ConnectorDynamo/ConnectorDynamoExtension/SpeckleWatchHandler.cs index 1f2ca6a3ca..310458f7aa 100644 --- a/ConnectorDynamo/ConnectorDynamoExtension/SpeckleWatchHandler.cs +++ b/ConnectorDynamo/ConnectorDynamoExtension/SpeckleWatchHandler.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using Dynamo.Interfaces; using Dynamo.ViewModels; using ProtoCore.Mirror; using Speckle.Core.Credentials; +using Speckle.Core.Logging; namespace Speckle.ConnectorDynamo.Extension; @@ -68,7 +68,7 @@ WatchHandlerCallback callback { return baseHandler.Process(data, preferredDictionaryOrdering, runtimeCore, tag, showRawData, callback); } - catch (Exception) + catch (Exception ex) when (!ex.IsFatal()) { return callback(data.Data, preferredDictionaryOrdering, runtimeCore, tag, showRawData); } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Auto.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Auto.cs index 011bde7bf3..7d66168f31 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Auto.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Auto.cs @@ -1,10 +1,9 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Autodesk.DesignScript.Runtime; -using Speckle.Core.Api; using Speckle.Core.Credentials; using Speckle.Core.Logging; @@ -76,18 +75,18 @@ public static Dictionary AutoReceive(object stream, bool enabled Task.Run(() => { //try parse as streamWrapper - if (stream is StreamWrapper) + if (stream is StreamWrapper wrapper) { - sw = (StreamWrapper)stream; + sw = wrapper; } //try parse as Url - else if (stream is string) + else if (stream is string s) { try { - sw = new StreamWrapper((string)stream); + sw = new StreamWrapper(s); } - catch + catch (Exception ex) when (ex is NotSupportedException or SpeckleException) { // ignored } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/BatchConverter.cs b/ConnectorDynamo/ConnectorDynamoFunctions/BatchConverter.cs index 8742deb7a4..6d5658fb57 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/BatchConverter.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/BatchConverter.cs @@ -177,7 +177,7 @@ private object TryConvertItemToSpeckle(object value) { return _converter.ConvertToSpeckle(value); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { var spcklEx = new SpeckleException($"Could not convert {value.GetType().Name} to Speckle:", ex); OnError?.Invoke(this, new OnErrorEventArgs(spcklEx)); @@ -226,7 +226,8 @@ public object ConvertDataTreeToNative(Base @base) .Split(';') // Split by ; .Select(text => { - int.TryParse(text, out var num); + // At this point, we expect split to yield all integers based on the dataTreePathRegex check above. + _ = int.TryParse(text, out var num); return num; }) .ToList(); @@ -331,9 +332,10 @@ private object TryConvertItemToNative(object value) { return _converter.ConvertToNative(@base); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - var spcklError = new Exception($"Could not convert {@base.GetType().Name}(id={@base.id}) to Dynamo.", e); + SpeckleLog.Logger.Error("Could not convert {typeName}(id={id}", @base.GetType().Name, @base.id); + var spcklError = new SpeckleException($"Could not convert {@base.GetType().Name}(id={@base.id}) to Dynamo.", ex); OnError?.Invoke(this, new OnErrorEventArgs(spcklError)); return null; } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Local.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Local.cs index 539da13ee2..aa28a39f11 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Local.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Local.cs @@ -21,7 +21,7 @@ public static string Send([ArbitraryDimensionArrayImport] object data) converter.OnError += (sender, args) => throw args.Error; var @base = converter.ConvertRecursivelyToSpeckle(data); - var objectId = Task.Run(async () => await Operations.Send(@base, disposeTransports: true)).Result; + var objectId = Task.Run(() => Operations.Send(@base)).Result; return objectId; } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Transport.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Transport.cs index d3023025ca..b93d8506d7 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Transport.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Developer/Transport.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using Dynamo.Graph.Nodes; -using Speckle.Core.Api; using Speckle.Core.Credentials; using Speckle.Core.Helpers; using Speckle.Core.Logging; @@ -29,7 +28,7 @@ public static object DiskTransport(string basePath = "") Analytics.TrackEvent(Analytics.Events.NodeRun, new Dictionary() { { "name", "Disk Transport" } }); - return new DiskTransport.DiskTransport(basePath); + return new DiskTransport(basePath); } /// diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Functions.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Functions.cs index 493ab9b152..819da029fd 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Functions.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Functions.cs @@ -3,17 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading; -using System.Windows.Forms; -using System.Xml.Linq; using Autodesk.DesignScript.Runtime; -using Sentry; using Speckle.Core.Api; using Speckle.Core.Credentials; using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Transports; -using static System.Resources.ResXFileRef; namespace Speckle.ConnectorDynamo.Functions; @@ -47,7 +43,10 @@ public static List Send( { totalCount = data?.GetTotalChildrenCount() ?? 0; } - catch (Exception e) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Warning(ex, "Failed to get total children count."); + } if (totalCount == 0) { @@ -108,7 +107,7 @@ public static List Send( commitWrappers.Add(wrapper.ToString()); Analytics.TrackEvent(client.Account, Analytics.Events.Send); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); return null; @@ -163,9 +162,9 @@ public static Dictionary Receive( commit = branch.commits.items[0]; } - catch + catch (Exception ex) when (!ex.IsFatal()) { - throw new SpeckleException("No branch found with name " + stream.BranchName); + throw new SpeckleException("No branch found with name " + stream.BranchName, ex); } } else if (stream.Type == StreamWrapperType.Commit) @@ -174,7 +173,7 @@ public static Dictionary Receive( { commit = client.CommitGet(stream.StreamId, stream.CommitId!, cancellationToken).Result; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); return null; @@ -213,6 +212,7 @@ public static Dictionary Receive( { throw new SpeckleException("Receive operation returned nothing"); } + try { client @@ -227,9 +227,9 @@ public static Dictionary Receive( ) .Wait(); } - catch + catch (Exception ex) when (!ex.IsFatal()) { - // Do nothing! + SpeckleLog.Logger.Error(ex, "Failed to register commit receipt"); } if (cancellationToken.IsCancellationRequested) @@ -247,7 +247,7 @@ public static Dictionary Receive( Analytics.Events.Receive, new Dictionary() { - { "sourceHostApp", HostApplications.GetHostAppFromString(commit.sourceApplication)?.Slug }, + { "sourceHostApp", HostApplications.GetHostAppFromString(commit.sourceApplication).Slug }, { "sourceHostAppVersion", commit.sourceApplication }, { "isMultiplayer", commit.authorId != client.Account.userInfo.id } } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Globals.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Globals.cs index 9f4a3ec07e..c346706d83 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Globals.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Globals.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Autodesk.DesignScript.Runtime; namespace Speckle.ConnectorDynamo.Functions; diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Icon.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Icon.cs index 2dc3873fce..15b715686c 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Icon.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Icon.cs @@ -1,10 +1,5 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Autodesk.DesignScript.Geometry; -using Autodesk.DesignScript.Runtime; namespace Speckle.ConnectorDynamo.Functions.AAA; diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/InMemoryCache.cs b/ConnectorDynamo/ConnectorDynamoFunctions/InMemoryCache.cs index fc85569b73..393a597476 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/InMemoryCache.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/InMemoryCache.cs @@ -1,9 +1,5 @@ using Autodesk.DesignScript.Runtime; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Speckle.ConnectorDynamo.Functions; diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Stream.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Stream.cs index a8b7bf009a..7332ed27fc 100755 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Stream.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Stream.cs @@ -62,7 +62,7 @@ public static object Get( ); } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); } @@ -112,9 +112,9 @@ public static StreamWrapper Update( { account = Task.Run(async () => await wrapper.GetAccount()).Result; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - throw e.InnerException ?? e; + throw ex.InnerException ?? ex; } var client = new Client(account); @@ -151,7 +151,7 @@ public static StreamWrapper Update( return wrapper; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); } @@ -191,9 +191,9 @@ public static object Details([ArbitraryDimensionArrayImport] object stream) { account = Task.Run(async () => await streamWrapper.GetAccount()).Result; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - throw e.InnerException ?? e; + throw ex.InnerException ?? ex; } var client = new Client(account); @@ -216,7 +216,7 @@ public static object Details([ArbitraryDimensionArrayImport] object stream) } ); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); return details; @@ -256,7 +256,9 @@ public static List List( if (account == null) { Utils.HandleApiExeption( - new Exception("No accounts found. Please use the Speckle Manager to manage your accounts on this computer.") + new SpeckleAccountManagerException( + "No accounts found. Please use the Speckle Manager to manage your accounts on this computer." + ) ); } @@ -271,7 +273,7 @@ public static List List( streamWrappers.Add(new StreamWrapper(x.id, account.userInfo.id, account.serverInfo.url)); }); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { Utils.HandleApiExeption(ex); } diff --git a/ConnectorDynamo/ConnectorDynamoFunctions/Utils.cs b/ConnectorDynamo/ConnectorDynamoFunctions/Utils.cs index 32cb481a28..028ea14906 100644 --- a/ConnectorDynamo/ConnectorDynamoFunctions/Utils.cs +++ b/ConnectorDynamo/ConnectorDynamoFunctions/Utils.cs @@ -4,6 +4,7 @@ using System.Linq; using Speckle.Core.Credentials; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Transports; namespace Speckle.ConnectorDynamo.Functions; @@ -91,72 +92,58 @@ internal static string GetAppName() return HostApplications.Dynamo.GetVersion(HostAppVersion.vRevit); } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return HostApplications.Dynamo.GetVersion(HostAppVersion.vRevit); } } } - //My god this function sucks. It took me 20 mins to understand. Why not one that simply deals with one stream wrapper, and then use linq to cast things around? + /// + /// Attempts to parse an input object into a list of stream wrapper instances. + /// + /// + /// The list of stream wrappers provided as input, or null if the input could not be parsed internal static List InputToStream(object input) { - try + return input switch { - //it's a list - var array = (input as ArrayList)?.ToArray(); - - try - { - //list of stream wrappers - return array.Cast().ToList(); - } - catch - { - //ignored - } + ArrayList arrayList => InputArrayListToStreams(arrayList), + StreamWrapper sw => new List { sw }, + string s when !string.IsNullOrEmpty(s) => new List { new(s) }, + _ => null + }; + } - try - { - //list of urls - return array.Cast().Select(x => new StreamWrapper(x)).ToList(); - } - catch - { - //ignored - } - } - catch + private static List InputArrayListToStreams(ArrayList arrayList) + { + if (arrayList == null) { - // ignored + return null; } + var array = arrayList.ToArray(); + try { - //single stream wrapper - var sw = input as StreamWrapper; - if (sw != null) - { - return new List { sw }; - } + //list of stream wrappers + return array.Cast().ToList(); } - catch + catch (InvalidCastException) { - //ignored + // List is not comprised of StreamWrapper instances + // This failure is expected. } try { - //single url - var s = input as string; - if (!string.IsNullOrEmpty(s)) - { - return new List { new(s) }; - } + //list of urls + return array.Cast().Select(x => new StreamWrapper(x)).ToList(); } - catch + catch (InvalidCastException) { - //ignored + // List is not comprised of string instances + // This failure is expected. } return null; diff --git a/ConnectorGrasshopper/ConnectorGrasshopper6/ConnectorGrasshopper6.csproj b/ConnectorGrasshopper/ConnectorGrasshopper6/ConnectorGrasshopper6.csproj index e2b19c1454..3edba7aeeb 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopper6/ConnectorGrasshopper6.csproj +++ b/ConnectorGrasshopper/ConnectorGrasshopper6/ConnectorGrasshopper6.csproj @@ -6,7 +6,7 @@ .gha Debug;Release;Debug Mac;Release Mac true - $(DefineConstants);RHINO6 + $(DefineConstants);RHINO6;RHINO6_OR_GREATER diff --git a/ConnectorGrasshopper/ConnectorGrasshopper7/ConnectorGrasshopper7.csproj b/ConnectorGrasshopper/ConnectorGrasshopper7/ConnectorGrasshopper7.csproj index dd8b147826..3b83177ef7 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopper7/ConnectorGrasshopper7.csproj +++ b/ConnectorGrasshopper/ConnectorGrasshopper7/ConnectorGrasshopper7.csproj @@ -6,7 +6,7 @@ .gha Debug;Release;Debug Mac;Release Mac true - $(DefineConstants);RHINO7 + $(DefineConstants);RHINO7;RHINO7_OR_GREATER;RHINO6_OR_GREATER @@ -29,6 +29,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/ConnectorGrasshopper/ConnectorGrasshopper8/ConnectorGrasshopper8.csproj b/ConnectorGrasshopper/ConnectorGrasshopper8/ConnectorGrasshopper8.csproj new file mode 100644 index 0000000000..800716423f --- /dev/null +++ b/ConnectorGrasshopper/ConnectorGrasshopper8/ConnectorGrasshopper8.csproj @@ -0,0 +1,39 @@ + + + ConnectorGrasshopper + SpeckleConnectorGrasshopper + net7.0-windows;net48 + .gha + Debug;Release;Debug Mac;Release Mac + true + $(DefineConstants);RHINO8;GRASSHOPPER;RHINO6_OR_GREATER;RHINO7_OR_GREATER;RHINO8_OR_GREATER + true + true + true + + + + + $(DefineConstants);MAC + + + + + + + + + + + + + + + + + + + + + + diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.GetAccountToken.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.GetAccountToken.cs index d96689cd89..1d577c6a63 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.GetAccountToken.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.GetAccountToken.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using System.Linq; +using ConnectorGrasshopper.Extras; using ConnectorGrasshopper.Properties; using Grasshopper; using Grasshopper.Kernel; @@ -46,12 +47,7 @@ public Accounts_GetAccountToken() protected override void RegisterInputParams(GH_InputParamManager pManager) { - pManager.AddTextParameter( - "Account", - "A", - "Account to get the auth token from. Expects the `userId`", - GH_ParamAccess.item - ); + pManager.AddParameter(new SpeckleAccountParam()); } protected override void RegisterOutputParams(GH_OutputParamManager pManager) @@ -66,14 +62,12 @@ protected override void RegisterOutputParams(GH_OutputParamManager pManager) public override void SolveInstanceWithLogContext(IGH_DataAccess DA) { - var userId = ""; - if (!DA.GetData(0, ref userId)) + Account account = null; + if (!DA.GetData(0, ref account)) { return; } - var acc = AccountManager.GetAccounts().FirstOrDefault(acc => acc.userInfo.id == userId); - - DA.SetData(0, acc.token); + DA.SetData(0, account.token); } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ListAccounts.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ListAccounts.cs index 815860b316..c83d8a55d7 100755 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ListAccounts.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ListAccounts.cs @@ -1,29 +1,31 @@ +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Windows.Forms; +using ConnectorGrasshopper.Extras; using ConnectorGrasshopper.Properties; using GH_IO.Serialization; using Grasshopper.Kernel; using Grasshopper.Kernel.Data; using Grasshopper.Kernel.Special; +using Grasshopper.Kernel.Types; using Speckle.Core.Credentials; namespace ConnectorGrasshopper.Accounts; public class AccountListComponent : GH_ValueList, ISpeckleTrackingDocumentObject { - private string selectedServerUrl; - - private string selectedUserId; + private Uri? _selectedAccountUrl; public AccountListComponent() { MutableNickName = false; //SetAccountList(); Tracker = new ComponentTracker(null); + _selectedAccountUrl = null; } protected override Bitmap Icon => Resources.Accounts; @@ -56,9 +58,6 @@ private void SetAccountList() ListItems.Clear(); ListItems.Add(new GH_ValueListItem("No account selected", "")); var accounts = AccountManager.GetAccounts().ToList(); - var defaultAccount = AccountManager.GetDefaultAccount(); - int index = 0, - defaultAccountIndex = 0; if (accounts.Count == 0) { @@ -70,24 +69,18 @@ private void SetAccountList() return; } - foreach (var account in accounts) - { - if (defaultAccount != null && account.userInfo.id == defaultAccount.userInfo.id) - { - defaultAccountIndex = index + 1; - } - - ListItems.Add(new GH_ValueListItem(account.ToString(), $"\"{account.userInfo.id}\"")); - index++; - } - Tracker.TrackNodeRun("Accounts list"); - if (string.IsNullOrEmpty(selectedServerUrl) && string.IsNullOrEmpty(selectedUserId)) - { - // This is a new component, use default account - SelectItem(defaultAccountIndex); + var valueItems = accounts.Select( + account => new GH_ValueListItem(account.ToString(), $"\"{AccountManager.GetLocalIdentifierForAccount(account)}\"") + ); + ListItems.AddRange(valueItems); + if (_selectedAccountUrl == null) + { + // This is a new component, use default account + 1 (first item is "No account selected") + var defaultAccountIndex = accounts.FindIndex(acc => acc.isDefault); + SelectItem(defaultAccountIndex + 1); return; } @@ -98,27 +91,33 @@ private void SetAccountList() private int GetSelectedAccountIndex(List accounts) { - //TODO: Refactor this into a method - // Check for the specific user ID that was selected before. - var acc = accounts.Find(a => a.userInfo.id == selectedUserId); - if (acc != null) + if (_selectedAccountUrl == null) { - var accIndex = accounts.IndexOf(acc); - return accIndex + 1; + return -1; } - // If the selected account doesn't work, try with another account in the same server - acc = accounts.FirstOrDefault(a => a.serverInfo.url == selectedServerUrl); + var acc = AccountManager.GetAccountForLocalIdentifier(_selectedAccountUrl); if (acc != null) { var accIndex = accounts.IndexOf(acc); - AddRuntimeMessage( - GH_RuntimeMessageLevel.Remark, - "Account mismatch. Using a different account for the same server." - ); - return accIndex + 1; } + else + { + // If the selected account doesn't work, try with another account in the same server + acc = accounts.FirstOrDefault(a => a.serverInfo.url == _selectedAccountUrl.GetLeftPart(UriPartial.Authority)); + if (acc != null) + { + var accIndex = accounts.IndexOf(acc); + AddRuntimeMessage( + GH_RuntimeMessageLevel.Remark, + "Account mismatch. Using a different account for the same server." + ); + + return accIndex + 1; + } + } + // If no accounts exist on the selected server, throw error in node. return -1; } @@ -127,50 +126,49 @@ public override bool Read(GH_IReader reader) { // Set isNew to false, indicating this node already existed in some way. This prevents the `NodeCreate` event from being raised. IsNew = false; - try + + string? userId = null; + string? serverUrl = null; + var idSuccess = reader.TryGetString("selectedId", ref userId); + var serverSuccess = reader.TryGetString("selectedServer", ref serverUrl); + + var isIdValid = idSuccess && userId != "-"; + var isServerValid = serverSuccess && serverUrl != "-"; + + string? accountUrl = null; + var accountUrlSuccess = reader.TryGetString(nameof(FirstSelectedItem), ref accountUrl); + var isAccountUrlValid = accountUrlSuccess && !string.IsNullOrEmpty(accountUrl); + + if (isAccountUrlValid) { - selectedUserId = reader.GetString("selectedId"); - selectedServerUrl = reader.GetString("selectedServer"); + _selectedAccountUrl = new(accountUrl); } - catch (Exception e) + else if (isIdValid && isServerValid) { - Console.WriteLine(e); + _selectedAccountUrl = new(serverUrl + "?id=" + userId); } + return base.Read(reader); } public override bool Write(GH_IWriter writer) { - try - { - var selectedUserId = FirstSelectedItem.Expression?.Trim('"'); - var selectedAccount = AccountManager.GetAccounts().FirstOrDefault(a => a.userInfo.id == selectedUserId); - if (selectedAccount != null) - { - writer.SetString("selectedId", selectedUserId); - writer.SetString("selectedServer", selectedAccount.serverInfo.url); - } - else - { - writer.SetString("selectedId", "-"); - writer.SetString("selectedServer", "-"); - } - } - catch (Exception e) - { - Console.WriteLine(e); - } + writer.SetString(nameof(FirstSelectedItem), FirstSelectedItem.Expression.Trim('"')); return base.Write(writer); } + /// + /// Custom method for collecting volatile data. + /// protected override void CollectVolatileData_Custom() { m_data.ClearData(); - - if (FirstSelectedItem.Value != null) + if (FirstSelectedItem.Value is GH_String strGoo) { - m_data.Append(FirstSelectedItem.Value, new GH_Path(0)); + var x = AccountManager.GetAccountForLocalIdentifier(new Uri(strGoo.Value)); + m_data.Append(new GH_SpeckleAccountGoo { Value = x }, new GH_Path(0)); } + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "hello"); } public override void AddedToDocument(GH_Document document) diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ServerAccount.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ServerAccount.cs index bfb15bba1b..bb7b31d994 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ServerAccount.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Accounts/Accounts.ServerAccount.cs @@ -88,12 +88,18 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) return; } + if (string.IsNullOrEmpty(sw)) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Server input cannot be null"); + return; + } + Uri url = null; try { url = new Uri(sw); } - catch (Exception e) + catch (UriFormatException e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Server input is not a valid url: {sw}"); return; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitAsyncComponentBase.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitAsyncComponentBase.cs index 6b5a81cc0e..7423a941f4 100755 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitAsyncComponentBase.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitAsyncComponentBase.cs @@ -54,7 +54,7 @@ public virtual void SetConverter() { SetConverterFromKit(SelectedKitName); } - catch + catch (Exception ex) when (!ex.IsFatal()) { AddRuntimeMessage( GH_RuntimeMessageLevel.Error, @@ -123,8 +123,9 @@ public override void AppendAdditionalMenuItems(ToolStripDropDown menu) Menu_AppendSeparator(menu); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "An error occurred while fetching Kits"); Menu_AppendItem(menu, "An error occurred while fetching Kits", null, false); } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitComponentBase.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitComponentBase.cs index e3a1a7f8cf..ff7b92ca12 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitComponentBase.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitComponentBase.cs @@ -4,6 +4,7 @@ using ConnectorGrasshopper.Extras; using Grasshopper.Kernel; using Speckle.Core.Kits; +using Speckle.Core.Logging; namespace ConnectorGrasshopper.Objects; @@ -46,10 +47,9 @@ public override void AppendAdditionalMenuItems(ToolStripDropDown menu) Menu_AppendSeparator(menu); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - // Todo: handle this - Console.WriteLine(e); + SpeckleLog.Logger.Error(ex, "Failed to append Kit selection menu items"); } } @@ -71,10 +71,9 @@ public void SetConverterFromKit(string kitName) Message = $"Using the {Kit.Name} Converter"; ExpireSolution(true); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - // TODO: handle this. - Console.WriteLine(e); + SpeckleLog.Logger.Error(ex, "Failed to set converter from Kit"); } } @@ -94,8 +93,9 @@ public override void AddedToDocument(GH_Document document) Converter.SetConverterSettings(SpeckleGHSettings.MeshSettings); Message = $"{Kit.Name} Kit"; } - catch + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "No default kit found on this machine."); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No default kit found on this machine."); } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitTaskCapableComponentBase.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitTaskCapableComponentBase.cs index 2373cc2f2c..c312761da9 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitTaskCapableComponentBase.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/BaseComponents/SelectKitTaskCapableComponentBase.cs @@ -60,8 +60,9 @@ public virtual bool SetConverter() SetConverterFromKit(SelectedKitName); return true; } - catch + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "No kit found on this machine."); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No kit found on this machine."); return false; } @@ -122,8 +123,9 @@ public override void AppendAdditionalMenuItems(ToolStripDropDown menu) Menu_AppendSeparator(menu); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "An error occurred while fetching Kits"); Menu_AppendItem(menu, "An error occurred while fetching Kits", null, false); } } @@ -161,9 +163,10 @@ protected override void BeforeSolveInstance() { Converter?.SetContextDocument(Loader.GetCurrentDocument()); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Failed to set document context:\n\t{e.ToFormattedString()}"); + SpeckleLog.Logger.Error(ex, "Failed to set document context"); + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Failed to set document context:\n\t{ex.ToFormattedString()}"); } base.BeforeSolveInstance(); } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Collections/FlattenCollectionComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Collections/FlattenCollectionComponent.cs index 3ecafa5250..4ff3728273 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Collections/FlattenCollectionComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Collections/FlattenCollectionComponent.cs @@ -3,9 +3,7 @@ using System.Drawing; using System.Linq; using Grasshopper.Kernel; -using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Core.Models.GraphTraversal; namespace ConnectorGrasshopper.Collections; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/DeserialiseTaskCapableComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/DeserialiseTaskCapableComponent.cs index e75450e148..fa13f09747 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/DeserialiseTaskCapableComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/DeserialiseTaskCapableComponent.cs @@ -8,6 +8,7 @@ using Grasshopper; using Grasshopper.Kernel; using Speckle.Core.Api; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; @@ -99,11 +100,12 @@ private Base DoWork(string item, IGH_DataAccess DA) { return Operations.Deserialize(item); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "Failed to deserialize object"); AddRuntimeMessage( GH_RuntimeMessageLevel.Warning, - $"Cannot deserialize object at path {{{DA.ParameterTargetPath(0)}}}[{DA.ParameterTargetIndex(0)}]: {e.ToFormattedString()}" + $"Cannot deserialize object at path {{{DA.ParameterTargetPath(0)}}}[{DA.ParameterTargetIndex(0)}]: {ex.ToFormattedString()}" ); return null; } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/SerialiseTaskCapableComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/SerialiseTaskCapableComponent.cs index 4dfbe90d71..1da1f8d3d1 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/SerialiseTaskCapableComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/SerialiseTaskCapableComponent.cs @@ -8,6 +8,7 @@ using Grasshopper; using Grasshopper.Kernel; using Speckle.Core.Api; +using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; namespace ConnectorGrasshopper.Conversion; @@ -102,9 +103,10 @@ private string DoWork(GH_SpeckleBase item, IGH_DataAccess DA) { return Operations.Serialize(item.Value); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.ToFormattedString()); + SpeckleLog.Logger.ForContext("speckle_type", item.Value.speckle_type).Error(ex, "Failed to serialise object"); + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, ex.ToFormattedString()); return null; } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToNativeTaskCapableComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToNativeTaskCapableComponent.cs index ded9182274..d90ab9f208 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToNativeTaskCapableComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToNativeTaskCapableComponent.cs @@ -100,7 +100,7 @@ private IGH_Goo DoWork(object item, IGH_DataAccess DA) { return Utilities.TryConvertItemToNative(item, Converter, true); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... if (ex is AggregateException aggregateException) diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToSpeckleTaskCapableComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToSpeckleTaskCapableComponent.cs index 63175e58bb..bb5999362f 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToSpeckleTaskCapableComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Conversion/ToSpeckleTaskCapableComponent.cs @@ -141,7 +141,7 @@ private IGH_Goo DoWork(object item, IGH_DataAccess DA) return new GH_SpeckleBase { Value = converted as Base }; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/GH_SpeckleAccount.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/GH_SpeckleAccount.cs index 2ec9969f6d..88ea73f63a 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/GH_SpeckleAccount.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/GH_SpeckleAccount.cs @@ -1,6 +1,5 @@ using System; using System.Drawing; -using System.Linq; using ConnectorGrasshopper.Properties; using Grasshopper.Kernel; using Grasshopper.Kernel.Types; @@ -17,11 +16,6 @@ public GH_SpeckleAccountGoo(Account account) m_value = account; } - public GH_SpeckleAccountGoo(string userId) - { - m_value = AccountManager.GetAccounts().First(acc => acc.id == userId); - } - public override bool IsValid => m_value != null; public override string TypeName => "GH_SpeckleAccount"; public override string TypeDescription => "An account belonging to a user in a Speckle server"; @@ -38,33 +32,12 @@ public override string ToString() public override bool CastFrom(object source) { - if (source is GH_String ghString) - { - try - { - Value = AccountManager.GetAccounts().First(acc => acc.userInfo.id == ghString.Value); - return true; - } - catch (Exception e) // TODO: Handle this exception instead of ignoring it - { } - } - - if (source is string userId) - { - try - { - Value = AccountManager.GetAccounts().First(acc => acc.id == userId); - return true; - } - catch (Exception e) // TODO: Handle this exception instead of ignoring it - { } - } - if (source is Account account) { Value = account; return true; } + return base.CastFrom(source); } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/SpeckleStreamParam.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/SpeckleStreamParam.cs index a32a21e9b4..522883a6ed 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/SpeckleStreamParam.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/SpeckleStreamParam.cs @@ -4,6 +4,7 @@ using Grasshopper.Kernel; using Grasshopper.Kernel.Types; using Speckle.Core.Credentials; +using Speckle.Core.Logging; namespace ConnectorGrasshopper.Extras; @@ -92,7 +93,7 @@ public override bool CastFrom(object source) Value = new StreamWrapper(ghStr.Value); return true; } - catch + catch (Exception ex) when (!ex.IsFatal()) { return false; } @@ -105,7 +106,7 @@ public override bool CastFrom(object source) Value = new StreamWrapper(str); return true; } - catch + catch (Exception ex) when (!ex.IsFatal()) { return false; } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/Utilities.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/Utilities.cs index 3e45cf2cbb..101ca74e88 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/Utilities.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Extras/Utilities.cs @@ -14,6 +14,7 @@ using Rhino.Display; using Rhino.Geometry; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; namespace ConnectorGrasshopper.Extras; @@ -435,9 +436,9 @@ public static IGH_Goo TryConvertItemToNative(object value, ISpeckleConverter con var converted = converter.ConvertToNative(@base); return WrapInGhType(converted); } - catch (Exception e) + catch (SpeckleException ex) { - converter.Report.ConversionErrors.Add(new Exception($"Could not convert {@base}", e)); + converter.Report.ConversionErrors.Add(new SpeckleException($"Could not convert {@base}", ex)); return null; } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Loader.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Loader.cs index bfe8118a4b..dc6c15ac58 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Loader.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Loader.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; using ConnectorGrasshopper.Extras; @@ -38,25 +37,28 @@ public class Loader : GH_AssemblyPriority public override GH_LoadingInstruction PriorityLoad() { - var version = HostApplications.Grasshopper.GetVersion(HostAppVersion.v6); - if (RhinoApp.Version.Major == 7) + string version = RhinoApp.Version.Major switch { - version = HostApplications.Grasshopper.GetVersion(HostAppVersion.v7); - } + 6 => HostApplications.Grasshopper.GetVersion(HostAppVersion.v6), + 7 => HostApplications.Grasshopper.GetVersion(HostAppVersion.v7), + 8 => HostApplications.Grasshopper.GetVersion(HostAppVersion.v8), + _ => throw new NotSupportedException($"Version {RhinoApp.Version.Major} of Rhino is not supported"), + }; - var logConfig = new SpeckleLogConfiguration(logToSentry: false); + const bool ENHANCED_LOG_CONTEXT = #if MAC - logConfig.enhancedLogContext = false; + false; +#else + true; #endif + var logConfig = new SpeckleLogConfiguration(logToSentry: false, enhancedLogContext: ENHANCED_LOG_CONTEXT); + SpeckleLog.Initialize(HostApplications.Grasshopper.Name, version, logConfig); try { - // Using reflection instead of calling `Setup.Init` to prevent loader from exploding. See comment on Catch clause. - typeof(Setup) - .GetMethod("Init", BindingFlags.Public | BindingFlags.Static) - .Invoke(null, new object[] { version, HostApplications.Grasshopper.Slug }); + Setup.Init(version, HostApplications.Grasshopper.Slug); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // This is here to ensure that other older versions of core (which did not have the Setup class) don't bork our connector initialisation. // The only way this can happen right now is if a 3rd party plugin includes the Core dll in their distribution (which they shouldn't ever do). @@ -143,7 +145,7 @@ private void OnDocumentEditorLoad(object sender, EventArgs e) var mainMenu = Instances.DocumentEditor.MainMenuStrip; AddSpeckleMenu(mainMenu); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { ShowLoadErrorMessageBox(); } @@ -266,7 +268,7 @@ private void AddSpeckleMenu(MenuStrip mainMenu) Process.Start(new ProcessStartInfo("https://speckle.systems/download") { UseShellExecute = true }); } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Fatal( ex, diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectByKeyValueV2TaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectByKeyValueV2TaskComponent.cs index 51ffd17198..ed78b5e805 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectByKeyValueV2TaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectByKeyValueV2TaskComponent.cs @@ -115,9 +115,9 @@ public Base DoWork(List keys, List values) speckleObj[key] = Converter != null ? Utilities.TryConvertItemToSpeckle(value, Converter) : value; } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, ex.ToFormattedString()); } } @@ -129,7 +129,7 @@ public Base DoWork(List keys, List values) return speckleObj; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectTaskComponent.cs index 66d853664f..e2b979b667 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/CreateSpeckleObjectTaskComponent.cs @@ -6,8 +6,6 @@ using ConnectorGrasshopper.Extras; using ConnectorGrasshopper.Properties; using Grasshopper.Kernel; -using Serilog.Context; -using Serilog.Core; using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; @@ -228,7 +226,7 @@ public async Task DoWork(Dictionary inputData) }) .ToList(); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Warning(ex, "Exception while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"{ex.ToFormattedString()}"); @@ -239,7 +237,7 @@ public async Task DoWork(Dictionary inputData) { @base[key] = converted; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Warning(ex, "Exception while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{ex.ToFormattedString()}"); @@ -261,7 +259,7 @@ public async Task DoWork(Dictionary inputData) @base[key] = value; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Warning(ex, "Exception while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{ex.ToFormattedString()}"); @@ -277,7 +275,7 @@ public async Task DoWork(Dictionary inputData) return @base; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/DeconstructSpeckleObjectTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/DeconstructSpeckleObjectTaskComponent.cs index 66c3991df8..8e34cb420f 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/DeconstructSpeckleObjectTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/DeconstructSpeckleObjectTaskComponent.cs @@ -329,7 +329,7 @@ protected override void BeforeSolveInstance() } } } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Failed to fetch outputs:\n\t{e.ToFormattedString()}"); } @@ -379,7 +379,7 @@ public Dictionary DoWork(Base @base) { return CreateOutputDictionary(@base); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/CreateSpeckleObjectByKeyValueTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/CreateSpeckleObjectByKeyValueTaskComponent.cs index b4e5bc4a3b..0201666e09 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/CreateSpeckleObjectByKeyValueTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/CreateSpeckleObjectByKeyValueTaskComponent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Threading.Tasks; using ConnectorGrasshopper.Extras; @@ -14,7 +15,8 @@ namespace ConnectorGrasshopper.Objects; -[Obsolete] +[Obsolete($"Use {nameof(CreateSpeckleObjectByKeyValueV2TaskComponent)}")] +[SuppressMessage("Design", "CA1031:Do not catch general exception types")] public class CreateSpeckleObjectByKeyValueTaskComponent : SelectKitTaskCapableComponentBase { public CreateSpeckleObjectByKeyValueTaskComponent() diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExpandSpeckleObjectTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExpandSpeckleObjectTaskComponent.cs index 9ecaaa02c5..8e51085412 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExpandSpeckleObjectTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExpandSpeckleObjectTaskComponent.cs @@ -365,7 +365,7 @@ public Dictionary DoWork(Base @base) { return CreateOutputDictionary(@base); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExtendSpeckleObjectByKeyValueTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExtendSpeckleObjectByKeyValueTaskComponent.cs index 522964150c..87ba9ee6ac 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExtendSpeckleObjectByKeyValueTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/Deprecated/ExtendSpeckleObjectByKeyValueTaskComponent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Threading.Tasks; using ConnectorGrasshopper.Extras; @@ -14,7 +15,8 @@ namespace ConnectorGrasshopper.Objects; -[Obsolete] +[Obsolete($"Use {nameof(ExtendSpeckleObjectByKeyValueV2TaskComponent)}")] +[SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Component is obsolete")] public class ExtendSpeckleObjectByKeyValueTaskComponent : SelectKitTaskCapableComponentBase { public ExtendSpeckleObjectByKeyValueTaskComponent() diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectByKeyValueV2TaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectByKeyValueV2TaskComponent.cs index e03b358f34..a27909f606 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectByKeyValueV2TaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectByKeyValueV2TaskComponent.cs @@ -173,9 +173,9 @@ public Base DoWork(object inputObj, List keys, List values) @base[key] = Converter != null ? Utilities.TryConvertItemToSpeckle(value, Converter) : value; } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, ex.ToFormattedString()); hasErrors = true; } } @@ -187,7 +187,7 @@ public Base DoWork(object inputObj, List keys, List values) return @base; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectTaskComponent.cs index bed085ef7b..2fe0e18e8c 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/ExtendSpeckleObjectTaskComponent.cs @@ -300,7 +300,7 @@ public Base DoWork(Base @base, Dictionary inputData) }) .ToList(); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Error(ex, "Exception while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"{ex.ToFormattedString()}"); @@ -311,7 +311,7 @@ public Base DoWork(Base @base, Dictionary inputData) { @base[key] = converted; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Error(ex, "Exception while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{ex.ToFormattedString()}"); @@ -333,7 +333,7 @@ public Base DoWork(Base @base, Dictionary inputData) @base[key] = value; } } - catch (Exception ex) + catch (SpeckleException ex) { SpeckleLog.Logger.Warning(ex, "Failed while creating speckle object"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{ex.ToFormattedString()}"); @@ -347,7 +347,7 @@ public Base DoWork(Base @base, Dictionary inputData) @base = null; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/GetObjectValueByKeyTaskComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/GetObjectValueByKeyTaskComponent.cs index 36be6b75c9..68c7e31af9 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/GetObjectValueByKeyTaskComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Objects/GetObjectValueByKeyTaskComponent.cs @@ -138,7 +138,7 @@ private object DoWork(Base @base, string key, CancellationToken token) break; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponent.cs index 9e3d21acaf..6e535cd975 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading; @@ -30,6 +31,7 @@ namespace ConnectorGrasshopper.Ops; +[Obsolete($"Use {nameof(VariableInputReceiveComponent)}")] public class ReceiveComponent : SelectKitAsyncComponentBase { public GH_Structure PrevReceivedData; @@ -473,6 +475,11 @@ private void ApiClient_OnCommitCreated(object sender, CommitInfo e) } } +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class ReceiveComponentWorker : WorkerInstance { private GH_Structure DataInput; @@ -541,9 +548,10 @@ public override void DoWork(Action ReportProgress, Action Done) { client = new Client(InputWrapper?.GetAccount().Result); } - catch (Exception e) + catch (Exception ex) { - RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, e.ToFormattedString())); + SpeckleLog.Logger.Warning(ex, "Failed to get speckle client"); + RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, ex.ToFormattedString())); Done(); return; } @@ -618,7 +626,7 @@ await client.CommitReceived( } ); } - catch + catch (Exception) { // Do nothing! } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponentSync.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponentSync.cs index db1c14ed00..5b34b89181 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponentSync.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.ReceiveComponentSync.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Threading; using System.Threading.Tasks; @@ -20,6 +21,12 @@ namespace ConnectorGrasshopper.Ops.Deprecated; +[Obsolete($"Use {nameof(SyncReceiveComponent)}")] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class ReceiveSync : SelectKitTaskCapableComponentBase { private const int delay = 100000; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponent.cs index b8647b052b..c160861f57 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -273,6 +274,11 @@ public override void DocumentContextChanged(GH_Document document, GH_DocumentCon } } +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class SendComponentWorker : WorkerInstance { private GH_Structure _MessageInput; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponentSync.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponentSync.cs index 1dc6bee8b0..8ab545b007 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponentSync.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.SendComponentSync.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading; @@ -21,6 +22,12 @@ namespace ConnectorGrasshopper.Ops.Deprecated; +[Obsolete($"Use {nameof(SyncSendComponent)}")] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class SendComponentSync : GH_SpeckleTaskCapableComponent> { private const int delay = 100000; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.VariableInputSendComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.VariableInputSendComponent.cs index 391f278e10..7dfba45788 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.VariableInputSendComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Deprecated/Operations.VariableInputSendComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -337,6 +338,11 @@ public override void AddedToDocument(GH_Document document) } } +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class VariableInputSendComponentWorker : WorkerInstance { private GH_Structure _MessageInput; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.ReceiveLocalComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.ReceiveLocalComponent.cs index 6dc660377f..dce6084b5d 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.ReceiveLocalComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.ReceiveLocalComponent.cs @@ -108,7 +108,7 @@ private void SetDefaultKitAndConverter() Converter.SetContextDocument(Loader.GetCurrentDocument()); foundKit = true; } - catch + catch (Exception e) when (!e.IsFatal()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No default kit found on this machine."); foundKit = false; @@ -158,7 +158,7 @@ public override void DoWork(Action ReportProgress, Action Done) { @base = Operations.Receive(localDataId, disposeTransports: true).Result; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, "Failed to receive local data.")); Done(); @@ -167,7 +167,7 @@ public override void DoWork(Action ReportProgress, Action Done) data = Utilities.ConvertToTree(Converter, @base, Parent.AddRuntimeMessage); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SendLocalComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SendLocalComponent.cs index 4758799d80..f4d3064132 100755 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SendLocalComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SendLocalComponent.cs @@ -9,6 +9,7 @@ using GrasshopperAsyncComponent; using Speckle.Core.Api; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; using Utilities = ConnectorGrasshopper.Extras.Utilities; @@ -85,12 +86,12 @@ public override void DoWork(Action ReportProgress, Action Done) var converted = Utilities.DataTreeToNestedLists(data, converter); var ObjectToSend = new Base(); ObjectToSend["@data"] = converted; - sentObjectId = Operations.Send(ObjectToSend, disposeTransports: true).Result; + sentObjectId = Operations.Send(ObjectToSend).Result; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - Console.WriteLine(e); - RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, e.ToFormattedString())); + SpeckleLog.Logger.Error(ex, "Local send failed"); + RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, ex.ToFormattedString())); } Done(); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncReceiveComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncReceiveComponent.cs index ce15a8adc1..e4652eb5e0 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncReceiveComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncReceiveComponent.cs @@ -13,6 +13,7 @@ using Speckle.Core.Api.SubscriptionModels; using Speckle.Core.Credentials; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Transports; using Utilities = ConnectorGrasshopper.Extras.Utilities; @@ -233,20 +234,19 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) var task = Task.Run( async () => { - var acc = await StreamWrapper?.GetAccount(); + if (StreamWrapper == null) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Input cannot be null"); + return null; + } + + var acc = await StreamWrapper.GetAccount().ConfigureAwait(false); var client = new Client(acc); - var remoteTransport = new ServerTransport(acc, StreamWrapper?.StreamId); - remoteTransport.TransportName = "R"; + var remoteTransport = new ServerTransport(acc, StreamWrapper.StreamId) { TransportName = "R" }; - var myCommit = await ReceiveComponentWorker.GetCommit( - StreamWrapper, - client, - (level, message) => - { - AddRuntimeMessage(level, message); - }, - CancelToken - ); + var myCommit = await ReceiveComponentWorker + .GetCommit(StreamWrapper, client, AddRuntimeMessage, CancelToken) + .ConfigureAwait(false); if (myCommit == null) { @@ -266,9 +266,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) } ); - var TotalObjectCount = 1; + var totalObjectCount = 1; - var ReceivedObject = Operations + var receivedObject = Operations .Receive( myCommit.referencedObject, CancelToken, @@ -276,29 +276,31 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) new SQLiteTransport { TransportName = "LC" }, // Local cache! null, null, - count => TotalObjectCount = count, + count => totalObjectCount = count, true ) .Result; try { - await client.CommitReceived( - new CommitReceivedInput - { - streamId = StreamWrapper.StreamId, - commitId = myCommit.id, - message = myCommit.message, - sourceApplication = Utilities.GetVersionedAppName() - } - ); + await client + .CommitReceived( + new CommitReceivedInput + { + streamId = StreamWrapper.StreamId, + commitId = myCommit.id, + message = myCommit.message, + sourceApplication = Utilities.GetVersionedAppName() + } + ) + .ConfigureAwait(false); } - catch + catch (Exception e) when (!e.IsFatal()) { - // Do nothing! + SpeckleLog.Logger.Error(e, "CommitReceived failed after send."); } - return ReceivedObject; + return receivedObject; }, CancelToken ); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncSendComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncSendComponent.cs index b560cc2a22..7ccbcb324d 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncSendComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.SyncSendComponent.cs @@ -13,6 +13,7 @@ using Grasshopper.Kernel.Types; using Speckle.Core.Api; using Speckle.Core.Credentials; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; using Speckle.Core.Transports; @@ -182,7 +183,7 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) { transport = new StreamWrapper(s); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { // TODO: Check this with team. AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.ToFormattedString()); @@ -209,8 +210,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) { acc = sw.GetAccount().Result; } - catch (Exception e) + catch (SpeckleException e) { + SpeckleLog.Logger.Warning(e, "Failed to get account from stream wrapper"); AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.ToFormattedString()); continue; } @@ -248,15 +250,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) } // Part 3.1: persist the objects - var BaseId = await Operations.Send( - objectToSend, - CancelToken, - transports, - UseDefaultCache, - y => { }, - (x, z) => { }, - true - ); + var BaseId = await Operations + .Send(objectToSend, CancelToken, transports, UseDefaultCache, y => { }, (x, z) => { }, true) + .ConfigureAwait(false); var message = messageInput; //.get_FirstItem(true).Value; if (message == "") @@ -309,8 +305,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) ); prevCommits.Add(wrapper); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Warning(e, "Failed to send synchronously"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); return null; } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputReceiveComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputReceiveComponent.cs index 1fab11f6b3..ce1a78b883 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputReceiveComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputReceiveComponent.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Drawing; using System.Linq; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Timers; @@ -536,10 +537,10 @@ public async Task ResetApiClient(StreamWrapper wrapper) { try { - var hasInternet = await Http.UserHasInternet(); + var hasInternet = await Http.UserHasInternet().ConfigureAwait(false); if (!hasInternet) { - throw new Exception("You are not connected to the internet."); + throw new HttpRequestException("You are not connected to the internet."); } Account account; @@ -547,13 +548,15 @@ public async Task ResetApiClient(StreamWrapper wrapper) { account = wrapper?.GetAccount().Result; } - catch (Exception e) + catch (SpeckleException e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.ToFormattedString()); account = new Account { id = wrapper?.StreamId, - serverInfo = new ServerInfo { url = wrapper?.ServerUrl }, + serverInfo = wrapper?.ServerUrl is not null + ? await AccountManager.GetServerInfo(new Uri(wrapper.ServerUrl)).ConfigureAwait(false) + : new(), token = "", refreshToken = "" }; @@ -564,8 +567,9 @@ public async Task ResetApiClient(StreamWrapper wrapper) ApiClient.SubscribeCommitCreated(StreamWrapper.StreamId); ApiClient.OnCommitCreated += ApiClient_OnCommitCreated; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Error(e, "Failed to reset API client"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); } } @@ -743,7 +747,7 @@ await receiveComponent.ApiClient.CommitReceived( } ); } - catch + catch (Exception ex) when (!ex.IsFatal()) { // Do nothing! } @@ -762,7 +766,7 @@ await receiveComponent.ApiClient.CommitReceived( }); t.Wait(); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); @@ -795,7 +799,7 @@ CancellationToken CancellationToken return myCommit; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { OnFail(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); return null; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputSendComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputSendComponent.cs index 0c6fccab83..cc4d4339e6 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputSendComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Ops/Operations.VariableInputSendComponent.cs @@ -470,7 +470,7 @@ public override void DoWork(Action ReportProgress, Action Done) ObjectToSend[key] = converted; TotalObjectCount += ObjectToSend.GetTotalChildrenCount(); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { RuntimeMessages.Add((GH_RuntimeMessageLevel.Error, e.ToFormattedString())); Done(); @@ -516,7 +516,7 @@ public override void DoWork(Action ReportProgress, Action Done) { transport = new StreamWrapper(s); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { // TODO: Check this with team. RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, e.ToFormattedString())); @@ -548,7 +548,7 @@ public override void DoWork(Action ReportProgress, Action Done) { acc = sw.GetAccount().Result; } - catch (Exception e) + catch (SpeckleException e) { RuntimeMessages.Add((GH_RuntimeMessageLevel.Warning, e.ToFormattedString())); continue; @@ -634,7 +634,7 @@ public override void DoWork(Action ReportProgress, Action Done) true ); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { ErrorAction("S", e); return; @@ -689,11 +689,17 @@ public override void DoWork(Action ReportProgress, Action Done) var commitId = await client.CommitCreate(commitCreateInput, CancellationToken); var wrapper = new StreamWrapper( - $"{client.Account.serverInfo.url}/streams/{((ServerTransport)transport).StreamId}/commits/{commitId}?u={client.Account.userInfo.id}" + ((ServerTransport)transport).StreamId, + client.Account.userInfo.id, + client.Account.serverInfo.url ); + wrapper.CommitId = commitId; + wrapper.BranchName = branch; + wrapper.SetAccount(client.Account); + OutputWrappers.Add(wrapper); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { ErrorAction.Invoke("Commits", e); } @@ -710,7 +716,7 @@ public override void DoWork(Action ReportProgress, Action Done) CancellationToken ); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { // If we reach this, something happened that we weren't expecting... SpeckleLog.Logger.Error(ex, "Failed during execution of {componentName}", this.GetType()); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObject.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObject.cs index 8b0591e185..fc9ecae967 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObject.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObject.cs @@ -109,7 +109,11 @@ public override void AppendAdditionalMenuItems(ToolStripDropDown menu) .Any(o => o.AttributeType.IsEquivalentTo(typeof(SchemaMainParam))) ); } - catch (Exception e) { } + catch (Exception ex) when (!ex.IsFatal()) + { + // Above code needs refactoring to have more granular exceptions thrown and documented. + SpeckleLog.Logger.Error(ex, "Failed to obtain main param for constructor {}", SelectedConstructor.Name); + } var objectItem = schemaConversionHeader.DropDownItems.Add("Convert as Schema object.") as ToolStripMenuItem; objectItem.Checked = !UseSchemaTag; @@ -343,34 +347,26 @@ public static GH_ValueList CreateDropDown(string name, List<(string name, int va public override bool Read(GH_IReader reader) { + var constructorName = reader.GetString("SelectedConstructorName"); + var typeName = reader.GetString("SelectedTypeName"); + + reader.TryGetBoolean("UseSchemaTag", ref UseSchemaTag); + reader.TryGetBoolean("UserSetSchemaTag", ref UserSetSchemaTag); + reader.TryGetString("seed", ref Seed); + try { - var constructorName = reader.GetString("SelectedConstructorName"); - var typeName = reader.GetString("SelectedTypeName"); - try - { - UseSchemaTag = reader.GetBoolean("UseSchemaTag"); - UserSetSchemaTag = reader.GetBoolean("UserSetSchemaTag"); - } - catch { } - SelectedConstructor = CSOUtils.FindConstructor(constructorName, typeName); if (SelectedConstructor == null) { readFailed = true; } } - catch + catch (Exception ex) when (!ex.IsFatal()) { readFailed = true; } - try - { - Seed = reader.GetString("seed"); - } - catch { } - return base.Read(reader); } @@ -444,12 +440,13 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) try { - inputValues = inputValues.Select(x => ExtractRealInputValue(x)).ToList(); + inputValues = inputValues.Select(ExtractRealInputValue).ToList(); objectProp = GetObjectListProp(param, inputValues, cParam.ParameterType); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); + SpeckleLog.Logger.Error(ex, "Failed to get object property list"); + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, ex.ToFormattedString()); return; } } @@ -480,8 +477,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) ((Base)schemaObject).applicationId = $"{Seed}-{SelectedConstructor.DeclaringType.FullName}-{DA.Iteration}"; ((Base)schemaObject)["units"] = units; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Error(e, "Failed to obtain create object from constructor"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); return; } @@ -491,21 +489,21 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) if (UseSchemaTag) { commitObj = commitObj.ShallowCopy(); - try - { - if (mainSchemaObj == null) - { - UseSchemaTag = false; - throw new Exception("Schema tag is not supported for this object type, will return Schema object instead."); - } + if (mainSchemaObj != null) + { commitObj = ((Base)mainSchemaObj).ShallowCopy(); commitObj["@SpeckleSchema"] = schemaObject; commitObj["units"] = units; } - catch (Exception e) + else { - AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, e.ToFormattedString()); + UseSchemaTag = false; + ((SpeckleBaseParam)Params.Output[0]).UseSchemaTag = UseSchemaTag; + AddRuntimeMessage( + GH_RuntimeMessageLevel.Remark, + "Schema tag is not supported for this object type, will return Schema object instead." + ); } } @@ -582,7 +580,7 @@ private object ConvertType(Type type, object value, string name) } var typeOfValue = value.GetType(); - if (value == null || typeOfValue == type || type.IsAssignableFrom(typeOfValue)) + if (typeOfValue == type || type.IsAssignableFrom(typeOfValue)) { return value; } @@ -594,7 +592,10 @@ private object ConvertType(Type type, object value, string name) { return Enum.Parse(type, value.ToString()); } - catch { } + catch (Exception e) when (e is ArgumentException or OverflowException) + { + SpeckleLog.Logger.Error(e, "Failed to parse enum value"); + } } // int, doubles, etc @@ -604,9 +605,9 @@ private object ConvertType(Type type, object value, string name) { return Convert.ChangeType(value, type); } - catch (Exception e) + catch (Exception ex) when (ex is FormatException or OverflowException or InvalidCastException) { - throw new Exception($"Cannot convert {value.GetType()} to {type}"); + throw new SpeckleException($"Cannot convert {value.GetType()} to {type}", ex); } } @@ -623,9 +624,10 @@ private object ConvertType(Type type, object value, string name) { return Convert.ChangeType(converted, type); } - catch (Exception e) + catch (Exception ex) + when (ex is InvalidCastException or FormatException or OverflowException or ArgumentNullException) { - throw new Exception($"Cannot convert {converted.GetType()} to {type}"); + throw new SpeckleException($"Cannot convert {converted.GetType()} to {type}", ex); } } @@ -640,7 +642,10 @@ private object ConvertType(Type type, object value, string name) MethodInfo castIntoMethod = GetType().GetMethod("CastObject").MakeGenericMethod(type); return castIntoMethod.Invoke(null, new[] { value }); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Failed to cast type"); + } AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to set " + name + "."); throw new SpeckleException($"Could not covert object to {type}"); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectBase.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectBase.cs index 0fbeac8b56..83897b862c 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectBase.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectBase.cs @@ -12,7 +12,6 @@ using GH_IO.Serialization; using Grasshopper; using Grasshopper.Kernel; -using Grasshopper.Kernel.Special; using Grasshopper.Kernel.Types; using Speckle.Core.Kits; using Speckle.Core.Logging; @@ -99,7 +98,11 @@ public override void AppendAdditionalMenuItems(ToolStripDropDown menu) ?.Count() > 0 ); } - catch (Exception e) { } + catch (Exception ex) when (!ex.IsFatal()) + { + // Above code needs refactoring to have more granular exceptions thrown and documented. + SpeckleLog.Logger.Error(ex, "Failed to obtain main param for constructor {}", SelectedConstructor.Name); + } var objectItem = schemaConversionHeader.DropDownItems.Add("Convert as Schema object.") as ToolStripMenuItem; objectItem.Checked = !UseSchemaTag; @@ -141,34 +144,26 @@ public string GenerateSeed() public override bool Read(GH_IReader reader) { + var constructorName = reader.GetString("SelectedConstructorName"); + var typeName = reader.GetString("SelectedTypeName"); + + reader.TryGetBoolean("UseSchemaTag", ref UseSchemaTag); + reader.TryGetBoolean("UserSetSchemaTag", ref UserSetSchemaTag); + reader.TryGetString("seed", ref Seed); + try { - var constructorName = reader.GetString("SelectedConstructorName"); - var typeName = reader.GetString("SelectedTypeName"); - try - { - UseSchemaTag = reader.GetBoolean("UseSchemaTag"); - UserSetSchemaTag = reader.GetBoolean("UserSetSchemaTag"); - } - catch { } - SelectedConstructor = CSOUtils.FindConstructor(constructorName, typeName); if (SelectedConstructor == null) { readFailed = true; } } - catch + catch (Exception ex) when (!ex.IsFatal()) { readFailed = true; } - try - { - Seed = reader.GetString("seed"); - } - catch { } - return base.Read(reader); } @@ -407,10 +402,10 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) try { - inputValues = inputValues.Select(x => ExtractRealInputValue(x)).ToList(); + inputValues = inputValues.Select(ExtractRealInputValue).ToList(); objectProp = GetObjectListProp(param, inputValues, cParam.ParameterType); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); return; @@ -446,8 +441,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) ((Base)schemaObject)["units"] = units; } } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Error(e, "Failed to obtain create object from constructor"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToFormattedString()); return; } @@ -457,15 +453,8 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) if (UseSchemaTag) { commitObj = commitObj.ShallowCopy(); - try + if (mainSchemaObj != null) { - if (mainSchemaObj == null) - { - UseSchemaTag = false; - ((SpeckleBaseParam)Params.Output[0]).UseSchemaTag = UseSchemaTag; - throw new Exception("Schema tag is not supported for this object type, will return Schema object instead."); - } - commitObj = ((Base)mainSchemaObj).ShallowCopy(); commitObj["@SpeckleSchema"] = schemaObject; if (commitObj["units"] == null || commitObj["units"] == "") @@ -473,9 +462,14 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) commitObj["units"] = units; } } - catch (Exception e) + else { - AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, e.ToFormattedString()); + UseSchemaTag = false; + ((SpeckleBaseParam)Params.Output[0]).UseSchemaTag = UseSchemaTag; + AddRuntimeMessage( + GH_RuntimeMessageLevel.Remark, + "Schema tag is not supported for this object type, will return Schema object instead." + ); } } @@ -552,7 +546,7 @@ private object ConvertType(Type type, object value, string name) } var typeOfValue = value.GetType(); - if (value == null || typeOfValue == type || type.IsAssignableFrom(typeOfValue)) + if (typeOfValue == type || type.IsAssignableFrom(typeOfValue)) { return value; } @@ -564,7 +558,10 @@ private object ConvertType(Type type, object value, string name) { return Enum.Parse(type, value.ToString()); } - catch { } + catch (Exception e) when (e is ArgumentException or OverflowException) + { + SpeckleLog.Logger.Error(e, "Failed to parse enum value"); + } } // int, doubles, etc @@ -574,9 +571,9 @@ private object ConvertType(Type type, object value, string name) { return Convert.ChangeType(value, type); } - catch (Exception e) + catch (Exception ex) when (ex is InvalidCastException or FormatException or OverflowException) { - throw new Exception($"Cannot convert {value.GetType()} to {type}"); + throw new SpeckleException($"Cannot convert {value.GetType()} to {type}", ex); } } @@ -593,9 +590,10 @@ private object ConvertType(Type type, object value, string name) { return Convert.ChangeType(converted, type); } - catch (Exception e) + catch (Exception ex) + when (ex is InvalidCastException or FormatException or OverflowException or ArgumentNullException) { - throw new Exception($"Cannot convert {converted.GetType()} to {type}"); + throw new SpeckleException($"Cannot convert {converted.GetType()} to {type}", ex); } } @@ -610,7 +608,10 @@ private object ConvertType(Type type, object value, string name) MethodInfo castIntoMethod = GetType().GetMethod("CastObject").MakeGenericMethod(type); return castIntoMethod.Invoke(null, new[] { value }); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error(ex, "Failed to cast type"); + } AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to set " + name + "."); throw new SpeckleException($"Could not covert object to {type}"); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectDialog.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectDialog.cs index 9d0f8e8ba2..0bb4bc70e9 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectDialog.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/CreateSchemaObjectDialog.cs @@ -6,6 +6,7 @@ using Eto.Drawing; using Eto.Forms; using Speckle.Core.Kits; +using Speckle.Core.Logging; namespace ConnectorGrasshopper; @@ -139,9 +140,11 @@ private void RecurseNamespace(string[] ns, Dictionary tree, Type ((Dictionary)tree[key])[t.Name] = constructors.Values.First(); } } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { - Console.WriteLine(e); + // We do not know what specific failure this will cause yet, requires further investigation and + // potentially a refactor of CSOUtils to throw more explicitly. + SpeckleLog.Logger.Warning(e, "Failed to get valid constructors for type {t}", t); } } } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/SchemaBuilderGen.tt b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/SchemaBuilderGen.tt index fb1d5f3596..55816b3678 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/SchemaBuilderGen.tt +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/SchemaBuilder/SchemaBuilderGen.tt @@ -5,8 +5,6 @@ <#@ assembly name="..\ConnectorGrasshopperUtils\bin\ConnectorGrasshopperUtils.dll" #> <#@ import namespace="System.Text" #> <#@ import namespace="System" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="ConnectorGrasshopperUtils" #> <# var allTypes = CSOUtils.ListAvailableTypes(); diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamCreateComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamCreateComponent.cs index abbaaf9b2b..ccdd157b1a 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamCreateComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamCreateComponent.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -15,6 +16,11 @@ namespace ConnectorGrasshopper.Streams; [Obsolete] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class StreamCreateComponent : GH_SpeckleComponent { public StreamCreateComponent() diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamDetailsComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamDetailsComponent.cs index 0d4884f3a4..67ed396806 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamDetailsComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamDetailsComponent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -16,6 +17,11 @@ namespace ConnectorGrasshopper.Streams; [Obsolete] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class StreamDetailsComponent : GH_SpeckleComponent { private Exception error; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamGetComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamGetComponent.cs index 806813b2e0..faaafdd185 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamGetComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamGetComponent.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -12,6 +13,11 @@ namespace ConnectorGrasshopper.Streams; [Obsolete] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class StreamGetComponent : GH_SpeckleComponent { private Exception error; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamListComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamListComponent.cs index 6e2918679e..8108c8730a 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamListComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamListComponent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Threading.Tasks; @@ -16,6 +17,11 @@ namespace ConnectorGrasshopper.Streams; [Obsolete] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class StreamListComponent : GH_SpeckleComponent { private Exception error; @@ -99,7 +105,7 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) Task.Run(async () => { - if (!await Http.UserHasInternet()) + if (!await Http.UserHasInternet().ConfigureAwait(false)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "You are not connected to the internet"); Message = "Error"; @@ -109,14 +115,14 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) { var client = new Client(account); // Save the result - var result = await client.StreamsGet(limit); + var result = await client.StreamsGet(limit).ConfigureAwait(false); streams = result .Select(stream => new StreamWrapper(stream.id, account.userInfo.id, account.serverInfo.url)) .ToList(); } - catch (Exception e) + catch (Exception ex) { - error = e; + error = ex; } finally { diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamUpdateComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamUpdateComponent.cs index 3f509ebee5..f6685e01e6 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamUpdateComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/Deprecated/StreamUpdateComponent.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Threading.Tasks; using ConnectorGrasshopper.Extras; @@ -11,6 +12,11 @@ namespace ConnectorGrasshopper.Streams; [Obsolete] +[SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Class is used by obsolete component" +)] public class StreamUpdateComponent : GH_SpeckleComponent { private Exception error; @@ -100,7 +106,7 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) var account = streamWrapper.GetAccount().Result; var client = new Client(account); var input = new StreamUpdateInput(); - stream = await client.StreamGet(streamWrapper.StreamId); + stream = await client.StreamGet(streamWrapper.StreamId).ConfigureAwait(false); input.id = streamWrapper.StreamId; input.name = name ?? stream.name; @@ -111,9 +117,9 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) input.isPublic = isPublic; } - await client.StreamUpdate(input); + await client.StreamUpdate(input).ConfigureAwait(false); } - catch (Exception e) + catch (SpeckleGraphQLException e) { error = e; } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetComponentV2.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetComponentV2.cs index 969983d771..eb727c475d 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetComponentV2.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetComponentV2.cs @@ -1,10 +1,12 @@ using System; using System.Drawing; +using System.Net.Http; using System.Threading.Tasks; using ConnectorGrasshopper.Extras; using ConnectorGrasshopper.Properties; using Grasshopper.Kernel; using Speckle.Core.Credentials; +using Speckle.Core.Logging; namespace ConnectorGrasshopper.Streams; @@ -90,7 +92,7 @@ private async Task AssignAccountToStream(StreamWrapper idWrapper, { await newWrapper.ValidateWithAccount(account).ConfigureAwait(false); // Validates the stream } - catch (Exception e) + catch (Exception e) when (e is SpeckleException or HttpRequestException or ArgumentException) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message); return null; diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetWithTokenComponent.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetWithTokenComponent.cs index 1da4902f9a..8fdd046435 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetWithTokenComponent.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamGetWithTokenComponent.cs @@ -6,7 +6,6 @@ using ConnectorGrasshopper.Properties; using Grasshopper; using Grasshopper.Kernel; -using Speckle.Core.Api; using Speckle.Core.Credentials; namespace ConnectorGrasshopper.Accounts; @@ -88,10 +87,15 @@ protected override void SolveInstance(IGH_DataAccess DA) var task = Task.Run( () => { - var acc = new Account(); - acc.token = token; - acc.serverInfo = new ServerInfo { url = sw.ServerUrl }; - acc.userInfo = acc.Validate().Result; + Uri serverUrl = new(sw.ServerUrl); + Account acc = + new() + { + token = token, + serverInfo = AccountManager.GetServerInfo(serverUrl).Result, + userInfo = AccountManager.GetUserInfo(token, serverUrl).Result + }; + sw.SetAccount(acc); return sw; }, diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamListComponentV2.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamListComponentV2.cs index d9d905578c..0adc7ecceb 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamListComponentV2.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Streams/StreamListComponentV2.cs @@ -92,10 +92,15 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) private Task> ListStreams(Account account, int limit) { - var client = new Client(account); + using var client = new Client(account); var res = client .StreamsGet(limit, CancelToken) - .Result.Select(stream => new StreamWrapper(stream.id, account.userInfo.id, account.serverInfo.url)) + .Result.Select(stream => + { + var s = new StreamWrapper(stream.id, account.userInfo.id, account.serverInfo.url); + s.SetAccount(account); + return s; + }) .ToList(); return Task.FromResult(res); } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperShared/Transports/Transports.Disk.cs b/ConnectorGrasshopper/ConnectorGrasshopperShared/Transports/Transports.Disk.cs index a24a21686e..d9751c226f 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperShared/Transports/Transports.Disk.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperShared/Transports/Transports.Disk.cs @@ -4,6 +4,7 @@ using ConnectorGrasshopper.Properties; using Grasshopper; using Grasshopper.Kernel; +using Speckle.Core.Transports; namespace ConnectorGrasshopper.Transports; @@ -83,7 +84,7 @@ public override void SolveInstanceWithLogContext(IGH_DataAccess DA) string basePath = null; DA.GetData(0, ref basePath); - var myTransport = new DiskTransport.DiskTransport(basePath); + var myTransport = new DiskTransport(basePath); DA.SetData(0, myTransport); } diff --git a/ConnectorGrasshopper/ConnectorGrasshopperUtils/ConnectorGrasshopperUtils.csproj b/ConnectorGrasshopper/ConnectorGrasshopperUtils/ConnectorGrasshopperUtils.csproj index c9ab70a53c..1da71c5e0e 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperUtils/ConnectorGrasshopperUtils.csproj +++ b/ConnectorGrasshopper/ConnectorGrasshopperUtils/ConnectorGrasshopperUtils.csproj @@ -1,12 +1,15 @@ - net462 + net462;net7.0 ConnectorGrasshopperUtils - false none - + + + + + diff --git a/ConnectorGrasshopper/ConnectorGrasshopperUtils/UserInterfaceUtils.cs b/ConnectorGrasshopper/ConnectorGrasshopperUtils/UserInterfaceUtils.cs index 3df45670dc..0cf8491a07 100644 --- a/ConnectorGrasshopper/ConnectorGrasshopperUtils/UserInterfaceUtils.cs +++ b/ConnectorGrasshopper/ConnectorGrasshopperUtils/UserInterfaceUtils.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Reflection; diff --git a/ConnectorNavisworks/ConnectorNavisworks.slnf b/ConnectorNavisworks/ConnectorNavisworks.slnf index 3395c52e83..2c01f7e4d5 100644 --- a/ConnectorNavisworks/ConnectorNavisworks.slnf +++ b/ConnectorNavisworks/ConnectorNavisworks.slnf @@ -20,7 +20,7 @@ "DesktopUI2\\AvaloniaHwndHost\\AvaloniaHwndHost.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", - "Objects\\Objects\\Objects.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Events.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Events.cs index 10b076e43c..5e08d4d426 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Events.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Events.cs @@ -8,46 +8,122 @@ namespace Speckle.ConnectorNavisworks.Bindings; public partial class ConnectorBindingsNavisworks { + /// + /// Registers global event handlers for the application. + /// + /// + /// This method sets up event handlers for various events related to the Navisworks document. + /// Navisworks operates as a Single Document Interface (SDI) and initially opens with an empty document. + /// Unlike other interfaces, loading a file in Navisworks does not trigger an ActiveDocumentChanged event, + /// but rather modifies the existing document in place. This method listens for the filename change event + /// to capture the intuitive document change event. It also registers event handlers for changes in selection sets + /// and changes in the model collection. + /// public void RegisterAppEvents() { - //// GLOBAL EVENT HANDLERS - - // Navisworks is an SDI (Single Document Interface) and on launch has an initial empty document. - // Loading a file doesn't trigger the ActiveDocumentChanged event. - // Instead it amends it in place. We can listen to the filename changing to get the intuitive event. - _doc.FileNameChanged += DocumentChangedEvent; - _doc.SelectionSets.Changed += SetsChangedEvent; + // Register event handlers for document, selection sets, and model collection changes + s_doc.FileNameChanged += DocumentChangedEvent; + s_doc.SelectionSets.Changed += SetsChangedEvent; + s_doc.Models.CollectionChanged += ModelsChangedEvent; } - private void SetsChangedEvent(object sender, EventArgs e) - { - UpdateSelectedStream?.Invoke(); - } + /// + /// Handles the event triggered when the selection sets are changed. + /// + /// The source of the event. + /// The event data. Not used in this handler. + private void SetsChangedEvent(object sender, EventArgs e) => UpdateSelectedStream?.Invoke(); - // Triggered when the active document name is changed. - // This will happen automatically if a document is newly created or opened. + /// + /// Handles the event triggered when the active document name changes. + /// + /// The source of the event, expected to be of type Document. + /// Event data associated with the document change event. + /// + /// This method is called automatically when a document is newly created or opened, + /// resulting in a change in the active document name. It first verifies if the sender + /// is a valid and non-clear Document using the IsInvalidOrClearDocument method. If the sender + /// is valid, the method updates the saved streams, navigates the MainViewModel to home, + /// retrieves streams from the file, updates the selected stream, and sets the context + /// document in the Navisworks converter, followed by nullifying the commit cache. + /// private void DocumentChangedEvent(object sender, EventArgs e) { - // As ConnectorNavisworks is Send only, There is little use for a new empty document. - if (sender is not Document doc || doc.IsClear) + if (IsInvalidOrClearDocument(sender)) { - UpdateSavedStreams?.Invoke(new List()); - MainViewModel.GoHome(); return; } + // Safely cast sender to Document now that we know it's not null or clear. + Document doc = sender as Document; + + UpdateSavedStreams?.Invoke(new List()); + MainViewModel.GoHome(); + var streams = GetStreamsInFile(); UpdateSavedStreams?.Invoke(streams); - UpdateSelectedStream?.Invoke(); - MainViewModel.GoHome(); _navisworksConverter.SetContextDocument(doc); - // Nullify any cached commit and conversions - _cachedCommit = null; + NullifyCommitCache(); + } + + /// + /// Handles the event triggered when the models change. + /// + /// The source of the event, expected to be of type Document. + /// The event data. Not used in this handler. + /// + /// Any change in the Models collection of the Document will require the recalculation of the context document. + /// Particularly important in the establishment of a changed up direction which can occur. + /// + private void ModelsChangedEvent(object sender, EventArgs e) + { + if (IsInvalidOrClearDocument(sender)) + { + return; + } + + // Safely cast sender to Document now that we know it's not null or clear. + Document doc = sender as Document; + _navisworksConverter.SetContextDocument(doc); + + NullifyCommitCache(); + } + + /// + /// Evaluates if the sender object from an event handler is a valid Document. + /// + /// The sender object, expected to be of type Document. + /// + /// Returns true if the sender is either not a Document or is a Document marked as clear. + /// This indicates that the sender object is an invalid Document and the event handler + /// should terminate further processing. + /// Returns false if the sender is a valid, non-clear Document, suggesting that the event + /// handler should continue its processing. + /// + /// + /// This method checks the sender object to determine if it is a valid Document (not null + /// and not marked as clear). If the sender fails this check, the method proceeds to invoke + /// UpdateSavedStreams with a new list of StreamState and navigates the MainViewModel to home, + /// then returns true, signifying the sender as an invalid Document. Otherwise, it returns false, + /// allowing the caller to continue processing. + /// + private static bool IsInvalidOrClearDocument(object sender) => sender is not Document { IsClear: false }; + + /// + /// Nullifies the commit cache. + /// + /// + /// This method resets the static fields related to the commit cache to null. + /// Any changes to the host document will invalidate the cache, so it needs to be reset. + /// + private static void NullifyCommitCache() + { + s_cachedCommit = null; CachedConvertedElements = null; - _cachedState = null; + s_cachedState = null; } } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.File.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.File.cs index ac131b6d84..53edb2ffad 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.File.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.File.cs @@ -11,10 +11,8 @@ public partial class ConnectorBindingsNavisworks /// Writes the list of stream states to the file. /// /// The list of stream states to write. - public override void WriteStreamsToFile(List streams) - { - SpeckleStreamManager.WriteStreamStateList(_doc, streams); - } + public override void WriteStreamsToFile(List streams) => + SpeckleStreamManager.WriteStreamStateList(s_doc, streams); /// /// Retrieves the list of stream states from the file. @@ -23,9 +21,9 @@ public override void WriteStreamsToFile(List streams) public override List GetStreamsInFile() { var streams = new List(); - if (_doc != null) + if (s_doc != null) { - streams = SpeckleStreamManager.ReadState(_doc); + streams = SpeckleStreamManager.ReadState(s_doc); } return streams; @@ -39,19 +37,19 @@ public override string GetFileName() { IsFileAndModelsPresent(); - return _doc?.CurrentFileName ?? string.Empty; + return s_doc?.CurrentFileName ?? string.Empty; } private static void IsFileAndModelsPresent() { - if (_doc == null) + if (s_doc == null) { - throw (new FileNotFoundException("No active document found. Cannot Send.")); + throw new FileNotFoundException("No active document found. Cannot Send."); } - if (_doc.Models.Count == 0) + if (s_doc.Models.Count == 0) { - throw (new FileNotFoundException("No models are appended. Nothing to Send.")); + throw new FileNotFoundException("No models are appended. Nothing to Send."); } } } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Filters.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Filters.cs index ab6e72f268..24ad7f49c3 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Filters.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Filters.cs @@ -23,14 +23,14 @@ public override List GetSelectionFilters() var manualFilter = new ManualSelectionFilter(); - if (_doc == null) + if (s_doc == null) { return filters; } filters.Add(manualFilter); - var selectSetsRootItem = _doc.SelectionSets.RootItem; + var selectSetsRootItem = s_doc.SelectionSets.RootItem; var savedSelectionSets = selectSetsRootItem?.Children.Select(GetSets).ToList() ?? new List(); @@ -47,7 +47,7 @@ public override List GetSelectionFilters() filters.Add(selectionSetsFilter); } - var savedViewsRootItem = _doc.SavedViewpoints.RootItem; + var savedViewsRootItem = s_doc.SavedViewpoints.RootItem; var savedViews = savedViewsRootItem?.Children.Select(GetViews).Select(RemoveNullNodes).Where(x => x != null).ToList() @@ -68,7 +68,7 @@ public override List GetSelectionFilters() filters.Add(savedViewsFilter); } - DocumentClash clashPlugin = _doc.GetClash(); + DocumentClash clashPlugin = s_doc.GetClash(); var clashTests = clashPlugin?.TestsData; @@ -102,7 +102,7 @@ private static TreeNode GetSets(SavedItem savedItem) DisplayName = savedItem.DisplayName, Guid = savedItem.Guid, IndexWith = nameof(TreeNode.Guid), - Indices = _doc.SelectionSets.CreateIndexPath(savedItem).ToArray() + Indices = s_doc.SelectionSets.CreateIndexPath(savedItem).ToArray() }; if (!savedItem.IsGroup) @@ -121,7 +121,7 @@ private static TreeNode GetSets(SavedItem savedItem) private static TreeNode GetViews(SavedItem savedItem) { - var reference = _doc.SavedViewpoints.CreateReference(savedItem); + var reference = s_doc.SavedViewpoints.CreateReference(savedItem); var treeNode = new TreeNode { @@ -142,6 +142,8 @@ private static TreeNode GetViews(SavedItem savedItem) return null; case false: return treeNode; + default: + break; // handles savedItem.IsGroup == true, somewhat redundant } foreach (var childItem in ((GroupItem)savedItem).Children) @@ -160,14 +162,14 @@ private static TreeNode RemoveNullNodes(TreeNode node) return null; } - if (!node.Elements.Any()) + if (node.Elements.Count == 0) { return node; } var elements = node.Elements.Select(RemoveNullNodes).Where(childNode => childNode != null).ToList(); - if (!elements.Any()) + if (elements.Count == 0) { return null; } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Receive.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Receive.cs index e5926c099d..02b91752b4 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Receive.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Receive.cs @@ -16,10 +16,7 @@ public partial class ConnectorBindingsNavisworks public override bool CanReceive => false; - public override List GetReceiveModes() - { - return null; - } + public override List GetReceiveModes() => null; public override async Task PreviewReceive(StreamState state, ProgressViewModel progress) { diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Selections.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Selections.cs index bef0d3af48..0a4b5b58b0 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Selections.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Selections.cs @@ -21,11 +21,11 @@ public override List GetSelectedObjects() Cursor.Current = Cursors.WaitCursor; // Current document, models and selected elements. - _doc = Application.ActiveDocument; + s_doc = Application.ActiveDocument; IsFileAndModelsPresent(); - var appSelectedItems = _doc.CurrentSelection.SelectedItems; + var appSelectedItems = s_doc.CurrentSelection.SelectedItems; // Storing as a Set for consistency with the converter's handling of fragments and paths. var selectedObjects = new HashSet(); @@ -46,10 +46,8 @@ public override List GetSelectedObjects() /// /// /// - private static bool IsElementVisible(ModelItem element) - { + private static bool IsElementVisible(ModelItem element) => // Hidden status is stored at the earliest node in the hierarchy // All of the the tree path nodes need to not be Hidden - return element.AncestorsAndSelf.All(x => x.IsHidden != true); - } + element.AncestorsAndSelf.All(x => x.IsHidden != true); } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Send.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Send.cs index 206d4806e5..11f23fd75d 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Send.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Send.cs @@ -15,7 +15,7 @@ using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Transports; -using static Speckle.ConnectorNavisworks.Other.Utilities; +using static Speckle.ConnectorNavisworks.Other.SpeckleNavisworksUtilities; using Application = Autodesk.Navisworks.Api.Application; using Cursor = System.Windows.Forms.Cursor; @@ -37,19 +37,17 @@ public partial class ConnectorBindingsNavisworks private static Collection CommitObject => new() { - ["units"] = GetUnits(_doc), + ["units"] = GetUnits(s_doc), collectionType = "Navisworks Model", - name = _doc.Title, + name = s_doc.Title, applicationId = "Root" }; // Stub - Preview send is not supported - public override async void PreviewSend(StreamState state, ProgressViewModel progress) - { + public override async void PreviewSend(StreamState state, ProgressViewModel progress) => await Task.Delay(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false); - // TODO! - } + // TODO! /// /// Sends the stream to Speckle. /// @@ -81,8 +79,8 @@ public override async Task SendStream(StreamState state, ProgressViewMod // Reset the cached conversion and commit objects CachedConvertedElements = null; - _cachedState = state; - _cachedCommit = commitObject; + s_cachedState = state; + s_cachedCommit = commitObject; Cursor.Current = Cursors.WaitCursor; @@ -108,7 +106,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod } else { - commitObject = _cachedCommit as Collection; + commitObject = s_cachedCommit as Collection; if (commitObject != null) { commitObject.elements = CachedConvertedElements; @@ -117,7 +115,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod var objectId = await SendConvertedObjectsToSpeckle(state, commitObject).ConfigureAwait(false); - if (_progressViewModel.Report.OperationErrors.Any()) + if (_progressViewModel.Report.OperationErrors.Count != 0) { ConnectorHelpers.DefaultSendErrorHandler("", _progressViewModel.Report.OperationErrors.Last()); } @@ -129,7 +127,7 @@ public override async Task SendStream(StreamState state, ProgressViewMod if (PersistCache == false) { // On success, cancel the conversion and commit object cache - _cachedCommit = null; + s_cachedCommit = null; CachedConvertedElements = null; } } @@ -184,7 +182,7 @@ private void ValidateBeforeSending(StreamState state) throw new ArgumentException("No ProgressViewModel provided."); } - if (_doc.ActiveSheet == null) + if (s_doc.ActiveSheet == null) { throw new InvalidOperationException("Your Document is empty. Nothing to Send."); } @@ -277,7 +275,7 @@ private void SetupConverter(StreamState state) CurrentSettings = state.Settings; var settings = state.Settings.ToDictionary(setting => setting.Slug, setting => setting.Selection); - _navisworksConverter.SetContextDocument(_doc); + _navisworksConverter.SetContextDocument(s_doc); _navisworksConverter.SetConverterSettings(settings); _navisworksConverter.Report.ReportObjects.Clear(); } @@ -368,11 +366,9 @@ private void HandleProgress(ConcurrentDictionary progressDict) /// /// Unused parameter (typically the sender). /// The exception that occurred. - private void HandleError(string _, Exception ex) - { + private void HandleError(string _, Exception ex) => // Add the exception to the report's operation errors _progressViewModel.Report.OperationErrors.Add(ex); - } /// /// Sends converted objects to the Speckle server. @@ -483,7 +479,7 @@ private List GetModelItemsForConversion(StreamState state) modelItemsToConvert.AddRange(selectionBuilder.ModelItems); - if (!modelItemsToConvert.Any()) + if (modelItemsToConvert.Count == 0) { throw new InvalidOperationException( "Zero objects visible for conversion; send stopped. Please select some objects, or check that your filter can actually select something." @@ -521,8 +517,8 @@ private void ConvertViews(StreamState state, DynamicBase commitObject) // Only send current view if we aren't sending other views. else if (CurrentSettings.Find(x => x.Slug == "current-view") is CheckBoxSetting { IsChecked: true }) { - var currentView = _conversionInvoker.Convert(_doc.CurrentViewpoint.ToViewpoint()); - var homeView = _conversionInvoker.Convert(_doc.HomeView); + var currentView = _conversionInvoker.Convert(s_doc.CurrentViewpoint.ToViewpoint()); + var homeView = _conversionInvoker.Convert(s_doc.HomeView); if (currentView != null) { @@ -537,7 +533,7 @@ private void ConvertViews(StreamState state, DynamicBase commitObject) } } - if (views.Any()) + if (views.Count != 0) { commitObject["views"] = views; } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Settings.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Settings.cs index bc572766b7..009066868f 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Settings.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.Settings.cs @@ -8,16 +8,16 @@ namespace Speckle.ConnectorNavisworks.Bindings; public partial class ConnectorBindingsNavisworks { // CAUTION: these strings need to have the same values as in the converter - private const string InternalOrigin = "Model Origin (default)"; - private const string ProxyOrigin = "Project Base Origin"; - private const string BBoxOrigin = "Boundingbox Origin"; + private const string INTERNAL_ORIGIN = "Model Origin (default)"; + private const string PROXY_ORIGIN = "Project Base Origin"; + private const string BBOX_ORIGIN = "Boundingbox Origin"; // used to store the Stream State settings when sending private List CurrentSettings { get; set; } public override List GetSettings() { - var referencePoints = new List { InternalOrigin, ProxyOrigin, BBoxOrigin }; + var referencePoints = new List { INTERNAL_ORIGIN, PROXY_ORIGIN, BBOX_ORIGIN }; var units = new List(Enum.GetNames(typeof(Units))); return new List @@ -28,7 +28,7 @@ public override List GetSettings() Name = "Reference Point", Icon = "LocationSearching", Values = referencePoints, - Selection = InternalOrigin, + Selection = INTERNAL_ORIGIN, Description = "Sends or receives stream objects in relation to this document point" }, new NumericSetting diff --git a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.cs b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.cs index 12f6d257cf..93dbe93c60 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Bindings/ConnectorNavisworksBindings.cs @@ -13,80 +13,62 @@ using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; +using static Speckle.ConnectorNavisworks.Other.SpeckleNavisworksUtilities; using Application = Autodesk.Navisworks.Api.Application; using Cursor = System.Windows.Forms.Cursor; using MenuItem = DesktopUI2.Models.MenuItem; -using Utilities = Speckle.ConnectorNavisworks.Other.Utilities; namespace Speckle.ConnectorNavisworks.Bindings; public partial class ConnectorBindingsNavisworks : ConnectorBindings { // Much of the interaction in Navisworks is through the ActiveDocument API - private static Document _doc; + private static Document s_doc; internal static Control Control; - private static object _cachedCommit; + private static object s_cachedCommit; internal static List CachedConvertedElements; - private static StreamState _cachedState; + private static StreamState s_cachedState; private ISpeckleKit _defaultKit; private ISpeckleConverter _navisworksConverter; // private bool _isRetrying; internal static bool PersistCache; - private NavisworksOptionsManager _settingsHandler; + private readonly NavisworksOptionsManager _settingsHandler; public ConnectorBindingsNavisworks(Document navisworksActiveDocument) { - _doc = navisworksActiveDocument; - _doc.SelectionSets.ToSavedItemCollection(); + s_doc = navisworksActiveDocument; + s_doc.SelectionSets.ToSavedItemCollection(); // Sets the Main Thread Control to Invoke commands on. Control = new Control(); Control.CreateControl(); _defaultKit = KitManager.GetDefaultKit(); - _navisworksConverter = _defaultKit?.LoadConverter(Utilities.VersionedAppName); + _navisworksConverter = _defaultKit?.LoadConverter(VersionedAppName); _settingsHandler = new NavisworksOptionsManager(); } public static string HostAppName => HostApplications.Navisworks.Slug; - public static string HostAppNameVersion => Utilities.VersionedAppName.Replace("Navisworks", "Navisworks "); + public static string HostAppNameVersion => VersionedAppName.Replace("Navisworks", "Navisworks "); public static bool CachedConversion => - CachedConvertedElements != null && CachedConvertedElements.Any() && _cachedCommit != null; + CachedConvertedElements != null && CachedConvertedElements.Count != 0 && s_cachedCommit != null; - public override string GetActiveViewName() - { - return "Entire Document"; - } + public override string GetActiveViewName() => "Entire Document"; - public override List GetCustomStreamMenuItems() - { - return new List(); - } + public override List GetCustomStreamMenuItems() => new(); - public override string GetHostAppName() - { - return HostAppName; - } + public override string GetHostAppName() => HostAppName; - public override string GetHostAppNameVersion() - { - return HostAppNameVersion; - } + public override string GetHostAppNameVersion() => HostAppNameVersion; - private static string GetDocPath() - { - return ""; - } + private static string GetDocPath() => ""; - public override string GetDocumentLocation() - { - return GetDocPath(); - } + public override string GetDocumentLocation() => GetDocPath(); public override void SelectClientObjects(List objs, bool deselect = false) { @@ -102,30 +84,29 @@ public override string GetDocumentId() { // TODO! // An unsaved document has no path or filename - var fileName = _doc.CurrentFileName; + var fileName = s_doc.CurrentFileName; var hash = Core.Models.Utilities.HashString(fileName, Core.Models.Utilities.HashingFunctions.MD5); return hash; } public override List GetObjectsInView() // this returns all visible doc objects. - // TODO! - { + // TODO! + => throw new NotImplementedException(); - } public async Task RetryLastConversionSend() { - if (_doc == null) + if (s_doc == null) { return; } - if (CachedConvertedElements == null || _cachedCommit == null) + if (CachedConvertedElements == null || s_cachedCommit == null) { throw new SpeckleException("Cant retry last conversion: no cached conversion or commit found."); } - if (_cachedCommit is Collection commitObject) + if (s_cachedCommit is Collection commitObject) { // _isRetrying = true; @@ -135,14 +116,14 @@ public async Task RetryLastConversionSend() commitObject.elements = CachedConvertedElements; - var state = _cachedState; + var state = s_cachedState; _progressBar.BeginSubOperation(0.7, "Retrying cached conversion."); _progressBar.EndSubOperation(); var objectId = await SendConvertedObjectsToSpeckle(state, commitObject).ConfigureAwait(false); - if (_progressViewModel.Report.OperationErrors.Any()) + if (_progressViewModel.Report.OperationErrors.Count != 0) { ConnectorHelpers.DefaultSendErrorHandler("", _progressViewModel.Report.OperationErrors.Last()); } @@ -172,7 +153,7 @@ public async Task RetryLastConversionSend() } // nullify the cached conversion and commit on success. - _cachedCommit = null; + s_cachedCommit = null; CachedConvertedElements = null; // _isRetrying = false; diff --git a/ConnectorNavisworks/ConnectorNavisworks/Entry/Commands.cs b/ConnectorNavisworks/ConnectorNavisworks/Entry/Commands.cs index 8536eb190a..9772013a87 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Entry/Commands.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Entry/Commands.cs @@ -2,27 +2,27 @@ namespace Speckle.ConnectorNavisworks.Entry; public abstract class LaunchSpeckleConnector { - public const string Command = "Speckle_Launch"; - public const string Plugin = "SpeckleUI"; + public const string COMMAND = "Speckle_Launch"; + public const string PLUGIN = "SpeckleUI"; } public abstract class RetryLastConversionSend { - public const string Command = "Speckle_RetryLastConversionSend"; - public const string Plugin = "SpeckleUI"; + public const string COMMAND = "Speckle_RetryLastConversionSend"; + public const string PLUGIN = "SpeckleUI"; } public abstract class Community { - public const string Command = "Speckle_Community"; + public const string COMMAND = "Speckle_Community"; } public abstract class TurnPersistCacheOff { - public const string Command = "Speckle_PersistCache_Off"; + public const string COMMAND = "Speckle_PersistCache_Off"; } public abstract class TurnPersistCacheOn { - public const string Command = "Speckle_PersistCache_On"; + public const string COMMAND = "Speckle_PersistCache_On"; } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Entry/Ribbon.xaml.cs b/ConnectorNavisworks/ConnectorNavisworks/Entry/Ribbon.xaml.cs index 940b5f9dcc..c9ef7b3a32 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Entry/Ribbon.xaml.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Entry/Ribbon.xaml.cs @@ -1,13 +1,17 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Text; +using System.Diagnostics.CodeAnalysis; using System.Windows.Forms; using Autodesk.Navisworks.Api.Plugins; using Speckle.ConnectorNavisworks.Bindings; using Speckle.Core.Logging; using NavisworksApp = Autodesk.Navisworks.Api.Application; +#if DEBUG +using System.Text; +#endif + namespace Speckle.ConnectorNavisworks.Entry; [ @@ -16,7 +20,7 @@ namespace Speckle.ConnectorNavisworks.Entry; RibbonLayout("Ribbon.xaml"), RibbonTab("Speckle", DisplayName = "Speckle", LoadForCanExecute = true), Command( - LaunchSpeckleConnector.Command, + LaunchSpeckleConnector.COMMAND, LoadForCanExecute = true, Icon = "Resources/logo16.ico", LargeIcon = "Resources/logo32.ico", @@ -25,7 +29,7 @@ namespace Speckle.ConnectorNavisworks.Entry; DisplayName = "Speckle\rConnector" ), Command( - Community.Command, + Community.COMMAND, Icon = "Resources/forum16.png", LargeIcon = "Resources/forum32.png", Shortcut = "Ctrl+Shift+C", @@ -33,7 +37,7 @@ namespace Speckle.ConnectorNavisworks.Entry; DisplayName = "Speckle\rCommunity" ), Command( - RetryLastConversionSend.Command, + RetryLastConversionSend.COMMAND, LoadForCanExecute = true, Icon = "Resources/retry16.ico", LargeIcon = "Resources/retry32.ico", @@ -42,7 +46,7 @@ namespace Speckle.ConnectorNavisworks.Entry; DisplayName = "Retry\rSend" ), Command( - TurnPersistCacheOn.Command, + TurnPersistCacheOn.COMMAND, LoadForCanExecute = true, Icon = "Resources/empty32.ico", LargeIcon = "Resources/empty32.ico", @@ -50,7 +54,7 @@ namespace Speckle.ConnectorNavisworks.Entry; DisplayName = "Cache" ), Command( - TurnPersistCacheOff.Command, + TurnPersistCacheOff.COMMAND, LoadForCanExecute = true, Icon = "Resources/logo16.ico", LargeIcon = "Resources/logo32.ico", @@ -59,9 +63,14 @@ namespace Speckle.ConnectorNavisworks.Entry; DisplayName = "Cache" ), ] +[SuppressMessage( + "design", + "CA1812:Avoid uninstantiated internal classes", + Justification = "Instantiated by Navisworks" +)] internal sealed class RibbonHandler : CommandHandlerPlugin { - private readonly static Dictionary LoadedPlugins = new(); + private static readonly Dictionary s_loadedPlugins = new(); /// /// Determines the state of a command in Navisworks. @@ -72,7 +81,7 @@ public override CommandState CanExecuteCommand(string commandId) { return commandId switch { - TurnPersistCacheOn.Command + TurnPersistCacheOn.COMMAND => new CommandState { #if DEBUG @@ -82,7 +91,7 @@ public override CommandState CanExecuteCommand(string commandId) #endif IsEnabled = !ConnectorBindingsNavisworks.PersistCache }, - TurnPersistCacheOff.Command + TurnPersistCacheOff.COMMAND => new CommandState { #if DEBUG @@ -93,7 +102,7 @@ public override CommandState CanExecuteCommand(string commandId) IsEnabled = ConnectorBindingsNavisworks.PersistCache }, _ - => commandId == RetryLastConversionSend.Command + => commandId == RetryLastConversionSend.COMMAND ? new CommandState(ConnectorBindingsNavisworks.CachedConversion) : new CommandState(true) }; @@ -133,10 +142,7 @@ private static void LoadPlugin(string plugin, bool notAutomatedCheck = true, str /// /// The flag indicating whether to check if the application is automated. /// True if the load should be skipped, False otherwise. - private static bool ShouldSkipLoad(bool notAutomatedCheck) - { - return notAutomatedCheck && NavisworksApp.IsAutomated; - } + private static bool ShouldSkipLoad(bool notAutomatedCheck) => notAutomatedCheck && NavisworksApp.IsAutomated; /// /// Checks whether the plugin load should be skipped based on the plugin and command values. @@ -144,10 +150,8 @@ private static bool ShouldSkipLoad(bool notAutomatedCheck) /// The name of the plugin. /// The command associated with the plugin. /// True if the plugin load should be skipped, False otherwise. - private static bool ShouldSkipPluginLoad(string plugin, string command) - { - return string.IsNullOrEmpty(plugin) || string.IsNullOrEmpty(command); - } + private static bool ShouldSkipPluginLoad(string plugin, string command) => + string.IsNullOrEmpty(plugin) || string.IsNullOrEmpty(command); /// /// Activates the plugin's pane if it is of the right type. @@ -162,7 +166,7 @@ private static void ActivatePluginPane(PluginRecord pluginRecord, object loadedP var dockPanePlugin = (DockPanePlugin)loadedPlugin; dockPanePlugin.ActivatePane(); - LoadedPlugins[dockPanePlugin] = true; + s_loadedPlugins[dockPanePlugin] = true; } else { @@ -178,10 +182,8 @@ private static void ActivatePluginPane(PluginRecord pluginRecord, object loadedP /// /// The plugin record. /// True if the plugin's pane should be activated, False otherwise. - private static bool ShouldActivatePluginPane(PluginRecord pluginRecord) - { - return pluginRecord.IsLoaded && pluginRecord is DockPanePluginRecord && pluginRecord.IsEnabled; - } + private static bool ShouldActivatePluginPane(PluginRecord pluginRecord) => + pluginRecord.IsLoaded && pluginRecord is DockPanePluginRecord && pluginRecord.IsEnabled; public override int ExecuteCommand(string commandId, params string[] parameters) { @@ -220,19 +222,19 @@ public override int ExecuteCommand(string commandId, params string[] parameters) switch (commandId) { - case LaunchSpeckleConnector.Command: + case LaunchSpeckleConnector.COMMAND: { - LoadPlugin(LaunchSpeckleConnector.Plugin, command: commandId); + LoadPlugin(LaunchSpeckleConnector.PLUGIN, command: commandId); break; } - case RetryLastConversionSend.Command: + case RetryLastConversionSend.COMMAND: { - LoadPlugin(RetryLastConversionSend.Plugin, command: commandId); + LoadPlugin(RetryLastConversionSend.PLUGIN, command: commandId); - var retryPlugin = NavisworksApp.Plugins.FindPlugin(RetryLastConversionSend.Plugin + ".Speckle").LoadedPlugin; + var retryPlugin = NavisworksApp.Plugins.FindPlugin(RetryLastConversionSend.PLUGIN + ".Speckle").LoadedPlugin; - LoadedPlugins.TryGetValue(retryPlugin, out var loaded); + s_loadedPlugins.TryGetValue(retryPlugin, out var loaded); if (loaded) { @@ -255,14 +257,14 @@ public override int ExecuteCommand(string commandId, params string[] parameters) break; } - case Community.Command: + case Community.COMMAND: { Process.Start("https://speckle.community/tag/navisworks"); break; } - case TurnPersistCacheOff.Command - or TurnPersistCacheOn.Command: + case TurnPersistCacheOff.COMMAND + or TurnPersistCacheOn.COMMAND: { ConnectorBindingsNavisworks.PersistCache = !ConnectorBindingsNavisworks.PersistCache; @@ -303,9 +305,6 @@ private static void ShowPluginInfoMessageBox() /// Shows a message box indicating that the plugin was not loaded. /// /// The command associated with the plugin. - private static void ShowPluginNotLoadedMessageBox(string command) - { - MessageBox.Show(command + " Plugin not loaded."); - } + private static void ShowPluginNotLoadedMessageBox(string command) => MessageBox.Show(command + " Plugin not loaded."); #endif } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleHostPane.xaml.cs b/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleHostPane.xaml.cs index 24e6459b16..aa7167703b 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleHostPane.xaml.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleHostPane.xaml.cs @@ -6,10 +6,10 @@ namespace Speckle.ConnectorNavisworks.Entry; public partial class SpeckleHostPane { - private const uint DlgcWantarrows = 0x0001; - private const uint DlgcHasSetSel = 0x0008; - private const uint DlgcWantChars = 0x0080; - private const uint WmGetDlgCode = 0x0087; + private const uint DLGC_WANTARROWS = 0x0001; + private const uint DLGC_HAS_SET_SEL = 0x0008; + private const uint DLGC_WANT_CHARS = 0x0080; + private const uint WM_GET_DLG_CODE = 0x0087; public SpeckleHostPane() { @@ -22,19 +22,16 @@ public SpeckleHostPane() } // Triggered when the active document name is changed. This will happen automatically if a document is newly created or opened. - private void Application_DocumentChanged(object sender, EventArgs e) - { - AvaloniaHost.Content = new MainUserControl(); - } + private void Application_DocumentChanged(object sender, EventArgs e) => AvaloniaHost.Content = new MainUserControl(); private static IntPtr AvaloniaHost_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { - if (msg != WmGetDlgCode) + if (msg != WM_GET_DLG_CODE) { return IntPtr.Zero; } handled = true; - return new IntPtr(DlgcWantChars | DlgcWantarrows | DlgcHasSetSel); + return new IntPtr(DLGC_WANT_CHARS | DLGC_WANTARROWS | DLGC_HAS_SET_SEL); } } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleNavisworksCommand.cs b/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleNavisworksCommand.cs index dcea266677..378f023ce2 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleNavisworksCommand.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Entry/SpeckleNavisworksCommand.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Windows.Forms; @@ -17,7 +18,7 @@ namespace Speckle.ConnectorNavisworks.Entry; [ DockPanePlugin(450, 750, FixedSize = false, AutoScroll = true, MinimumHeight = 410, MinimumWidth = 250), Plugin( - LaunchSpeckleConnector.Plugin, + LaunchSpeckleConnector.PLUGIN, "Speckle", DisplayName = "Speckle", Options = PluginOptions.None, @@ -25,11 +26,20 @@ namespace Speckle.ConnectorNavisworks.Entry; ExtendedToolTip = "Speckle Connector for Navisworks" ) ] -// ReSharper disable once ClassNeverInstantiated.Global - This is because of the mechanism Navisworks uses to load plugins. +[SuppressMessage( + "design", + "CA1812:Avoid uninstantiated internal classes", + Justification = "Instantiated by Navisworks" +)] internal sealed class SpeckleNavisworksCommandPlugin : DockPanePlugin { internal ConnectorBindingsNavisworks Bindings; + [SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Instance of InitAvalonia has unknown Exceptions." + )] public override Control CreateControlPane() { AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; @@ -90,10 +100,7 @@ private static AppBuilder BuildAvaloniaApp() return app; } - private static void InitAvalonia() - { - BuildAvaloniaApp().SetupWithoutStarting(); - } + private static void InitAvalonia() => BuildAvaloniaApp().SetupWithoutStarting(); private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) { diff --git a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Autosave.cs b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Autosave.cs index 7d5d89d80f..8bdb6aa52e 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Autosave.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Autosave.cs @@ -36,6 +36,10 @@ private void UpdateAutoSaveSetting(bool enable) case true when _autosaveSetting: rootOptions.SetBoolean("general.autosave.enable", true); break; + default: + // This case is intentionally left empty as all logical scenarios + // for a boolean 'enable' are covered above. + break; } SaveGlobalOptions(); @@ -44,16 +48,10 @@ private void UpdateAutoSaveSetting(bool enable) /// /// Disables the auto-save feature. /// - public void DisableAutoSave() - { - UpdateAutoSaveSetting(false); - } + public void DisableAutoSave() => UpdateAutoSaveSetting(false); /// /// Restores the auto-save setting to its original state after the send process. /// - public void RestoreAutoSave() - { - UpdateAutoSaveSetting(true); - } + public void RestoreAutoSave() => UpdateAutoSaveSetting(true); } diff --git a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Manager.cs b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Manager.cs index efeea8898b..e58f088a69 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Manager.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Manager.cs @@ -1,7 +1,3 @@ -using Autodesk.Navisworks.Api.Interop; -using static Autodesk.Navisworks.Api.Interop.LcOpRegistry; -using static Autodesk.Navisworks.Api.Interop.LcUOption; - namespace Speckle.ConnectorNavisworks.NavisworksOptions; /// diff --git a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Properties.cs b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Properties.cs index ee077c9aec..81992fa473 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Properties.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/NavisworksOptions/Properties.cs @@ -38,64 +38,50 @@ private void UpdateOptionSetting(string optionName, ref bool optionSetting, bool /// /// Updates the internal property display setting. /// - private void UpdateInternalPropertySetting() - { + private void UpdateInternalPropertySetting() => UpdateOptionSetting( "interface.developer.show_properties", ref _internalPropertyDisplaySetting, _internalPropertyDisplaySetting ); - } /// /// Updates the internal property display setting. /// /// A boolean value indicating whether to enable or disable the internal property display. - private void UpdateInternalPropertySetting(bool enable) - { + private void UpdateInternalPropertySetting(bool enable) => UpdateOptionSetting("interface.developer.show_properties", ref _internalPropertyDisplaySetting, enable); - } /// /// Updates the internal property name setting. /// - private void UpdateInternalPropertyNameSetting() - { + private void UpdateInternalPropertyNameSetting() => UpdateOptionSetting( "interface.developer.show_property_internal_names", ref _useInternalPropertyNamesSetting, _useInternalPropertyNamesSetting ); - } /// /// Updates the internal property name setting. /// /// A boolean value indicating whether to enable or disable the internal property names. - private void UpdateInternalPropertyNameSetting(bool enable) - { + private void UpdateInternalPropertyNameSetting(bool enable) => UpdateOptionSetting( "interface.developer.show_property_internal_names", ref _useInternalPropertyNamesSetting, enable ); - } /// /// Shows internal properties. /// - public void ShowInternalProperties() - { - UpdateInternalPropertySetting(true); - } + public void ShowInternalProperties() => UpdateInternalPropertySetting(true); /// /// Uses internal property names. /// - public void UseInternalPropertyNames() - { - UpdateInternalPropertyNameSetting(true); - } + public void UseInternalPropertyNames() => UpdateInternalPropertyNameSetting(true); /// /// Restores the internal properties display to its original state after the send process. diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/Constants.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/Constants.cs index b28815df5a..a2202b7b5c 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/Constants.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/Constants.cs @@ -2,7 +2,7 @@ namespace Speckle.ConnectorNavisworks.Other; public static class Constants { - public const string RootNodePseudoId = "___"; + public const string ROOT_NODE_PSEUDO_ID = "___"; public enum ConversionState { diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/Elements.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/Elements.cs index b3653cea84..52068a8612 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/Elements.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/Elements.cs @@ -37,25 +37,22 @@ public Element() { } public string PseudoId { get; private set; } + private static readonly int[] s_lowerBounds = new[] { 1 }; + private static readonly string[] s_separator = new[] { "." }; + /// /// Creates a new Element instance using a given pseudoId. /// /// The pseudoId used to create the Element instance. /// A new Element instance with its pseudoId set. - public static Element GetElement(string pseudoId) - { - return new Element(pseudoId); - } + public static Element GetElement(string pseudoId) => new(pseudoId); /// /// Creates a new Element instance using a given ModelItem. /// /// The ModelItem used to create the Element instance. /// A new Element instance with its PseudoId and _modelItem field set. - public Element GetElement(ModelItem modelItem) - { - return new Element(GetPseudoId(modelItem), modelItem); - } + public Element GetElement(ModelItem modelItem) => new(GetPseudoId(modelItem), modelItem); /// /// Gets the PseudoId for the given ModelItem. @@ -72,7 +69,7 @@ private string GetPseudoId(ModelItem modelItem) var arrayData = ((Array)ComApiBridge.ToInwOaPath(modelItem).ArrayData).ToArray(); PseudoId = arrayData.Length == 0 - ? Constants.RootNodePseudoId + ? Constants.ROOT_NODE_PSEUDO_ID : string.Join("-", arrayData.Select(x => x.ToString().PadLeft(4, '0'))); return PseudoId; } @@ -88,7 +85,7 @@ private ModelItem Resolve() return _modelItem; } - if (PseudoId == Constants.RootNodePseudoId) + if (PseudoId == Constants.ROOT_NODE_PSEUDO_ID) { return Application.ActiveDocument.Models.RootItems.First; } @@ -121,9 +118,8 @@ private ModelItem Resolve() /// The PseudoId to parse. /// An array of integers representing the path. /// Thrown when the PseudoId is malformed. - private int[] ParsePseudoIdToPathArray(string pseudoId) - { - return pseudoId + private int[] ParsePseudoIdToPathArray(string pseudoId) => + pseudoId .Split('-') .Select(x => { @@ -135,7 +131,6 @@ private int[] ParsePseudoIdToPathArray(string pseudoId) throw new ArgumentException("malformed path pseudoId"); }) .ToArray(); - } /// /// Converts a zero-based integer array into a one-based array. @@ -144,7 +139,7 @@ private int[] ParsePseudoIdToPathArray(string pseudoId) /// A one-based array with the same elements as the input array. private Array ConvertTo1BasedArray(int[] pathArray) { - var oneBasedArray = Array.CreateInstance(typeof(int), new[] { pathArray.Length }, new[] { 1 }); + var oneBasedArray = Array.CreateInstance(typeof(int), new[] { pathArray.Length }, s_lowerBounds); Array.Copy(pathArray, 0, oneBasedArray, 1, pathArray.Length); return oneBasedArray; } @@ -172,7 +167,7 @@ private static string ElementDescriptor(ModelItem modelItem) var simpleType = modelItem .GetType() .ToString() - .Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) + .Split(s_separator, StringSplitOptions.RemoveEmptyEntries) .LastOrDefault(); return string.IsNullOrEmpty(modelItem.ClassDisplayName) ? $"{simpleType}" @@ -183,10 +178,7 @@ private static string ElementDescriptor(ModelItem modelItem) /// Generates a descriptor for the current model item. /// /// A descriptor for the current model item, or null if no model item is set. - public string Descriptor() - { - return _modelItem == null ? null : ElementDescriptor(_modelItem); - } + public string Descriptor() => _modelItem == null ? null : ElementDescriptor(_modelItem); /// /// Builds a nested object hierarchy from a dictionary of flat key-value pairs. @@ -211,7 +203,7 @@ StreamState streamState // First pass: Create lookup dictionary and identify potential root nodes foreach (var pair in convertedDictionary) { - var element = pair.Value.Item2; + var element = pair.Value.Key; var pseudoId = element.PseudoId; var baseNode = pair.Value.Item1; var modelItem = element.ModelItem; diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/FilterTypes.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/FilterTypes.cs index 4743276e1a..c3144fcd7a 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/FilterTypes.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/FilterTypes.cs @@ -2,8 +2,8 @@ namespace Speckle.ConnectorNavisworks.Other; internal static class FilterTypes { - public const string Manual = "manual"; - public const string Sets = "sets"; - public const string Clashes = "clashes"; - public const string Views = "views"; + public const string MANUAL = "manual"; + public const string SETS = "sets"; + public const string CLASHES = "clashes"; + public const string VIEWS = "views"; } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/Invokers.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/Invokers.cs index 25983c8239..88f72466ea 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/Invokers.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/Invokers.cs @@ -79,10 +79,8 @@ public ProgressInvoker(Progress applicationProgress) /// /// Progress in sub op between 0 and 1 maps to fraction of remaining time in main operation. /// The message of the sub operation. Defaults to an empty string. - internal void BeginSubOperation(double fractionOfRemainingTime, string message = "") - { + internal void BeginSubOperation(double fractionOfRemainingTime, string message = "") => Invoke(new Action(_progressBar.BeginSubOperation), fractionOfRemainingTime, message); - } /// /// Ends the current sub operation. @@ -152,8 +150,5 @@ public ConversionInvoker(ISpeckleConverter converter) /// /// The object to convert. This can be a ModelItem, View or whichever conversions get added. /// A Speckle Base object. - public Base Convert(object navisworksObject) - { - return (Base)Invoke(_convertToSpeckle, navisworksObject); - } + public Base Convert(object navisworksObject) => (Base)Invoke(_convertToSpeckle, navisworksObject); } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/SelectionBuilder.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/SelectionBuilder.cs index ef0805b1de..b1dcf4dfb6 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/SelectionBuilder.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/SelectionBuilder.cs @@ -18,7 +18,7 @@ public class SelectionHandler private readonly HashSet _uniqueModelItems; private int _descendantProgress; private HashSet _visited; - public ProgressInvoker ProgressBar; + internal ProgressInvoker ProgressBar; private readonly bool _coalesceData; /// @@ -48,24 +48,26 @@ public void GetFromFilter() { switch (_filter.Slug) { - case FilterTypes.Manual: + case FilterTypes.MANUAL: _uniqueModelItems.AddRange(GetObjectsFromSelection()); break; - case FilterTypes.Sets: + case FilterTypes.SETS: _uniqueModelItems.AddRange(GetObjectsFromSavedSets()); break; - case FilterTypes.Views: + case FilterTypes.VIEWS: _uniqueModelItems.AddRange(GetObjectsFromSavedViewpoint()); break; + default: + throw new ArgumentOutOfRangeException(nameof(_filter.Slug), _filter.Slug, "Unrecognized filter type"); } } /// /// Retrieves the model items from the selection. /// - private IEnumerable GetObjectsFromSelection() + private HashSet GetObjectsFromSelection() { _uniqueModelItems.Clear(); @@ -116,21 +118,17 @@ private IEnumerable GetObjectsFromSavedViewpoint() var success = false; - new Invoker().Invoke( - (Action)( - () => - { - var savedViewpoint = ResolveSavedViewpoint(selection); - if (savedViewpoint != null && !savedViewpoint.ContainsVisibilityOverrides) - { - return; - } + new Invoker().Invoke(() => + { + var savedViewpoint = ResolveSavedViewpoint(selection); + if (savedViewpoint != null && !savedViewpoint.ContainsVisibilityOverrides) + { + return; + } - Application.ActiveDocument.SavedViewpoints.CurrentSavedViewpoint = savedViewpoint; - success = true; - } - ) - ); + Application.ActiveDocument.SavedViewpoints.CurrentSavedViewpoint = savedViewpoint; + success = true; + }); if (!success) { @@ -258,7 +256,7 @@ private TreeNode GetViews(SavedItem savedItem) switch (savedItem) { case SavedViewpoint { ContainsVisibilityOverrides: false }: - // TODO: Determine whether to return null or an empty TreeNode or based on current visibility + // TODO: Determine whether to return null or an empty TreeNode or based on current visibility. This is another don't send everything safeguard. return null; case GroupItem groupItem: foreach (var childItem in groupItem.Children) @@ -267,6 +265,10 @@ private TreeNode GetViews(SavedItem savedItem) treeNode.Elements.Add(GetViews(childItem)); } break; + default: + // This case is intentionally left empty as all SDK object scenarios are covered above. + // and will fall throw with the treeNode for a SavedViewpoint that is not a group and has visibility overrides. + break; } // Return the treeNode @@ -276,7 +278,7 @@ private TreeNode GetViews(SavedItem savedItem) /// /// Retrieves the model items from the saved sets. /// - private IEnumerable GetObjectsFromSavedSets() + private HashSet GetObjectsFromSavedSets() { _uniqueModelItems.Clear(); @@ -305,7 +307,7 @@ private IEnumerable GetObjectsFromSavedSets() /// public void PopulateHierarchyAndOmitHidden() { - if (_uniqueModelItems == null || !_uniqueModelItems.Any()) + if (_uniqueModelItems == null || _uniqueModelItems.Count == 0) { return; } @@ -488,9 +490,7 @@ private void ProgressLooper( /// /// Omits items that are hidden from the starting list of nodes if they are not visible in the model. /// - public void ValidateStartNodes() - { + public void ValidateStartNodes() => // Remove any nodes that are descendants of hidden nodes. _uniqueModelItems.RemoveWhere(e => e.AncestorsAndSelf.Any(a => a.IsHidden)); - } } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Other/Utilities.cs b/ConnectorNavisworks/ConnectorNavisworks/Other/Utilities.cs index 730c405cbe..f15779e495 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Other/Utilities.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Other/Utilities.cs @@ -17,37 +17,26 @@ public static T[] ToArray(this Array arr) } } -public static class Utilities +public static class SpeckleNavisworksUtilities { #if NAVMAN21 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2024); + public static readonly string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2024); #elif NAVMAN20 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2023); + public static readonly string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2023); #elif NAVMAN19 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2022); + public static readonly string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2022); #elif NAVMAN18 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2021); + public static readonly string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2021); #elif NAVMAN17 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2020); + public static readonly string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2020); #endif - internal static void ConsoleLog(string message, ConsoleColor color = ConsoleColor.Blue) - { + internal static void ConsoleLog(string message, ConsoleColor color = ConsoleColor.Blue) => Console.WriteLine(message, color); - } - public static void WarnLog(string warningMessage) - { - ConsoleLog(warningMessage, ConsoleColor.DarkYellow); - } + public static void WarnLog(string warningMessage) => ConsoleLog(warningMessage, ConsoleColor.DarkYellow); - public static void ErrorLog(string errorMessage) - { - ConsoleLog(errorMessage, ConsoleColor.DarkRed); - } + public static void ErrorLog(string errorMessage) => ConsoleLog(errorMessage, ConsoleColor.DarkRed); - public static string GetUnits(Document doc) - { - return doc.Units.ToString(); - } + public static string GetUnits(Document doc) => doc.Units.ToString(); } diff --git a/ConnectorNavisworks/ConnectorNavisworks/Storage/SpeckleStreamManager.cs b/ConnectorNavisworks/ConnectorNavisworks/Storage/SpeckleStreamManager.cs index deb4376943..8f853a405b 100644 --- a/ConnectorNavisworks/ConnectorNavisworks/Storage/SpeckleStreamManager.cs +++ b/ConnectorNavisworks/ConnectorNavisworks/Storage/SpeckleStreamManager.cs @@ -5,14 +5,14 @@ using Autodesk.Navisworks.Api.Data; using DesktopUI2.Models; using Speckle.Newtonsoft.Json; -using static Speckle.ConnectorNavisworks.Other.Utilities; +using static Speckle.ConnectorNavisworks.Other.SpeckleNavisworksUtilities; namespace Speckle.ConnectorNavisworks.Storage; internal abstract class SpeckleStreamManager { - private const string TableName = "speckle"; - private const string KeyName = "stream_states"; + private const string TABLE_NAME = "speckle"; + private const string KEY_NAME = "stream_states"; public static List ReadState(Document doc) { @@ -37,7 +37,7 @@ public static List ReadState(Document doc) using var table = new DataTable(); using ( var dataAdapter = new NavisworksDataAdapter( - $"SELECT value FROM {TableName} WHERE key = '{KeyName}'", + $"SELECT value FROM {TABLE_NAME} WHERE key = '{KEY_NAME}'", database.Value ) ) @@ -64,8 +64,8 @@ public static List ReadState(Document doc) { ConsoleLog($"Rebuilding Saved State DB. {table.Rows.Count} is too many."); - string deleteSql = $"DELETE FROM {TableName} WHERE key = @key"; - string insertSql = $"INSERT INTO {TableName}(key, value) VALUES(@key, @value)"; + string deleteSql = $"DELETE FROM {TABLE_NAME} WHERE key = @key"; + string insertSql = $"INSERT INTO {TABLE_NAME}(key, value) VALUES(@key, @value)"; using NavisworksTransaction transaction = database.BeginTransaction(DatabaseChangedAction.Edited); NavisworksCommand command = transaction.Connection.CreateCommand(); @@ -73,12 +73,12 @@ public static List ReadState(Document doc) try { command.CommandText = deleteSql; - command.Parameters.AddWithValue("@key", KeyName); + command.Parameters.AddWithValue("@key", KEY_NAME); int unused = command.ExecuteNonQuery(); command.CommandText = insertSql; - command.Parameters.AddWithValue("@key", KeyName); + command.Parameters.AddWithValue("@key", KEY_NAME); command.Parameters.AddWithValue("@value", row.ItemArray); int inserted = command.ExecuteNonQuery(); @@ -112,7 +112,7 @@ public static List ReadState(Document doc) { ErrorLog( "Something isn't right. " - + $"{KeyName} was found but didn't deserialize into any streams:" + + $"{KEY_NAME} was found but didn't deserialize into any streams:" + $"\n {speckleStreamsStore}" ); } @@ -145,9 +145,9 @@ internal static void WriteStreamStateList(Document doc, List stream string streamStatesStore = JsonConvert.SerializeObject(streamStates); - string createSql = $"CREATE TABLE IF NOT EXISTS {TableName}(key TEXT, value TEXT)"; - string deleteSql = $"DELETE FROM {TableName} WHERE key = @key"; - string insertSql = $"INSERT INTO {TableName}(key, value) VALUES(@key, @value)"; + string createSql = $"CREATE TABLE IF NOT EXISTS {TABLE_NAME}(key TEXT, value TEXT)"; + string deleteSql = $"DELETE FROM {TABLE_NAME} WHERE key = @key"; + string insertSql = $"INSERT INTO {TABLE_NAME}(key, value) VALUES(@key, @value)"; using (NavisworksTransaction transaction = documentDatabase.BeginTransaction(DatabaseChangedAction.Reset)) { @@ -166,11 +166,11 @@ internal static void WriteStreamStateList(Document doc, List stream try { command.CommandText = deleteSql; - command.Parameters.AddWithValue("@key", KeyName); + command.Parameters.AddWithValue("@key", KEY_NAME); int unused = command.ExecuteNonQuery(); command.CommandText = insertSql; - command.Parameters.AddWithValue("@key", KeyName); + command.Parameters.AddWithValue("@key", KEY_NAME); command.Parameters.AddWithValue("@value", streamStatesStore); int inserted = command.ExecuteNonQuery(); diff --git a/ConnectorRevit/ConnectorRevit.slnf b/ConnectorRevit/ConnectorRevit.slnf index 1f3820ecd5..c5c13cec76 100644 --- a/ConnectorRevit/ConnectorRevit.slnf +++ b/ConnectorRevit/ConnectorRevit.slnf @@ -19,8 +19,8 @@ "ConnectorRevit\\RevitSharedResources2024\\RevitSharedResources2024.csproj", "ConnectorRevit\\RevitSharedResources\\RevitSharedResources.shproj", "Core\\Core\\Core.csproj", - "Core\\IntegrationTests\\TestsIntegration.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Integration\\Speckle.Core.Tests.Integration.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "Core\\Transports\\MongoDBTransport\\MongoDBTransport.csproj", "DesktopUI2\\AvaloniaHwndHost\\AvaloniaHwndHost.csproj", @@ -38,7 +38,7 @@ "Objects\\Converters\\ConverterRevit\\ConverterRevitTests\\ConverterRevitTestsShared\\ConverterRevitTestsShared.shproj", "Objects\\Converters\\ConverterRevit\\ConverterRevitTests\\TestGenerator\\TestGenerator.csproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorRevit/ConnectorRevit/Entry/App.cs b/ConnectorRevit/ConnectorRevit/Entry/App.cs index 9b8c8a9a7e..19a2e9609f 100644 --- a/ConnectorRevit/ConnectorRevit/Entry/App.cs +++ b/ConnectorRevit/ConnectorRevit/Entry/App.cs @@ -7,6 +7,7 @@ using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.UI; using ConnectorRevit; +using RevitSharedResources.Extensions.SpeckleExtensions; using RevitSharedResources.Models; using Speckle.BatchUploader.Sdk; using Speckle.BatchUploader.OperationDriver; @@ -22,8 +23,12 @@ public class App : IExternalApplication public static UIControlledApplication UICtrlApp { get; set; } + private bool _initialized; + public Result OnStartup(UIControlledApplication application) { + InitializeConnector(); + //Always initialize RevitTask ahead of time within Revit API context APIContext.Initialize(application); @@ -35,7 +40,17 @@ public Result OnStartup(UIControlledApplication application) { application.CreateRibbonTab(tabName); } - catch { } + catch (Autodesk.Revit.Exceptions.ArgumentException) + { + // exception occurs when the speckle tab has already been created. + // this happens when both the dui2 and the dui3 connectors are installed. Can be safely ignored. + } + catch (Autodesk.Revit.Exceptions.InvalidOperationException ex) + { + SpeckleLog.Logger.Warning(ex, "User has too many Revit add-on tabs installed"); + NotifyUserOfErrorStartingConnector(ex); + return Result.Failed; + } var specklePanel = application.CreateRibbonPanel(tabName, "Speckle 2"); @@ -124,18 +139,10 @@ Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e { try { - // We need to hook into the AssemblyResolve event before doing anything else - // or we'll run into unresolved issues loading dependencies - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolve); - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - System.Windows.Forms.Application.ThreadException += Application_ThreadException; + InitializeConnector(); AppInstance = new UIApplication(sender as Application); - Setup.Init(ConnectorBindingsRevit.HostAppNameVersion, ConnectorBindingsRevit.HostAppName); - - //DUI2 - pre build app, so that it's faster to open up - SpeckleRevitCommand.InitAvalonia(); var bindings = new ConnectorBindingsRevit(AppInstance); bindings.RegisterAppEvents(); SpeckleRevitCommand.Bindings = bindings; @@ -154,28 +161,15 @@ Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e //AppInstance.ViewActivated += new EventHandler(Application_ViewActivated); } - catch (Exception ex) + catch (KitException ex) + { + SpeckleLog.Logger.Warning(ex, "Error loading kit on startup"); + NotifyUserOfErrorStartingConnector(ex); + } + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Fatal(ex, "Failed to load Speckle app"); - var td = new TaskDialog("Error loading Speckle"); - if (ex is KitException) - { - td.MainContent = ex.Message; - } - else - { - td.MainContent = - $"Oh no! Something went wrong while loading Speckle, please report it on the forum:\n\n{ex.Message}"; - } - - td.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Ask for help on our Community Forum"); - - TaskDialogResult tResult = td.Show(); - - if (TaskDialogResult.CommandLink1 == tResult) - { - Process.Start("https://speckle.community/"); - } + NotifyUserOfErrorStartingConnector(ex); } } @@ -225,7 +219,10 @@ private ImageSource LoadPngImgSource(string sourceName, string path) ImageSource m_source = m_decoder.Frames[0]; return (m_source); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } return null; } @@ -245,4 +242,45 @@ static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) return a; } + + internal static void NotifyUserOfErrorStartingConnector(Exception ex) + { + using var td = new TaskDialog("Error loading Speckle"); + + td.MainContent = + ex is KitException + ? ex.Message + : $"Oh no! Something went wrong while loading Speckle, please report it on the forum:\n\n{ex.Message}"; + + td.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Ask for help on our Community Forum"); + + TaskDialogResult tResult = td.Show(); + + if (TaskDialogResult.CommandLink1 == tResult) + { + Process.Start("https://speckle.community/"); + } + } + + private void InitializeConnector() + { + if (_initialized) + { + return; + } + + // We need to hook into the AssemblyResolve event before doing anything else + // or we'll run into unresolved issues loading dependencies + AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolve); + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + System.Windows.Forms.Application.ThreadException += Application_ThreadException; + + // initialize the speckle logger + Setup.Init(ConnectorBindingsRevit.HostAppNameVersion, ConnectorBindingsRevit.HostAppName); + + //DUI2 - pre build app, so that it's faster to open up + SpeckleRevitCommand.InitAvalonia(); + + _initialized = true; + } } diff --git a/ConnectorRevit/ConnectorRevit/Entry/SpeckleRevitCommand.cs b/ConnectorRevit/ConnectorRevit/Entry/SpeckleRevitCommand.cs index e7324e18d7..c0a7e6f4ed 100644 --- a/ConnectorRevit/ConnectorRevit/Entry/SpeckleRevitCommand.cs +++ b/ConnectorRevit/ConnectorRevit/Entry/SpeckleRevitCommand.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Threading; @@ -12,7 +11,6 @@ using DesktopUI2.ViewModels; using DesktopUI2.Views; using Speckle.ConnectorRevit.UI; -using Speckle.Core.Logging; namespace Speckle.ConnectorRevit.Entry; @@ -56,16 +54,9 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme { if (UseDockablePanel) { - try - { - RegisterPane(); - var panel = App.AppInstance.GetDockablePane(PanelId); - panel.Show(); - } - catch (Exception ex) - { - SpeckleLog.Logger.Error(ex, "Failed to show dockable panel"); - } + RegisterPane(); + var panel = App.AppInstance.GetDockablePane(PanelId); + panel.Show(); } else { @@ -77,113 +68,77 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme internal static void RegisterPane() { - try + if (!UseDockablePanel) { - if (!UseDockablePanel) - { - return; - } - - var registered = DockablePane.PaneIsRegistered(PanelId); - var created = DockablePane.PaneExists(PanelId); - - if (registered && created) - { - _panel.Init(); - return; - } - - if (!registered) - { - //Register dockable panel - var viewModel = new MainViewModel(Bindings); - _panel = new Panel { DataContext = viewModel }; - App.AppInstance.RegisterDockablePane(PanelId, "Speckle", _panel); - _panel.Init(); - } - created = DockablePane.PaneExists(PanelId); + return; + } - //if revit was launched double-clicking on a Revit file, we're screwed - //could maybe show the old window? - if (!created && App.AppInstance.Application.Documents.Size > 0) - { - TaskDialog mainDialog = new("Dockable Panel Issue"); - mainDialog.MainInstruction = "Dockable Panel Issue"; - mainDialog.MainContent = - "Revit cannot properly register Dockable Panels when launched by double-clicking a Revit file. " - + "Please close and re-open Revit without launching a file OR open/create a new project to trigger the Speckle panel registration."; + var registered = DockablePane.PaneIsRegistered(PanelId); + var created = DockablePane.PaneExists(PanelId); - // Set footer text. Footer text is usually used to link to the help document. - mainDialog.FooterText = - "" + "Click here for more info"; + if (registered && created) + { + _panel.Init(); + return; + } - mainDialog.Show(); - } + if (!registered) + { + //Register dockable panel + var viewModel = new MainViewModel(Bindings); + _panel = new Panel { DataContext = viewModel }; + App.AppInstance.RegisterDockablePane(PanelId, "Speckle", _panel); + _panel.Init(); } - catch (Exception ex) + created = DockablePane.PaneExists(PanelId); + + //if revit was launched double-clicking on a Revit file, we're screwed + //could maybe show the old window? + if (!created && App.AppInstance.Application.Documents.Size > 0) { - SpeckleLog.Logger.Fatal(ex, "Failed to load Speckle command for host app"); - var td = new TaskDialog("Error"); - td.MainContent = - $"Oh no! Something went wrong while loading Speckle, please report it on the forum:\n{ex.Message}"; - td.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Report issue on our Community Forum"); + TaskDialog mainDialog = new("Dockable Panel Issue"); + mainDialog.MainInstruction = "Dockable Panel Issue"; + mainDialog.MainContent = + "Revit cannot properly register Dockable Panels when launched by double-clicking a Revit file. " + + "Please close and re-open Revit without launching a file OR open/create a new project to trigger the Speckle panel registration."; - TaskDialogResult tResult = td.Show(); + // Set footer text. Footer text is usually used to link to the help document. + mainDialog.FooterText = + "" + "Click here for more info"; - if (TaskDialogResult.CommandLink1 == tResult) - { - Process.Start("https://speckle.community/"); - } + mainDialog.Show(); } } public static void CreateOrFocusSpeckle(bool showWindow = true) { - try + if (MainWindow == null) { - if (MainWindow == null) - { - var viewModel = new MainViewModel(Bindings); - MainWindow = new MainWindow { DataContext = viewModel }; - - //massive hack: we start the avalonia main loop and stop it immediately (since it's thread blocking) - //to avoid an annoying error when closing revit - var cts = new CancellationTokenSource(); - cts.CancelAfter(100); - AvaloniaApp.Run(cts.Token); - } - - if (showWindow) - { - MainWindow.Show(); - MainWindow.Activate(); - - //required to gracefully quit avalonia and the skia processes - //can also be used to manually do so - //https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes - - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var parentHwnd = App.AppInstance.MainWindowHandle; - var hwnd = MainWindow.PlatformImpl.Handle.Handle; - SetWindowLongPtr(hwnd, GWL_HWNDPARENT, parentHwnd); - } - } + var viewModel = new MainViewModel(Bindings); + MainWindow = new MainWindow { DataContext = viewModel }; + + //massive hack: we start the avalonia main loop and stop it immediately (since it's thread blocking) + //to avoid an annoying error when closing revit + var cts = new CancellationTokenSource(); + cts.CancelAfter(100); + AvaloniaApp.Run(cts.Token); } - catch (Exception ex) + + if (showWindow) { - SpeckleLog.Logger.Fatal(ex, "Failed to create main window"); - var td = new TaskDialog("Error"); - td.MainContent = - $"Oh no! Something went wrong while loading Speckle, please report it on the forum:\n{ex.Message}"; - td.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Report issue on our Community Forum"); + MainWindow.Show(); + MainWindow.Activate(); + + //required to gracefully quit avalonia and the skia processes + //can also be used to manually do so + //https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes - TaskDialogResult tResult = td.Show(); - if (TaskDialogResult.CommandLink1 == tResult) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Process.Start("https://speckle.community/"); + var parentHwnd = App.AppInstance.MainWindowHandle; + var hwnd = MainWindow.PlatformImpl.Handle.Handle; + SetWindowLongPtr(hwnd, GWL_HWNDPARENT, parentHwnd); } } } diff --git a/ConnectorRevit/ConnectorRevit/Revit/FamilyLoadOption.cs b/ConnectorRevit/ConnectorRevit/Revit/FamilyLoadOption.cs index 6613d1e5f4..4857769541 100644 --- a/ConnectorRevit/ConnectorRevit/Revit/FamilyLoadOption.cs +++ b/ConnectorRevit/ConnectorRevit/Revit/FamilyLoadOption.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; using Autodesk.Revit.DB; namespace ConnectorRevit.Revit; diff --git a/ConnectorRevit/ConnectorRevit/Storage/RevitObjectCache.cs b/ConnectorRevit/ConnectorRevit/Storage/RevitObjectCache.cs index 7f515abe76..c69a26cbc9 100644 --- a/ConnectorRevit/ConnectorRevit/Storage/RevitObjectCache.cs +++ b/ConnectorRevit/ConnectorRevit/Storage/RevitObjectCache.cs @@ -1,7 +1,6 @@ #nullable enable using System; using System.Collections.Generic; -using Autodesk.Revit.DB; using RevitSharedResources.Interfaces; namespace ConnectorRevit.Storage; diff --git a/ConnectorRevit/ConnectorRevit/Storage/StreamStateCache.cs b/ConnectorRevit/ConnectorRevit/Storage/StreamStateCache.cs index 716a8417c8..fa99ff382c 100644 --- a/ConnectorRevit/ConnectorRevit/Storage/StreamStateCache.cs +++ b/ConnectorRevit/ConnectorRevit/Storage/StreamStateCache.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; diff --git a/ConnectorRevit/ConnectorRevit/Storage/StreamStateManager.cs b/ConnectorRevit/ConnectorRevit/Storage/StreamStateManager.cs index fffb3baabe..3c44df3989 100644 --- a/ConnectorRevit/ConnectorRevit/Storage/StreamStateManager.cs +++ b/ConnectorRevit/ConnectorRevit/Storage/StreamStateManager.cs @@ -4,6 +4,8 @@ using Autodesk.Revit.DB; using Autodesk.Revit.DB.ExtensibleStorage; using DesktopUI2.Models; +using RevitSharedResources.Extensions.SpeckleExtensions; +using Speckle.Core.Logging; using Speckle.Newtonsoft.Json; namespace Speckle.ConnectorRevit.Storage; @@ -36,8 +38,9 @@ public static List ReadState(Document doc) return states; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); return new List(); } } diff --git a/ConnectorRevit/ConnectorRevit/TypeMapping/ElementTypeMapper.cs b/ConnectorRevit/ConnectorRevit/TypeMapping/ElementTypeMapper.cs index e28b1ca96a..c947336fdb 100644 --- a/ConnectorRevit/ConnectorRevit/TypeMapping/ElementTypeMapper.cs +++ b/ConnectorRevit/ConnectorRevit/TypeMapping/ElementTypeMapper.cs @@ -18,7 +18,6 @@ using Speckle.Core.Models.GraphTraversal; using Speckle.Newtonsoft.Json; using DB = Autodesk.Revit.DB; -using SHC = RevitSharedResources.Helpers.Categories; namespace ConnectorRevit.TypeMapping; @@ -40,7 +39,7 @@ internal sealed class ElementTypeMapper /// /// /// - /// + /// public ElementTypeMapper( ISpeckleConverter converter, IRevitDocumentAggregateCache revitDocumentAggregateCache, @@ -53,7 +52,7 @@ Document doc if (converter is not IRevitElementTypeRetriever typeRetriever) { - throw new ArgumentException($"Converter does not implement interface {nameof(IRevitElementTypeRetriever)}"); + throw new SpeckleException($"Converter does not implement interface {nameof(IRevitElementTypeRetriever)}"); } else { @@ -62,7 +61,7 @@ Document doc if (converter is not IAllRevitCategoriesExposer typeInfoExposer) { - throw new ArgumentException($"Converter does not implement interface {nameof(IRevitElementTypeRetriever)}"); + throw new SpeckleException($"Converter does not implement interface {nameof(IRevitElementTypeRetriever)}"); } else { @@ -70,7 +69,7 @@ Document doc } this.revitDocumentAggregateCache = - revitDocumentAggregateCache ?? throw new ArgumentException($"RevitDocumentAggregateCache cannot be null"); + revitDocumentAggregateCache ?? throw new SpeckleException($"RevitDocumentAggregateCache cannot be null"); var traversalFunc = DefaultTraversal.CreateTraverseFunc(converter); foreach (var appObj in flattenedCommit) @@ -218,8 +217,9 @@ await Dispatcher.UIThread { StreamViewModel.HandleCommandException(ex, false, "ImportTypesCommand"); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); var speckleEx = new SpeckleException(ex.Message, ex); StreamViewModel.HandleCommandException(speckleEx, false, "ImportTypesCommand"); } @@ -354,9 +354,9 @@ string category previousMappingExists = true; return JsonConvert.DeserializeObject(mappingSetting.MappingJson, settings); } - catch + catch (Exception ex) when (!ex.IsFatal()) { - // couldn't deserialize so just return null + SpeckleLog.Logger.LogDefaultError(ex); } } previousMappingExists = false; diff --git a/ConnectorRevit/ConnectorRevit/TypeMapping/FamilyImporter.cs b/ConnectorRevit/ConnectorRevit/TypeMapping/FamilyImporter.cs index a34faec090..d7cf9a0921 100644 --- a/ConnectorRevit/ConnectorRevit/TypeMapping/FamilyImporter.cs +++ b/ConnectorRevit/ConnectorRevit/TypeMapping/FamilyImporter.cs @@ -205,11 +205,10 @@ await APIContext AddSymbolToAllSymbols(allSymbols, xmlDoc, nsman, familyName, elementTypes); // delete the newly created xml file - try + if (System.IO.File.Exists(xmlPath)) { System.IO.File.Delete(xmlPath); } - catch (Exception ex) { } } //close current dialog body diff --git a/ConnectorRevit/ConnectorRevit/TypeMapping/HostTypeContainer.cs b/ConnectorRevit/ConnectorRevit/TypeMapping/HostTypeContainer.cs index 49e364da98..36275b45df 100644 --- a/ConnectorRevit/ConnectorRevit/TypeMapping/HostTypeContainer.cs +++ b/ConnectorRevit/ConnectorRevit/TypeMapping/HostTypeContainer.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using DesktopUI2.Models.TypeMappingOnReceive; using DesktopUI2.ViewModels; diff --git a/ConnectorRevit/ConnectorRevit/TypeMapping/RevitMappingValue.cs b/ConnectorRevit/ConnectorRevit/TypeMapping/RevitMappingValue.cs index e6c56feb30..d098813a2d 100644 --- a/ConnectorRevit/ConnectorRevit/TypeMapping/RevitMappingValue.cs +++ b/ConnectorRevit/ConnectorRevit/TypeMapping/RevitMappingValue.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; using System.Runtime.Serialization; using System.Text; using DesktopUI2.Models.TypeMappingOnReceive; -using ReactiveUI; namespace ConnectorRevit.TypeMapping; diff --git a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Events.cs b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Events.cs index ed0c95aa5e..b0dc9f2312 100644 --- a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Events.cs +++ b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Events.cs @@ -7,7 +7,6 @@ using Avalonia.Controls; using DesktopUI2.Models; using DesktopUI2.ViewModels; -using DesktopUI2.Views; using DesktopUI2.Views.Windows.Dialogs; using RevitSharedResources.Models; using Speckle.ConnectorRevit.Entry; @@ -15,6 +14,7 @@ using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; +using RevitSharedResources.Extensions.SpeckleExtensions; namespace Speckle.ConnectorRevit.UI; @@ -38,7 +38,10 @@ await APIContext }) .ConfigureAwait(false); } - catch (Exception ex) + // note : I don't think this exception catch is necessary, but this is an async VOID instead + // of an async Task. Revit WILL CRASH if this method tries to throw an error, so keeping this + // catch out of an abundance of caution + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Fatal( ex, @@ -109,21 +112,9 @@ private void ShowImportExportAlert() var dialog = new ImportExportAlert(); dialog.LaunchAction = () => { - try - { - SpeckleRevitCommand.RegisterPane(); - var panel = App.AppInstance.GetDockablePane(SpeckleRevitCommand.PanelId); - panel.Show(); - } - catch (Exception ex) - { - SpeckleLog.Logger.Fatal( - ex, - "Swallowing exception in {methodName}: {exceptionMessage}", - nameof(ShowImportExportAlert), - ex.Message - ); - } + SpeckleRevitCommand.RegisterPane(); + var panel = App.AppInstance.GetDockablePane(SpeckleRevitCommand.PanelId); + panel.Show(); }; dialog.WindowStartupLocation = WindowStartupLocation.CenterScreen; dialog.Show(); @@ -198,7 +189,10 @@ private async void SendScheduledStream(string slug, string message = "") ); } } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } } //checks whether to refresh the stream list in case the user changes active view and selects a different document @@ -234,7 +228,10 @@ private void RevitApp_ViewActivated(object sender, Autodesk.Revit.UI.Events.View MainViewModel.Instance.NavigateToDefaultScreen(); } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } } private void Application_DocumentClosed(object sender, Autodesk.Revit.DB.Events.DocumentClosedEventArgs e) @@ -260,7 +257,10 @@ private void Application_DocumentClosed(object sender, Autodesk.Revit.DB.Events. MainViewModel.Instance.NavigateToDefaultScreen(); } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } } // this method is triggered when there are changes in the active document @@ -306,92 +306,75 @@ private void Application_DocumentOpened(object sender, Autodesk.Revit.DB.Events. public override async Task Open3DView(List viewCoordinates, string viewName = "") { - try + var views = new FilteredElementCollector(CurrentDoc.Document).OfClass(typeof(View3D)).ToElements().Cast(); + var viewtypes = new FilteredElementCollector(CurrentDoc.Document) + .OfClass(typeof(ViewFamilyType)) + .ToElements() + .Cast() + .Where(x => x.ViewFamily == ViewFamily.ThreeDimensional); + + //hacky but the current comments camera is not a Base object + //so it cannot be passed automatically to the converter + //making a dummy one here + var speckleCamera = new Base(); + speckleCamera["isHackySpeckleCamera"] = true; + speckleCamera["coordinates"] = viewCoordinates; + + //when in a perspective view, it's not possible to open any transaction (txs adsk) + //so we're switching to any other non perspective view here + if (CurrentDoc.ActiveView.ViewType == ViewType.ThreeD) { - var views = new FilteredElementCollector(CurrentDoc.Document).OfClass(typeof(View3D)).ToElements().Cast(); - var viewtypes = new FilteredElementCollector(CurrentDoc.Document) - .OfClass(typeof(ViewFamilyType)) - .ToElements() - .Cast() - .Where(x => x.ViewFamily == ViewFamily.ThreeDimensional); - - //hacky but the current comments camera is not a Base object - //so it cannot be passed automatically to the converter - //making a dummy one here - var speckleCamera = new Base(); - speckleCamera["isHackySpeckleCamera"] = true; - speckleCamera["coordinates"] = viewCoordinates; - - //when in a perspective view, it's not possible to open any transaction (txs adsk) - //so we're switching to any other non perspective view here - if (CurrentDoc.ActiveView.ViewType == ViewType.ThreeD) + var activeView = CurrentDoc.ActiveView as View3D; + if (activeView.IsPerspective) { - var activeView = CurrentDoc.ActiveView as View3D; - if (activeView.IsPerspective) + var nonPerspectiveView = views.FirstOrDefault(x => !x.IsPerspective); + if (nonPerspectiveView != null) { - var nonPerspectiveView = views.FirstOrDefault(x => !x.IsPerspective); - if (nonPerspectiveView != null) - { - CurrentDoc.ActiveView = nonPerspectiveView; - } + CurrentDoc.ActiveView = nonPerspectiveView; } } + } - var perspView = views.FirstOrDefault(o => o.Name == "SpeckleCommentView"); + var perspView = views.FirstOrDefault(o => o.Name == "SpeckleCommentView"); - await APIContext.Run(app => + await APIContext.Run(app => + { + using (var t = new Transaction(CurrentDoc.Document, $"Open Comment View")) { - using (var t = new Transaction(CurrentDoc.Document, $"Open Comment View")) - { - t.Start(); + t.Start(); - var converter = (ISpeckleConverter)Activator.CreateInstance(Converter.GetType()); - converter.SetContextDocument(CurrentDoc.Document); - var viewOrientation3D = converter.ConvertToNative(speckleCamera) as ViewOrientation3D; + var converter = (ISpeckleConverter)Activator.CreateInstance(Converter.GetType()); + converter.SetContextDocument(CurrentDoc.Document); + var viewOrientation3D = converter.ConvertToNative(speckleCamera) as ViewOrientation3D; - //txs bcfier - if (perspView == null) - { - perspView = View3D.CreatePerspective(CurrentDoc.Document, viewtypes.First().Id); - perspView.Name = "SpeckleCommentView"; - } - perspView.SetOrientation(viewOrientation3D); - perspView.CropBoxActive = false; - perspView.CropBoxVisible = false; - perspView.DisplayStyle = DisplayStyle.Shading; + //txs bcfier + if (perspView == null) + { + perspView = View3D.CreatePerspective(CurrentDoc.Document, viewtypes.First().Id); + perspView.Name = "SpeckleCommentView"; + } + perspView.SetOrientation(viewOrientation3D); + perspView.CropBoxActive = false; + perspView.CropBoxVisible = false; + perspView.DisplayStyle = DisplayStyle.Shading; - // the default phase was not looking good, picking the one of the View3D - if (views.Any()) + // the default phase was not looking good, picking the one of the View3D + if (views.Any()) + { + var viewPhase = views.First().get_Parameter(BuiltInParameter.VIEW_PHASE); + if (viewPhase != null) { - var viewPhase = views.First().get_Parameter(BuiltInParameter.VIEW_PHASE); - if (viewPhase != null) - { - perspView.get_Parameter(BuiltInParameter.VIEW_PHASE).Set(viewPhase.AsElementId()); - } + perspView.get_Parameter(BuiltInParameter.VIEW_PHASE).Set(viewPhase.AsElementId()); } - - t.Commit(); } - // needs to be outside the transaction - CurrentDoc.ActiveView = perspView; - // "refresh" the active view, txs Connor - var uiView = CurrentDoc.GetOpenUIViews().FirstOrDefault(uv => uv.ViewId.Equals(perspView.Id)); - uiView.Zoom(1); - }); - - //needed to force refresh the active view - } - catch (Exception ex) - { - SpeckleLog.Logger.Error(ex, "Failed to open view"); - MainUserControl.NotificationManager.Show( - new PopUpNotificationViewModel() - { - Title = "📷 Open View Error", - Message = $"Could not open the view: {ex.Message}", - Type = Avalonia.Controls.Notifications.NotificationType.Error - } - ); - } + + t.Commit(); + } + // needs to be outside the transaction + CurrentDoc.ActiveView = perspView; + // "refresh" the active view, txs Connor + var uiView = CurrentDoc.GetOpenUIViews().FirstOrDefault(uv => uv.ViewId.Equals(perspView.Id)); + uiView.Zoom(1); + }); } } diff --git a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Previews.cs b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Previews.cs index dbd90b3eb0..e07220ea7d 100644 --- a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Previews.cs +++ b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Previews.cs @@ -5,7 +5,6 @@ using DesktopUI2.ViewModels; using Speckle.Core.Api; using Speckle.Core.Kits; -using Speckle.Core.Logging; using Speckle.Core.Models; using System; using System.Collections.Generic; @@ -15,7 +14,6 @@ using Autodesk.Revit.DB.DirectContext3D; using RevitSharedResources.Interfaces; using RevitSharedResources.Models; -using ConnectorRevit.Revit; namespace Speckle.ConnectorRevit.UI; @@ -27,65 +25,58 @@ public partial class ConnectorBindingsRevit public override async Task PreviewReceive(StreamState state, ProgressViewModel progress) { - try + // first check if commit is the same and preview objects have already been generated + Commit commit = await ConnectorHelpers.GetCommitFromState(state, progress.CancellationToken); + progress.Report = new ProgressReport(); + + if (commit.id != SelectedReceiveCommit) { - // first check if commit is the same and preview objects have already been generated - Commit commit = await ConnectorHelpers.GetCommitFromState(state, progress.CancellationToken); - progress.Report = new ProgressReport(); + // check for converter + var converter = KitManager.GetDefaultKit().LoadConverter(ConnectorRevitUtils.RevitAppName); + converter.SetContextDocument(CurrentDoc.Document); - if (commit.id != SelectedReceiveCommit) + var settings = new Dictionary(); + CurrentSettings = state.Settings; + foreach (var setting in state.Settings) { - // check for converter - var converter = KitManager.GetDefaultKit().LoadConverter(ConnectorRevitUtils.RevitAppName); - converter.SetContextDocument(CurrentDoc.Document); + settings.Add(setting.Slug, setting.Selection); + } - var settings = new Dictionary(); - CurrentSettings = state.Settings; - foreach (var setting in state.Settings) - { - settings.Add(setting.Slug, setting.Selection); - } + settings["preview"] = "true"; + converter.SetConverterSettings(settings); - settings["preview"] = "true"; - converter.SetConverterSettings(settings); + var commitObject = await ConnectorHelpers.ReceiveCommit(commit, state, progress); - var commitObject = await ConnectorHelpers.ReceiveCommit(commit, state, progress); + Preview.Clear(); + StoredObjects.Clear(); - Preview.Clear(); - StoredObjects.Clear(); + Preview = FlattenCommitObject(commitObject, converter); + foreach (var previewObj in Preview) + { + progress.Report.Log(previewObj); + } - Preview = FlattenCommitObject(commitObject, converter); - foreach (var previewObj in Preview) + IConvertedObjectsCache convertedObjects = null; + await APIContext + .Run(app => { - progress.Report.Log(previewObj); - } - - IConvertedObjectsCache convertedObjects = null; - await APIContext - .Run(app => + using (var t = new Transaction(CurrentDoc.Document, $"Baking stream {state.StreamId}")) { - using (var t = new Transaction(CurrentDoc.Document, $"Baking stream {state.StreamId}")) - { - t.Start(); - convertedObjects = ConvertReceivedObjects(converter, progress, new TransactionManager(null, null)); - t.Commit(); - } - - AddMultipleRevitElementServers(convertedObjects); - }) - .ConfigureAwait(false); - } - else // just generate the log - { - foreach (var previewObj in Preview) - { - progress.Report.Log(previewObj); - } - } + t.Start(); + convertedObjects = ConvertReceivedObjects(converter, progress, new TransactionManager(null, null)); + t.Commit(); + } + + AddMultipleRevitElementServers(convertedObjects); + }) + .ConfigureAwait(false); } - catch (Exception ex) + else // just generate the log { - SpeckleLog.Logger.Error(ex, "Failed to preview receive: {exceptionMessage}", ex.Message); + foreach (var previewObj in Preview) + { + progress.Report.Log(previewObj); + } } return null; @@ -152,34 +143,27 @@ public void UnregisterServers() public override void PreviewSend(StreamState state, ProgressViewModel progress) { - try + var converter = (ISpeckleConverter)Activator.CreateInstance(Converter.GetType()); + var filterObjs = GetSelectionFilterObjects(converter, state.Filter); + foreach (var filterObj in filterObjs) { - var converter = (ISpeckleConverter)Activator.CreateInstance(Converter.GetType()); - var filterObjs = GetSelectionFilterObjects(converter, state.Filter); - foreach (var filterObj in filterObjs) + var descriptor = ConnectorRevitUtils.ObjectDescriptor(filterObj); + var reportObj = new ApplicationObject(filterObj.UniqueId, descriptor); + if (!converter.CanConvertToSpeckle(filterObj)) { - var descriptor = ConnectorRevitUtils.ObjectDescriptor(filterObj); - var reportObj = new ApplicationObject(filterObj.UniqueId, descriptor); - if (!converter.CanConvertToSpeckle(filterObj)) - { - reportObj.Update( - status: ApplicationObject.State.Skipped, - logItem: $"Sending this object type is not supported in Revit" - ); - } - else - { - reportObj.Update(status: ApplicationObject.State.Created); - } - - progress.Report.Log(reportObj); + reportObj.Update( + status: ApplicationObject.State.Skipped, + logItem: $"Sending this object type is not supported in Revit" + ); + } + else + { + reportObj.Update(status: ApplicationObject.State.Created); } - SelectClientObjects(filterObjs.Select(o => o.UniqueId).ToList(), true); - } - catch (Exception ex) - { - SpeckleLog.Logger.Error(ex, "Failed to preview send: {exceptionMessage}", ex.Message); + progress.Report.Log(reportObj); } + + SelectClientObjects(filterObjs.Select(o => o.UniqueId).ToList(), true); } } diff --git a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Receive.cs b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Receive.cs index 19f7e9d36f..5d7cf33b84 100644 --- a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Receive.cs +++ b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Receive.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Autodesk.Revit.DB; using Avalonia.Threading; -using ConnectorRevit.Revit; using ConnectorRevit.Storage; using ConnectorRevit.TypeMapping; using DesktopUI2; @@ -22,7 +20,6 @@ using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; -using Speckle.Core.Transports; namespace Speckle.ConnectorRevit.UI; @@ -85,7 +82,6 @@ await ConnectorHelpers.TryCommitReceived( // share the same revit element cache between the connector and converter converter.SetContextDocument(revitDocumentAggregateCache); -#pragma warning disable CA1031 // Do not catch general exception types try { var elementTypeMapper = new ElementTypeMapper( @@ -102,21 +98,17 @@ await elementTypeMapper ) .ConfigureAwait(false); } - catch (Exception ex) + catch (SpeckleException ex) { - var speckleEx = new SpeckleException($"Failed to map incoming types to Revit types. Reason: {ex.Message}", ex); - StreamViewModel.HandleCommandException(speckleEx, false, "MapIncomingTypesCommand"); - progress.Report.LogOperationError( - new Exception("Could not update receive object with user types. Using default mapping.", ex) - ); + SpeckleLog.Logger.Warning("Failed to map incoming types to Revit types. Reason: {ex.Message}", ex); + StreamViewModel.HandleCommandException(ex, false, "MapIncomingTypesCommand"); } finally { MainViewModel.CloseDialog(); } -#pragma warning restore CA1031 // Do not catch general exception types - var (success, exception) = await APIContext + await APIContext .Run(_ => { using var transactionManager = new TransactionManager(state.StreamId, CurrentDoc.Document); @@ -135,41 +127,32 @@ await elementTypeMapper previousObjects.AddConvertedElements(convertedObjects); transactionManager.Finish(); - return (true, null); } - catch (Exception ex) + catch (OperationCanceledException) when (progress.CancellationToken.IsCancellationRequested) + { + transactionManager.RollbackAll(); + throw; + } + catch (SpeckleNonUserFacingException ex) { SpeckleLog.Logger.Error(ex, "Rolling back connector transaction"); - - string message = $"Fatal Error: {ex.Message}"; - if (ex is OperationCanceledException) - { - message = "Receive cancelled"; - } - - progress.Report.LogOperationError(new Exception($"{message} - Changes have been rolled back", ex)); - transactionManager.RollbackAll(); - return (false, ex); //We can't throw exceptions in from RevitTask, but we can return it along with a success status + throw; + } + catch (Autodesk.Revit.Exceptions.ApplicationException ex) + { + SpeckleLog.Logger.Error(ex, "Rolling back connector transaction"); + transactionManager.RollbackAll(); + throw; + } + finally + { + revitDocumentAggregateCache.InvalidateAll(); + CurrentOperationCancellation = null; } }) .ConfigureAwait(false); - revitDocumentAggregateCache.InvalidateAll(); - CurrentOperationCancellation = null; - - if (!success) - { - switch (exception) - { - case OperationCanceledException when progress.CancellationToken.IsCancellationRequested: - case SpeckleNonUserFacingException: - throw exception; - default: - throw new SpeckleException(exception.Message, exception); - } - } - return state; } @@ -200,9 +183,10 @@ IConvertedObjectsCache convertedObjects { CurrentDoc.Document.Delete(elementToDelete.Id); } - catch + catch (Autodesk.Revit.Exceptions.ArgumentException) { - // unable to delete previously recieved object + // unable to delete object that was previously received and then removed from the stream + // because it was already deleted by the user. This isn't an issue and can safely be ignored. } } @@ -472,7 +456,7 @@ out _ // the struct must be saved to the cache again or the "numberOfTimesCaught" increment will not persist notReadyDataCache.Set(@base.id, notReadyData); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { transactionManager.RollbackSubTransaction(); SpeckleLog.Logger.Warning(ex, "Failed to convert due to unexpected error."); diff --git a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Selection.cs b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Selection.cs index 8eeac3c409..a01c341f0f 100644 --- a/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Selection.cs +++ b/ConnectorRevit/ConnectorRevit/UI/ConnectorBindingsRevit.Selection.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; -using ConnectorRevit; using DesktopUI2.Models.Filters; using DesktopUI2.Models.Settings; using RevitSharedResources.Extensions.SpeckleExtensions; diff --git a/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/ILoggerExtensions.cs b/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/ILoggerExtensions.cs new file mode 100644 index 0000000000..d04b193877 --- /dev/null +++ b/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/ILoggerExtensions.cs @@ -0,0 +1,13 @@ +using System; +using System.Runtime.CompilerServices; +using Serilog; + +namespace RevitSharedResources.Extensions.SpeckleExtensions; + +public static class ILoggerExtensions +{ + public static void LogDefaultError(this ILogger logger, Exception ex, [CallerMemberName] string caller = null) + { + logger.Error(ex, "Method named {caller} threw an error of type {type}", caller, ex.GetType()); + } +} diff --git a/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/IRevitDocumentAggregateCacheExtensions.cs b/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/IRevitDocumentAggregateCacheExtensions.cs index 4b8e901fa7..7c3352ae8b 100644 --- a/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/IRevitDocumentAggregateCacheExtensions.cs +++ b/ConnectorRevit/RevitSharedResources/Extensions/SpeckleExtensions/IRevitDocumentAggregateCacheExtensions.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; using Autodesk.Revit.DB; -using RevitSharedResources.Helpers; using RevitSharedResources.Interfaces; using SCH = RevitSharedResources.Helpers.Categories; diff --git a/ConnectorRevit/RevitSharedResources/Helpers/Extensions.cs b/ConnectorRevit/RevitSharedResources/Helpers/Extensions.cs index b3b10a1ad9..7854aff3d1 100644 --- a/ConnectorRevit/RevitSharedResources/Helpers/Extensions.cs +++ b/ConnectorRevit/RevitSharedResources/Helpers/Extensions.cs @@ -47,14 +47,12 @@ public static bool IsPhysicalElement(this Element e) /// This function will never throw, returning false instead public static bool HasCategory(this IEnumerable categories, Category category) { - try - { - return categories.Select(x => (int)x).Contains(category.Id.IntegerValue); - } - catch (Exception e) + if (category?.Id?.IntegerValue is not int categoryInt) { return false; } + + return categories.Select(x => (int)x).Contains(categoryInt); } /// diff --git a/ConnectorRevit/RevitSharedResources/Interfaces/IAllRevitCategories.cs b/ConnectorRevit/RevitSharedResources/Interfaces/IAllRevitCategories.cs index 7abb27d3ca..b55d305d18 100644 --- a/ConnectorRevit/RevitSharedResources/Interfaces/IAllRevitCategories.cs +++ b/ConnectorRevit/RevitSharedResources/Interfaces/IAllRevitCategories.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Speckle.Core.Models; namespace RevitSharedResources.Interfaces; diff --git a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilder.cs b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilder.cs index 9530d2c5ef..44bbe7e685 100644 --- a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilder.cs +++ b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilder.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; using Autodesk.Revit.DB; using Speckle.Core.Models; diff --git a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilderExposer.cs b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilderExposer.cs index b656c4c068..b90116adb0 100644 --- a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilderExposer.cs +++ b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitCommitObjectBuilderExposer.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace RevitSharedResources.Interfaces; public interface IRevitCommitObjectBuilderExposer diff --git a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitDocumentAggregateCache.cs b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitDocumentAggregateCache.cs index 36f9fdaf9e..e5fa5549ec 100644 --- a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitDocumentAggregateCache.cs +++ b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitDocumentAggregateCache.cs @@ -1,7 +1,5 @@ #nullable enable using System; -using System.Collections.Generic; -using System.Text; using Autodesk.Revit.DB; namespace RevitSharedResources.Interfaces; diff --git a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitObjectCache.cs b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitObjectCache.cs index af7931d18a..90116be752 100644 --- a/ConnectorRevit/RevitSharedResources/Interfaces/IRevitObjectCache.cs +++ b/ConnectorRevit/RevitSharedResources/Interfaces/IRevitObjectCache.cs @@ -1,7 +1,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Text; namespace RevitSharedResources.Interfaces; diff --git a/ConnectorRevit/RevitSharedResources/Models/APIContext.cs b/ConnectorRevit/RevitSharedResources/Models/APIContext.cs index 5738eba7dd..223186ff64 100644 --- a/ConnectorRevit/RevitSharedResources/Models/APIContext.cs +++ b/ConnectorRevit/RevitSharedResources/Models/APIContext.cs @@ -109,6 +109,11 @@ public ExternalEventHandler(Func func) public HandlerStatus Status { get; private set; } = HandlerStatus.NotStarted; public TParameter Parameter { get; private set; } + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "This is a very generic utility method for running things in a Revit context. If the result of the Run method is awaited, then the exception caught here will be raised there." + )] public void Execute(UIApplication app) { Status = HandlerStatus.Started; diff --git a/ConnectorRevit/RevitSharedResources/Models/ConversionNotReadyCacheData.cs b/ConnectorRevit/RevitSharedResources/Models/ConversionNotReadyCacheData.cs index 05018a73ef..64fd0acbba 100644 --- a/ConnectorRevit/RevitSharedResources/Models/ConversionNotReadyCacheData.cs +++ b/ConnectorRevit/RevitSharedResources/Models/ConversionNotReadyCacheData.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace RevitSharedResources.Models; public struct ConversionNotReadyCacheData diff --git a/ConnectorRevit/RevitSharedResources/Models/ErrorEater.cs b/ConnectorRevit/RevitSharedResources/Models/ErrorEater.cs index 549ee848b6..1f6c53df07 100644 --- a/ConnectorRevit/RevitSharedResources/Models/ErrorEater.cs +++ b/ConnectorRevit/RevitSharedResources/Models/ErrorEater.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; -using Speckle.Core.Kits; using Speckle.Core.Logging; namespace RevitSharedResources.Models; @@ -41,7 +40,7 @@ public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAcces failuresAccessor.ResolveFailure(failure); resolvedFailures++; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException ex) { var idsToDelete = failure.GetFailingElementIds().ToList(); @@ -65,9 +64,9 @@ public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAcces failedElements.AddRange(failure.GetFailingElementIds()); // logging the error - var speckleEx = new SpeckleException($"Fatal Error: {t}"); + var speckleEx = new SpeckleException($"Unexpected error while preprocessing failures: {t}", ex); _exceptions.Add(speckleEx); - SpeckleLog.Logger.Fatal(speckleEx, "Fatal Error: {failureMessage}", t); + SpeckleLog.Logger.Error(speckleEx, "Unexpected error while preprocessing failures: {failureMessage}", t); } } } diff --git a/ConnectorRevit/RevitSharedResources/Models/TransactionManager.cs b/ConnectorRevit/RevitSharedResources/Models/TransactionManager.cs index 8ad3888c47..4a9908b2cb 100644 --- a/ConnectorRevit/RevitSharedResources/Models/TransactionManager.cs +++ b/ConnectorRevit/RevitSharedResources/Models/TransactionManager.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Autodesk.Revit.DB; -using RevitSharedResources.Interfaces; using Speckle.Core.Logging; namespace RevitSharedResources.Models; @@ -187,9 +186,10 @@ public static TResult ExecuteInTemporaryTransaction(Func funct t.Start(); result = function(); } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException ex) { // ignore because we're just going to rollback + SpeckleLog.Logger.Warning(ex, "Error occured in temporary transaction"); } finally { @@ -204,9 +204,10 @@ public static TResult ExecuteInTemporaryTransaction(Func funct t.Start(); result = function(); } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException ex) { // ignore because we're just going to rollback + SpeckleLog.Logger.Warning(ex, "Error occured in temporary transaction"); } finally { diff --git a/ConnectorRevit/RevitSharedResources/RevitSharedResources.projitems b/ConnectorRevit/RevitSharedResources/RevitSharedResources.projitems index 4f392cebd7..bf2c2d31dc 100644 --- a/ConnectorRevit/RevitSharedResources/RevitSharedResources.projitems +++ b/ConnectorRevit/RevitSharedResources/RevitSharedResources.projitems @@ -9,6 +9,7 @@ RevitSharedResources + diff --git a/ConnectorRhino/ConnectorRhino.sln b/ConnectorRhino/ConnectorRhino.sln index 0dc95d18d2..bdd51c6e59 100644 --- a/ConnectorRhino/ConnectorRhino.sln +++ b/ConnectorRhino/ConnectorRhino.sln @@ -65,7 +65,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorGrasshopper6", ".. {B74CB8C1-187B-46A6-B20B-92B8C129F3EE} = {B74CB8C1-187B-46A6-B20B-92B8C129F3EE} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConnectorGrasshopperUtils", "..\ConnectorGrasshopper\ConnectorGrasshopperUtils\ConnectorGrasshopperUtils.csproj", "{E2A8E961-6DB6-4474-9E31-0C00FEB4A067}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorGrasshopperUtils", "..\ConnectorGrasshopper\ConnectorGrasshopperUtils\ConnectorGrasshopperUtils.csproj", "{E2A8E961-6DB6-4474-9E31-0C00FEB4A067}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRhino8", "..\Objects\Converters\ConverterRhinoGh\ConverterRhino8\ConverterRhino8.csproj", "{CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectorRhino8", "ConnectorRhino8\ConnectorRhino8.csproj", "{8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverterGrasshopper8", "..\Objects\Converters\ConverterRhinoGh\ConverterGrasshopper8\ConverterGrasshopper8.csproj", "{AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConnectorGrasshopper8", "..\ConnectorGrasshopper\ConnectorGrasshopper8\ConnectorGrasshopper8.csproj", "{B3206C93-471A-43B6-8264-2A5FCAEDDF3E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -164,24 +172,44 @@ Global {E20D7D1E-0FF7-49A5-9AA9-9430901F92BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {E20D7D1E-0FF7-49A5-9AA9-9430901F92BB}.Release|Any CPU.Build.0 = Release|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU - {86920221-416E-4A66-A601-3418207E2401}.Debug Mac|Any CPU.Build.0 = Debug Mac|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Debug|Any CPU.Build.0 = Debug|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Release Mac|Any CPU.ActiveCfg = Release Mac|Any CPU - {86920221-416E-4A66-A601-3418207E2401}.Release Mac|Any CPU.Build.0 = Release Mac|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Release|Any CPU.ActiveCfg = Release|Any CPU {86920221-416E-4A66-A601-3418207E2401}.Release|Any CPU.Build.0 = Release|Any CPU - {86920221-416E-4A66-A601-3418207E2401}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU - {86920221-416E-4A66-A601-3418207E2401}.Debug Mac|Any CPU.Build.0 = Debug Mac|Any CPU - {86920221-416E-4A66-A601-3418207E2401}.Release Mac|Any CPU.ActiveCfg = Release Mac|Any CPU - {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug|Any CPU.Build.0 = Debug|Any CPU {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU - {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release|Any CPU.Build.0 = Release|Any CPU + {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Debug|Any CPU.Build.0 = Debug|Any CPU {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release Mac|Any CPU.Build.0 = Release|Any CPU + {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2A8E961-6DB6-4474-9E31-0C00FEB4A067}.Release|Any CPU.Build.0 = Release|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Release Mac|Any CPU.Build.0 = Release|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8}.Release|Any CPU.Build.0 = Release|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Release Mac|Any CPU.ActiveCfg = Release Mac|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF}.Release|Any CPU.Build.0 = Release|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Release|Any CPU.Build.0 = Release|Any CPU + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D}.Release Mac|Any CPU.ActiveCfg = Release|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Debug Mac|Any CPU.ActiveCfg = Debug Mac|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Release Mac|Any CPU.ActiveCfg = Release Mac|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -202,6 +230,10 @@ Global {B81E0F77-1ABD-4941-9D76-C0DC6B1B6B82} = {E591AEAC-C9ED-4DB3-9188-0B74FFAF7F39} {E20D7D1E-0FF7-49A5-9AA9-9430901F92BB} = {1E404CB8-22F1-439D-B58E-C23B14A45158} {86920221-416E-4A66-A601-3418207E2401} = {E591AEAC-C9ED-4DB3-9188-0B74FFAF7F39} + {CE1FE536-2EFE-42DF-A23D-2C7401C87BF8} = {F415936B-1E0C-4218-B8A8-E54F15549BBB} + {8CAB0785-FFFF-4F66-ABF0-DBC1173656DF} = {E591AEAC-C9ED-4DB3-9188-0B74FFAF7F39} + {AEBC5F3E-5B7E-4E09-AB1B-F8600130DB8D} = {F415936B-1E0C-4218-B8A8-E54F15549BBB} + {B3206C93-471A-43B6-8264-2A5FCAEDDF3E} = {E591AEAC-C9ED-4DB3-9188-0B74FFAF7F39} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1BFED19F-741B-4E11-95C0-753E2058B3D2} @@ -210,12 +242,14 @@ Global ..\ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{0f1fd0c3-875f-4689-9c4a-c56e9ab31102}*SharedItemsImports = 13 ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{6c851417-514b-4e45-9553-408377535b68}*SharedItemsImports = 5 ..\ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{86920221-416e-4a66-a601-3418207e2401}*SharedItemsImports = 5 + ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{8cab0785-ffff-4f66-abf0-dbc1173656df}*SharedItemsImports = 5 ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{9454d346-a629-40e0-9ee2-7c6933ed1530}*SharedItemsImports = 5 ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{a64acbf9-db82-4839-af99-57ed2e7989f4}*SharedItemsImports = 5 ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{b7376ec8-5d3e-47d2-96a7-748552f14c39}*SharedItemsImports = 13 ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{b74cb8c1-187b-46a6-b20b-92b8c129f3ee}*SharedItemsImports = 13 ..\ConnectorGrasshopper\ConnectorGrasshopperShared\ConnectorGrasshopperShared.projitems*{b81e0f77-1abd-4941-9d76-c0dc6b1b6b82}*SharedItemsImports = 5 ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{cae61ac4-e81a-4e69-8dd0-07b7cdf77e2e}*SharedItemsImports = 5 + ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{ce1fe536-2efe-42df-a23d-2c7401c87bf8}*SharedItemsImports = 5 ConnectorRhino\ConnectorRhinoShared\ConnectorRhinoShared.projitems*{d648bb69-b992-4d34-906e-7a547374b86c}*SharedItemsImports = 5 ..\Objects\Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{f1703d03-3edb-4389-add9-39c52c6aea19}*SharedItemsImports = 5 EndGlobalSection diff --git a/ConnectorRhino/ConnectorRhino.slnf b/ConnectorRhino/ConnectorRhino.slnf index 31cec7c7ea..40d01b1231 100644 --- a/ConnectorRhino/ConnectorRhino.slnf +++ b/ConnectorRhino/ConnectorRhino.slnf @@ -4,24 +4,28 @@ "projects": [ "ConnectorGrasshopper\\ConnectorGrasshopper6\\ConnectorGrasshopper6.csproj", "ConnectorGrasshopper\\ConnectorGrasshopper7\\ConnectorGrasshopper7.csproj", + "ConnectorGrasshopper\\ConnectorGrasshopper8\\ConnectorGrasshopper8.csproj", "ConnectorGrasshopper\\ConnectorGrasshopperShared\\ConnectorGrasshopperShared.shproj", "ConnectorGrasshopper\\ConnectorGrasshopperUtils\\ConnectorGrasshopperUtils.csproj", "ConnectorRhino\\ConnectorRhino6\\ConnectorRhino6.csproj", "ConnectorRhino\\ConnectorRhino7\\ConnectorRhino7.csproj", + "ConnectorRhino\\ConnectorRhino8\\ConnectorRhino8.csproj", "ConnectorRhino\\ConnectorRhino\\ConnectorRhinoShared\\ConnectorRhinoShared.shproj", "Core\\Core\\Core.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "Core\\Transports\\MongoDBTransport\\MongoDBTransport.csproj", "DesktopUI2\\AvaloniaHwndHost\\AvaloniaHwndHost.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", "Objects\\Converters\\ConverterRhinoGh\\ConverterGrasshopper6\\ConverterGrasshopper6.csproj", "Objects\\Converters\\ConverterRhinoGh\\ConverterGrasshopper7\\ConverterGrasshopper7.csproj", + "Objects\\Converters\\ConverterRhinoGh\\ConverterGrasshopper8\\ConverterGrasshopper8.csproj", "Objects\\Converters\\ConverterRhinoGh\\ConverterRhino6\\ConverterRhino6.csproj", "Objects\\Converters\\ConverterRhinoGh\\ConverterRhino7\\ConverterRhino7.csproj", + "Objects\\Converters\\ConverterRhinoGh\\ConverterRhino8\\ConverterRhino8.csproj", "Objects\\Converters\\ConverterRhinoGh\\ConverterRhinoGhShared\\ConverterRhinoGhShared.shproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/Plugin.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/Plugin.cs index 5d40abbe9c..da0df1c6a4 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/Plugin.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/Plugin.cs @@ -14,12 +14,15 @@ using Rhino.DocObjects; using Rhino.PlugIns; using Rhino.Runtime; -using Rhino.UI; using Serilog.Context; using Speckle.Core.Helpers; using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; +#if !MAC +using Rhino.UI; +#endif + [assembly: Guid("8dd5f30b-a13d-4a24-abdc-3e05c8c87143")] [assembly: NeutralResourcesLanguage("en")] @@ -141,7 +144,8 @@ private void RhinoDoc_EndOpenDocument(object sender, DocumentOpenEventArgs e) try { SpeckleCommandMac.CreateOrFocusSpeckle(); - } catch (Exception ex) + } + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Fatal(ex, "Failed to create or focus Speckle window"); RhinoApp.CommandLineOut.WriteLine($"Speckle error - {ex.ToFormattedString()}"); @@ -169,12 +173,16 @@ protected override LoadReturnCode OnLoad(ref string errorMessage) { try { - var logConfig = new SpeckleLogConfiguration(logToSentry: false); - var hostAppName = Utils.AppName; - var hostAppVersion = Utils.RhinoAppName; + const bool ENHANCED_LOG_CONTEXT = #if MAC - logConfig.enhancedLogContext = false; + false; +#else + true; #endif + var logConfig = new SpeckleLogConfiguration(logToSentry: false, enhancedLogContext: ENHANCED_LOG_CONTEXT); + + var hostAppName = Utils.AppName; + var hostAppVersion = Utils.RhinoAppName; SpeckleLog.Initialize(hostAppName, hostAppVersion, logConfig); SpeckleLog.Logger.Information( "Loading Speckle Plugin for host app {hostAppName} version {hostAppVersion}", @@ -182,7 +190,7 @@ protected override LoadReturnCode OnLoad(ref string errorMessage) hostAppVersion ); } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { RhinoApp.CommandLineOut.WriteLine("Failed to init speckle logger: " + e.ToFormattedString()); return LoadReturnCode.ErrorShowDialog; @@ -207,7 +215,8 @@ protected override LoadReturnCode OnLoad(ref string errorMessage) { Init(); } - catch (Exception ex) + // need investigation in seq of specific excpetions thrown (FileNotFound, TypeInitialization) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Fatal(ex, "Failed to load Speckle Plugin with {exceptionMessage}", ex.Message); errorMessage = $"Failed to load Speckle Plugin with {ex.ToFormattedString()}"; @@ -253,6 +262,8 @@ private void EnsureVersionSettings() sb.Append(@"\McNeel\Rhinoceros\6.0\UI\Plug-ins\"); #elif RHINO7 sb.Append(@"\McNeel\Rhinoceros\7.0\UI\Plug-ins\"); +#elif RHINO8 + sb.Append(@"\McNeel\Rhinoceros\8.0\UI\Plug-ins\"); #endif sb.AppendFormat("{0}.rui", Assembly.GetName().Name); @@ -260,17 +271,30 @@ private void EnsureVersionSettings() using (LogContext.PushProperty("path", path)) { - SpeckleLog.Logger.Debug("Deleting and Updating RUI settings file"); - if (File.Exists(path)) { + SpeckleLog.Logger.Information("Deleting and Updating RUI settings file"); try { File.Delete(path); } - catch (Exception ex) + catch (IOException ioEx) + { + SpeckleLog.Logger.Error( + ioEx, + "Failed to delete Speckle toolbar .rui file with {exceptionMessage}", + ioEx.Message + ); + RhinoApp.CommandLineOut.WriteLine($"Failed to delete Speckle toolbar {path} with {ioEx.ToFormattedString()}"); + } + catch (UnauthorizedAccessException uaEx) { - SpeckleLog.Logger.Warning(ex, "Failed to delete rui file {exceptionMessage}", ex.Message); + SpeckleLog.Logger.Error( + uaEx, + "Failed to delete Speckle toolbar .rui file with {exceptionMessage}", + uaEx.Message + ); + RhinoApp.CommandLineOut.WriteLine($"Failed to delete Speckle toolbar {path} with {uaEx.ToFormattedString()}"); } } } @@ -293,8 +317,10 @@ private void RhinoApp_Idle(object sender, EventArgs e) return; } #else - if (SpeckleMappingsCommandMac.MainWindow == null || !SpeckleMappingsCommandMac.MainWindow.IsVisible) - return; + if (SpeckleMappingsCommandMac.MainWindow == null || !SpeckleMappingsCommandMac.MainWindow.IsVisible) + { + return; + } #endif try @@ -311,7 +337,7 @@ private void RhinoApp_Idle(object sender, EventArgs e) MappingBindings.UpdateExistingSchemaElements(MappingBindings.GetExistingSchemaElements()); } } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) { } } private void RhinoDoc_DeselectObjects(object sender, RhinoObjectSelectionEventArgs e) diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandMac.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandMac.cs index 4cb722f3c3..a5351e526b 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandMac.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandMac.cs @@ -1,15 +1,10 @@ #if MAC using System; -using System.Runtime.InteropServices; -using System.Threading; -using Avalonia; using Avalonia.Controls; -using Avalonia.ReactiveUI; using DesktopUI2.ViewModels; using DesktopUI2.Views; using Rhino; using Rhino.Commands; -using Serilog; using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; @@ -37,7 +32,7 @@ protected override Result RunCommand(RhinoDoc doc, RunMode mode) CreateOrFocusSpeckle(); return Result.Success; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { SpeckleLog.Logger.Fatal(e, "Failed to create or focus Speckle window"); RhinoApp.CommandLineOut.WriteLine($"Speckle Error - { e.ToFormattedString() }"); diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandWin.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandWin.cs index 9bbc2f5047..866b39c1c5 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandWin.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleCommandWin.cs @@ -1,12 +1,13 @@ +#if !MAC using System; using Rhino; using Rhino.Commands; using Rhino.UI; +using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; namespace SpeckleRhino; -#if !MAC public class SpeckleCommandWin : Command { public SpeckleCommandWin() @@ -25,11 +26,14 @@ protected override Result RunCommand(RhinoDoc doc, RunMode mode) Panels.OpenPanel(typeof(DuiPanel).GUID); return Result.Success; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + // needs more investigation. logging to seq for now. + SpeckleLog.Logger.Error(e, "Failed to open Speckle Rhino Connector DuiPanel with {exceptionMessage}", e.Message); RhinoApp.CommandLineOut.WriteLine($"Speckle Error - {e.ToFormattedString()}"); return Result.Failure; } } } + #endif diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandMac.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandMac.cs index 31cccf9b65..9b46cb1364 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandMac.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandMac.cs @@ -1,16 +1,10 @@ #if MAC using System; -using System.Runtime.InteropServices; -using System.Threading; -using Avalonia; using Avalonia.Controls; -using Avalonia.ReactiveUI; -using DesktopUI2.ViewModels; using DesktopUI2.ViewModels.MappingTool; using DesktopUI2.Views; using Rhino; using Rhino.Commands; -using Serilog; using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; @@ -47,7 +41,7 @@ protected override Result RunCommand(RhinoDoc doc, RunMode mode) MainWindow.Activate(); return Result.Success; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { SpeckleLog.Logger.Fatal(e, "Failed to create or focus Speckle mappings window"); RhinoApp.CommandLineOut.WriteLine($"Speckle Error - {e.ToFormattedString()}"); diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandWin.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandWin.cs index 41e44cf13a..5a772999d5 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandWin.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Entry/SpeckleMappingsCommandWin.cs @@ -1,12 +1,14 @@ +#if !MAC + using System; using Rhino; using Rhino.Commands; using Rhino.UI; +using Speckle.Core.Logging; using Speckle.Core.Models.Extensions; namespace SpeckleRhino; -#if !MAC public class SpeckleMappingsCommandWin : Command { public SpeckleMappingsCommandWin() @@ -25,8 +27,10 @@ protected override Result RunCommand(RhinoDoc doc, RunMode mode) Panels.OpenPanel(typeof(MappingsPanel).GUID); return Result.Success; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + // needs more investigation. logging to seq for now. + SpeckleLog.Logger.Error(e, "Failed to open Speckle Rhino Mapper DuiPanel with {exceptionMessage}", e.Message); RhinoApp.CommandLineOut.WriteLine($"Speckle Error - {e.ToFormattedString()}"); return Result.Failure; } diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Previews.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Previews.cs index 67eb7e402f..3c339dbf71 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Previews.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Previews.cs @@ -8,6 +8,7 @@ using Rhino.DocObjects; using Speckle.Core.Api; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; namespace SpeckleRhino; @@ -195,16 +196,15 @@ public override async Task PreviewReceive(StreamState state, Progre } // create display conduit - try + PreviewConduit = new PreviewConduit(Preview); + if (PreviewConduit.Preview.Count == 0) { - PreviewConduit = new PreviewConduit(Preview); - } - catch (Exception e) - { - progress.Report.OperationErrors.Add(new Exception($"Could not create preview: {e.Message}")); + SpeckleLog.Logger.Information("No previewable geometry was found."); + progress.Report.OperationErrors.Add(new Exception($"No previewable objects found.")); ResetDocument(); return null; } + PreviewConduit.Enabled = true; Doc.Views.ActiveView.ActiveViewport.ZoomBoundingBox(PreviewConduit.bbox); Doc.Views.Redraw(); diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Receive.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Receive.cs index 29bbf0b3a7..bcf4c63633 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Receive.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Receive.cs @@ -314,26 +314,29 @@ public override async Task ReceiveStream(StreamState state, Progres // gets objects by id directly or by application id user string private List GetObjectsByApplicationId(string applicationId) { + List match = new(); + if (string.IsNullOrEmpty(applicationId)) { - return new List(); + return match; } // first try to find the object by app id user string - var match = Doc.Objects.FindByUserString(ApplicationIdKey, applicationId, true).ToList(); + if (Doc.Objects.FindByUserString(ApplicationIdKey, applicationId, true) is RhinoObject[] foundObjects) + { + match = foundObjects.ToList(); + } // if nothing is found, look for the geom obj by its guid directly - if (!match.Any()) + if (match.Count == 0) { - try + if (Utils.GetGuidFromString(applicationId, out Guid id)) { - RhinoObject obj = Doc.Objects.FindId(new Guid(applicationId)); - if (obj != null) + if (Doc.Objects.FindId(id) is RhinoObject obj) { match.Add(obj); } } - catch { } } return match; @@ -542,9 +545,10 @@ private void BakeObject( Base render = obj["renderMaterial"] as Base ?? obj["@renderMaterial"] as Base; if (display != null) { - if (converter.ConvertToNative(display) is ObjectAttributes displayAttribute) + var convertedDisplay = converter.ConvertToNative(display) as ObjectAttributes; + if (convertedDisplay is not null) { - attributes = displayAttribute; + attributes = convertedDisplay; } } else if (render != null) @@ -555,27 +559,8 @@ private void BakeObject( // assign layer attributes.LayerIndex = layer.Index; - // handle user info, including application id - SetUserInfo(obj, attributes, parent); - - // add revit parameters as user strings - var paramId = parent != null ? parent.OriginalId : obj.id; - if (StoredObjectParams.ContainsKey(paramId)) - { - var parameters = StoredObjectParams[paramId]; - foreach (var member in parameters.GetMembers(DynamicBaseMemberType.Dynamic)) - { - if (member.Value is Base parameter) - { - var convertedParameter = converter.ConvertToNative(parameter) as Tuple; - if (convertedParameter is not null) - { - var name = $"{convertedParameter.Item1}({member.Key})"; - attributes.SetUserString(name, convertedParameter.Item2); - } - } - } - } + // handle user info, application id, revit parameters + SetUserInfo(obj, attributes, converter, parent); Guid id = Doc.Objects.Add(o, attributes); if (id == Guid.Empty) @@ -607,8 +592,8 @@ private void BakeObject( // handle render material if (render != null) { - var convertedMaterial = converter.ConvertToNative(render) as RenderMaterial; //Maybe wrap in try catch in case no conversion exists? - if (convertedMaterial != null) + var convertedMaterial = converter.ConvertToNative(render) as RenderMaterial; + if (convertedMaterial is not null) { RhinoObject rhinoObject = Doc.Objects.FindId(id); rhinoObject.RenderMaterial = convertedMaterial; @@ -620,7 +605,7 @@ private void BakeObject( case RhinoObject o: // this was prbly a block instance, baked during conversion o.Attributes.LayerIndex = layer.Index; // assign layer - SetUserInfo(obj, o.Attributes, parent); // handle user info, including application id + SetUserInfo(obj, o.Attributes, converter, parent); // handle user info, including application id o.CommitChanges(); if (parent != null) { @@ -659,7 +644,12 @@ private void BakeObject( } } - private void SetUserInfo(Base obj, ObjectAttributes attributes, ApplicationObject parent = null) + private void SetUserInfo( + Base obj, + ObjectAttributes attributes, + ISpeckleConverter converter, + ApplicationObject parent = null + ) { // set user strings if (obj[UserStrings] is Base userStrings) @@ -672,11 +662,7 @@ private void SetUserInfo(Base obj, ObjectAttributes attributes, ApplicationObjec // set application id var appId = parent != null ? parent.applicationId : obj.applicationId; - try - { - attributes.SetUserString(ApplicationIdKey, appId); - } - catch { } + attributes.SetUserString(ApplicationIdKey, appId); // set user dictionaries if (obj[UserDictionary] is Base userDictionary) @@ -684,11 +670,30 @@ private void SetUserInfo(Base obj, ObjectAttributes attributes, ApplicationObjec ParseDictionaryToArchivable(attributes.UserDictionary, userDictionary); } + // set name or label var name = obj["name"] as string ?? obj["label"] as string; // gridlines have a "label" prop instead of name? if (name != null) { attributes.Name = name; } + + // set revit parameters as user strings + var paramId = parent != null ? parent.OriginalId : obj.id; + if (StoredObjectParams.TryGetValue(paramId, out Base parameters)) + { + foreach (var member in parameters.GetMembers(DynamicBaseMemberType.Dynamic)) + { + if (member.Value is Base parameter) + { + var convertedParameter = converter.ConvertToNative(parameter) as Tuple; + if (convertedParameter is not null) + { + var paramName = $"{convertedParameter.Item1}({member.Key})"; + attributes.SetUserString(paramName, convertedParameter.Item2); + } + } + } + } } // Clears the stored objects, params, and preview objects @@ -703,10 +708,9 @@ private void ClearStorage() /// Copies a Base to an ArchivableDictionary /// /// - /// private void ParseDictionaryToArchivable(ArchivableDictionary target, Base @base) { - foreach (var prop in @base.GetMemberNames()) + foreach (var prop in @base.GetMembers().Keys) { var obj = @base[prop]; switch (obj) diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Selection.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Selection.cs index ddab48b1f5..f770a25efc 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Selection.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Selection.cs @@ -76,37 +76,23 @@ public override List GetSelectionFilters() public override void SelectClientObjects(List objs, bool deselect = false) { - var isPreview = PreviewConduit != null && PreviewConduit.Enabled ? true : false; + var isPreview = PreviewConduit != null && PreviewConduit.Enabled; foreach (var id in objs) { - RhinoObject obj = null; - try + if (Utils.GetGuidFromString(id, out Guid guid)) { - obj = Doc.Objects.FindId(new Guid(id)); // this is a rhinoobj - } - catch - { - continue; // this was a named view! - } - - if (obj != null) - { - if (deselect) + if (Doc.Objects.FindId(guid) is RhinoObject obj) { - obj.Select(false, true, false, true, true, true); + obj.Select(!deselect, true, true, true, true, true); } - else + else if (isPreview) { - obj.Select(true, true, true, true, true, true); + PreviewConduit.Enabled = false; + PreviewConduit.SelectPreviewObject(id, deselect); + PreviewConduit.Enabled = true; } } - else if (isPreview) - { - PreviewConduit.Enabled = false; - PreviewConduit.SelectPreviewObject(id, deselect); - PreviewConduit.Enabled = true; - } } Doc.Views.ActiveView.ActiveViewport.ZoomExtentsSelected(); diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Send.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Send.cs index 5cd525365e..a55f132719 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Send.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Send.cs @@ -6,14 +6,12 @@ using DesktopUI2; using DesktopUI2.Models; using DesktopUI2.ViewModels; -using Rhino; using Rhino.DocObjects; using Speckle.Core.Api; using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Transports; -using Speckle.Newtonsoft.Json; namespace SpeckleRhino; diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Settings.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Settings.cs index 6fab551c68..3384f18d4c 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Settings.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.Settings.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using DesktopUI2; using DesktopUI2.Models.Settings; -using Rhino; -using Rhino.DocObjects.Tables; namespace SpeckleRhino; diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/DuiPanel.xaml.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/DuiPanel.xaml.cs index 1e5e51a768..af5a81ee18 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/DuiPanel.xaml.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/DuiPanel.xaml.cs @@ -3,6 +3,7 @@ using System.Windows.Controls; using DesktopUI2.ViewModels; using DesktopUI2.Views; +using Speckle.Core.Logging; namespace SpeckleRhino; @@ -24,6 +25,6 @@ public DuiPanel() DataContext = viewModel; AvaloniaHost.Content = new MainUserControl(); } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) { } } } diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingBindingsRhino.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingBindingsRhino.cs index e4eb11c24c..d43812e920 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingBindingsRhino.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingBindingsRhino.cs @@ -28,14 +28,18 @@ public override MappingSelectionInfo GetSelectionInfo() { try { - var selection = RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false).ToList(); - var result = new List(); + List selection = RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false)?.ToList(); + if (selection is null) + { + return new MappingSelectionInfo(new List(), 0); + } + var result = new List(); foreach (var obj in selection) { - var schemas = GetObjectSchemas(obj); + List schemas = GetObjectSchemas(obj); - if (!result.Any()) + if (result.Count == 0) { result = schemas; } @@ -44,11 +48,15 @@ public override MappingSelectionInfo GetSelectionInfo() //intersect lists //TODO: if some elements already have a schema and values are different //we should default to an empty schema, instead of potentially restoring the one with values - result = result.Where(x => schemas.Any(y => y.Name == x.Name)).ToList(); + List intersect = result.Where(x => schemas.Any(y => y.Name == x.Name))?.ToList(); + if (intersect is not null) + { + result = intersect; + } } //incompatible selection - if (!result.Any()) + if (result.Count == 0) { return new MappingSelectionInfo(new List(), selection.Count); } @@ -56,10 +64,11 @@ public override MappingSelectionInfo GetSelectionInfo() return new MappingSelectionInfo(result, selection.Count); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + // check seq to see if this has ever been thrown SpeckleLog.Logger.Error(ex, "Could not get selection info: {exceptionMessage}", ex.Message); - return new MappingSelectionInfo(new List(), 0); + throw; } } @@ -74,8 +83,7 @@ private List GetObjectSchemas(RhinoObject obj) try { - var existingSchema = GetExistingObjectSchema(obj); - if (existingSchema != null) + if (GetExistingObjectSchema(obj) is Schema existingSchema) { result.Add(existingSchema); } @@ -158,7 +166,7 @@ private List GetObjectSchemas(RhinoObject obj) } } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Error(ex, "Could not get object schemas: {exceptionMessage}", ex.Message); } @@ -278,8 +286,13 @@ private Schema GetExistingObjectSchema(RhinoObject obj) return JsonConvert.DeserializeObject(viewModel, settings); } - catch + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error( + ex, + "Could not deserialize Speckle mapping view key into a schema: {exceptionMessage}", + ex.Message + ); return null; } } @@ -298,20 +311,16 @@ public override void SetMappings(string schema, string viewModel) public override void ClearMappings(List ids) { - foreach (var id in ids) + foreach (string id in ids) { - try + if (Utils.GetGuidFromString(id, out Guid guid)) { - var obj = RhinoDoc.ActiveDoc.Objects.FindId(new Guid(id)); - if (obj == null) + if (RhinoDoc.ActiveDoc.Objects.FindId(guid) is RhinoObject obj) { - continue; + obj.Attributes.DeleteUserString(SpeckleMappingKey); + obj.Attributes.DeleteUserString(SpeckleMappingViewKey); } - - obj.Attributes.DeleteUserString(SpeckleMappingKey); - obj.Attributes.DeleteUserString(SpeckleMappingViewKey); } - catch { } } SpeckleRhinoConnectorPlugin.Instance.ExistingSchemaLogExpired = true; @@ -339,28 +348,29 @@ public override List GetExistingSchemaElements() public override void HighlightElements(List ids) { - try + if (ids is not null && Display is not null) { Display.ObjectIds = ids; - RhinoDoc.ActiveDoc?.Views.Redraw(); - } - catch (Exception ex) - { - //fail silently + RhinoDoc.ActiveDoc?.Views?.Redraw(); } } public override void SelectElements(List ids) { - try + if (ids is not null) { - RhinoDoc.ActiveDoc.Objects.UnselectAll(); - RhinoDoc.ActiveDoc.Objects.Select(ids.Select(x => Guid.Parse(x))); - RhinoDoc.ActiveDoc?.Views.Redraw(); - } - catch (Exception ex) - { - //fail silently + RhinoDoc.ActiveDoc?.Objects?.UnselectAll(); + List guids = new(); + foreach (string id in ids) + { + if (Utils.GetGuidFromString(id, out Guid guid)) + { + guids.Add(guid); + } + } + + RhinoDoc.ActiveDoc?.Objects?.Select(guids); + RhinoDoc.ActiveDoc?.Views?.Redraw(); } } } diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingsPanel.xaml.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingsPanel.xaml.cs index 89cdbe23ef..a1a6acaafd 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingsPanel.xaml.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/MappingsPanel.xaml.cs @@ -3,6 +3,7 @@ using System.Windows.Controls; using DesktopUI2.ViewModels.MappingTool; using DesktopUI2.Views; +using Speckle.Core.Logging; namespace SpeckleRhino; @@ -24,6 +25,6 @@ public MappingsPanel() DataContext = viewModel; AvaloniaHost.Content = new MappingsControl(); } - catch (Exception ex) { } + catch (Exception ex) when (!ex.IsFatal()) { } } } diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Utils.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Utils.cs index c3b4f8b8e9..20e1ad797d 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Utils.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/Utils.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.Linq; -using System.Text.RegularExpressions; using Rhino; using Rhino.Display; using Rhino.DocObjects; using Rhino.Geometry; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Point = Rhino.Geometry.Point; @@ -22,23 +21,79 @@ public static class Utils #elif RHINO7 public static string RhinoAppName = HostApplications.Rhino.GetVersion(HostAppVersion.v7); public static string AppName = "Rhino"; +#elif RHINO8 + public static string RhinoAppName = HostApplications.Rhino.GetVersion(HostAppVersion.v8); + public static string AppName = "Rhino"; #else public static string RhinoAppName = HostApplications.Rhino.Name; public static string AppName = "Rhino"; #endif - public static string invalidRhinoChars = @"{}()"; + public static string invalidRhinoChars = @"{}()[]"; /// - /// Removes invalid characters for Rhino layer and block names + /// Creates a valid name for Rhino layers, blocks, and named views. + /// + /// Layer, block, or named view name + /// The original name if valid, or "@name" if not. + /// From trial and error, names cannot begin with invalidRhinoChars. This has been encountered in grasshopper branch syntax. + public static string MakeValidName(string str) + { + if (string.IsNullOrEmpty(str)) + { + return str; + } + else + { + return invalidRhinoChars.Contains(str[0]) ? $"@{str}" : str; + } + } + + /// + /// Creates a valid path for Rhino layers. /// /// /// - public static string RemoveInvalidRhinoChars(string str) + public static string MakeValidPath(string str) { - // using this to handle grasshopper branch syntax - string cleanStr = str.Replace("{", "").Replace("}", ""); - return cleanStr; + if (string.IsNullOrEmpty(str)) + { + return str; + } + + string validPath = ""; + string[] layerNames = str.Split(new string[] { Layer.PathSeparator }, StringSplitOptions.None); + foreach (var item in layerNames) + { + validPath += string.IsNullOrEmpty(validPath) ? MakeValidName(item) : Layer.PathSeparator + MakeValidName(item); + } + + return validPath; + } + + /// + /// Attemps to retrieve a Guid from a string + /// + /// + /// Guid on success, null on failure + public static bool GetGuidFromString(string s, out Guid id) + { + id = Guid.Empty; + if (string.IsNullOrEmpty(s)) + { + return false; + } + + try + { + id = Guid.Parse(s); + } + catch (FormatException) + { + return false; + } + + return true; } /// @@ -53,28 +108,24 @@ public static bool FindObjectBySelectedId(RhinoDoc doc, string id, out object ob { descriptor = string.Empty; obj = null; - try - { - Guid guid = new(id); // try to get guid from object id - RhinoObject geom = doc.Objects.FindId(guid); - if (geom != null) + if (GetGuidFromString(id, out Guid guid)) + { + if (doc.Objects.FindId(guid) is RhinoObject geom) { descriptor = Formatting.ObjectDescriptor(geom); obj = geom; } else { - var layer = doc.Layers.FindId(guid); - if (layer != null) + if (doc.Layers.FindId(guid) is Layer layer) { descriptor = "Layer"; obj = layer; } else { - var standardView = doc.Views.Find(guid)?.ActiveViewport; - if (standardView != null) + if (doc.Views.Find(guid)?.ActiveViewport is RhinoViewport standardView) { descriptor = "Standard View"; obj = new ViewInfo(standardView); @@ -82,7 +133,7 @@ public static bool FindObjectBySelectedId(RhinoDoc doc, string id, out object ob } } } - catch // this was a named view name + else // this was probably a named view (saved by name, not guid) { var viewIndex = doc.NamedViews.FindByName(id); if (viewIndex != -1) @@ -92,48 +143,62 @@ public static bool FindObjectBySelectedId(RhinoDoc doc, string id, out object ob } } - return obj == null ? false : true; + return obj != null; } #region extension methods + /// - /// Finds a layer from its full path + /// Creates a layer from its name and parent /// /// - /// Full path of layer - /// Create the layer if it doesn't already exist - /// Null on failure - /// Note: The created layer path may be different from the input path, due to removal of invalid chars - public static Layer GetLayer(this RhinoDoc doc, string path, bool MakeIfNull = false) + /// + /// The new layer + /// Layer name is invalid. + /// Layer parent could not be set, or a layer with the same name already exists. + public static Layer MakeLayer(this RhinoDoc doc, string name, Layer parentLayer = null) { - Layer MakeLayer(string name, Layer parentLayer = null) + if (!Layer.IsValidName(name)) + { + throw new ArgumentException("Layer name is invalid."); + } + + Layer newLayer = new() { Color = Color.AliceBlue, Name = name }; + if (parentLayer != null) { try { - Layer newLayer = new() { Color = Color.AliceBlue, Name = name }; - if (parentLayer != null) - { - newLayer.ParentLayerId = parentLayer.Id; - } - - int newIndex = doc.Layers.Add(newLayer); - if (newIndex < 0) - { - return null; - } - - return doc.Layers.FindIndex(newIndex); + newLayer.ParentLayerId = parentLayer.Id; } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { - return null; + throw new InvalidOperationException("Could not set layer parent id.", e); } } - var cleanPath = RemoveInvalidRhinoChars(path); + int newIndex = doc.Layers.Add(newLayer); + if (newIndex is -1) + { + throw new InvalidOperationException("A layer with the same name already exists."); + } + + return newLayer; + } + + /// + /// Finds a layer from its full path + /// + /// + /// Full path of layer + /// Create the layer if it doesn't already exist + /// The layer on success. On failure, returns null. + /// Note: The created layer path may be different from the input path, due to removal of invalid chars + public static Layer GetLayer(this RhinoDoc doc, string path, bool makeIfNull = false) + { + Layer layer; + var cleanPath = MakeValidPath(path); int index = doc.Layers.FindByFullPath(cleanPath, RhinoMath.UnsetIntIndex); - Layer layer = doc.Layers.FindIndex(index); - if (layer == null && MakeIfNull) + if (index is RhinoMath.UnsetIntIndex && makeIfNull) { var layerNames = cleanPath.Split(new[] { Layer.PathSeparator }, StringSplitOptions.RemoveEmptyEntries); @@ -146,18 +211,48 @@ Layer MakeLayer(string name, Layer parentLayer = null) currentLayer = doc.GetLayer(currentLayerPath); if (currentLayer == null) { - currentLayer = MakeLayer(layerNames[i], parent); - } - - if (currentLayer == null) - { - break; + try + { + currentLayer = doc.MakeLayer(layerNames[i], parent); + } + catch (ArgumentException argEx) + { + SpeckleLog.Logger.Error( + argEx, + "Failed to create layer {layerPath} with {exceptionMessage}", + currentLayerPath, + argEx.Message + ); + RhinoApp.CommandLineOut.WriteLine( + $"Failed to create layer {currentLayerPath} while creating {cleanPath}: {argEx.Message}" + ); + break; + } + catch (InvalidOperationException ioEx) + { + SpeckleLog.Logger.Error( + ioEx, + "Failed to create layer {layerPath} with {exceptionMessage}", + currentLayerPath, + ioEx.Message + ); + RhinoApp.CommandLineOut.WriteLine( + $"Failed to create layer {currentLayerPath} while creating {cleanPath}: {ioEx.Message}" + ); + break; + } } parent = currentLayer; } + layer = currentLayer; } + else + { + layer = doc.Layers.FindIndex(index); + } + return layer; } @@ -188,6 +283,7 @@ public static List StandardViews(this RhinoDoc doc) } #region Preview + public class PreviewConduit : DisplayConduit { public BoundingBox bbox; @@ -206,9 +302,15 @@ public PreviewConduit(List preview) foreach (var previewObj in preview) { var converted = new List(); - var toBeConverted = previewObj.Convertible + List toBeConverted = previewObj.Convertible ? previewObj.Converted - : previewObj.Fallback.SelectMany(o => o.Converted).ToList(); + : previewObj.Fallback?.SelectMany(o => o.Converted)?.ToList(); + + if (toBeConverted is null) + { + continue; + } + foreach (var obj in toBeConverted) { switch (obj) @@ -227,14 +329,14 @@ public PreviewConduit(List preview) converted.Add(obj); } - if (!Preview.ContainsKey(previewObj.OriginalId)) + if (!Preview.ContainsKey(previewObj.OriginalId) && converted.Count > 0) { Preview.Add(previewObj.OriginalId, converted); } } } - private Dictionary> Preview { get; set; } = new(); + public Dictionary> Preview { get; set; } = new(); public void SelectPreviewObject(string id, bool unselect = false) { @@ -361,63 +463,4 @@ public static string ObjectDescriptor(RhinoObject obj) var simpleType = obj.ObjectType.ToString(); return obj.HasName ? $"{simpleType}" : $"{simpleType} {obj.Name}"; } - - public static string TimeAgo(string timestamp) - { - //TODO: this implementation is almost the same as Speckle.Core.Api.Helpers - TimeSpan timeAgo; - try - { - timeAgo = DateTime.Now.Subtract(DateTime.Parse(timestamp)); - } - catch (FormatException e) - { - Debug.WriteLine("Could not parse the string to a DateTime"); - return ""; - } - - if (timeAgo.TotalSeconds < 60) - { - return "less than a minute ago"; - } - - if (timeAgo.TotalMinutes < 60) - { - return $"about {timeAgo.Minutes} minute{PluralS(timeAgo.Minutes)} ago"; - } - - if (timeAgo.TotalHours < 24) - { - return $"about {timeAgo.Hours} hour{PluralS(timeAgo.Hours)} ago"; - } - - if (timeAgo.TotalDays < 7) - { - return $"about {timeAgo.Days} day{PluralS(timeAgo.Days)} ago"; - } - - if (timeAgo.TotalDays < 30) - { - return $"about {timeAgo.Days / 7} week{PluralS(timeAgo.Days / 7)} ago"; - } - - if (timeAgo.TotalDays < 365) - { - return $"about {timeAgo.Days / 30} month{PluralS(timeAgo.Days / 30)} ago"; - } - - return $"over {timeAgo.Days / 356} year{PluralS(timeAgo.Days / 356)} ago"; - } - - public static string PluralS(int num) - { - return num != 1 ? "s" : ""; - } - - public static string CommitInfo(string stream, string branch, string commitId) - { - string formatted = $"{stream}[ {branch} @ {commitId} ]"; - string clean = Regex.Replace(formatted, @"[^\u0000-\u007F]+", string.Empty).Trim(); // remove emojis and trim :( - return clean; - } } diff --git a/ConnectorRhino/ConnectorRhino6/ConnectorRhino6.csproj b/ConnectorRhino/ConnectorRhino6/ConnectorRhino6.csproj index 4b57f487c3..a403f5e918 100644 --- a/ConnectorRhino/ConnectorRhino6/ConnectorRhino6.csproj +++ b/ConnectorRhino/ConnectorRhino6/ConnectorRhino6.csproj @@ -12,7 +12,7 @@ win-x64 true true - $(DefineConstants);RHINO6 + $(DefineConstants);RHINO6;RHINO6_OR_GREATER /Applications/Rhinoceros.app diff --git a/ConnectorRhino/ConnectorRhino7/ConnectorRhino7.csproj b/ConnectorRhino/ConnectorRhino7/ConnectorRhino7.csproj index c7425b783b..7746ae3948 100644 --- a/ConnectorRhino/ConnectorRhino7/ConnectorRhino7.csproj +++ b/ConnectorRhino/ConnectorRhino7/ConnectorRhino7.csproj @@ -23,7 +23,7 @@ x64 win-x64 true - $(DefineConstants);RHINO7 + $(DefineConstants);RHINO7;RHINO6_OR_GREATER;RHINO7_OR_GREATER Library @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/ConnectorRhino/ConnectorRhino8/ConnectorRhino8.csproj b/ConnectorRhino/ConnectorRhino8/ConnectorRhino8.csproj new file mode 100644 index 0000000000..48a329c751 --- /dev/null +++ b/ConnectorRhino/ConnectorRhino8/ConnectorRhino8.csproj @@ -0,0 +1,62 @@ + + + + net7.0-windows;net48 + SpeckleRhino + Description of SpeckleRhino + .rhp + /Applications/Rhino 8.app + SpeckleConnectorRhino + Debug;Release;Debug Mac;Release Mac + SpeckleRhino + ConnectorRhino8 + true + + + + $(DefineConstants);RHINO8;RHINO6_OR_GREATER;RHINO7_OR_GREATER;RHINO8_OR_GREATER + Library + true + true + true + true + + + + $(DefineConstants);MAC + + + + C:\Program Files\Rhino 8\System\Rhino.exe + Program + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructures.slnf b/ConnectorTeklaStructures/ConnectorTeklaStructures.slnf index ec1529ee31..443700b8e9 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructures.slnf +++ b/ConnectorTeklaStructures/ConnectorTeklaStructures.slnf @@ -17,7 +17,7 @@ "Objects\\Converters\\ConverterTeklaStructures\\ConverterTeklaStructuresShared\\ConverterTeklaStructuresShared.shproj", "Objects\\Converters\\StructuralUtilities\\PolygonMesher\\PolygonMesher.csproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj" ] } } \ No newline at end of file diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainForm.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainForm.cs index f8c26d1478..f236b75fd0 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainForm.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainForm.cs @@ -1,14 +1,11 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Threading; using Avalonia; using Avalonia.Controls; using Avalonia.ReactiveUI; using DesktopUI2.ViewModels; -using DesktopUI2.Views; using Speckle.ConnectorTeklaStructures.UI; using Speckle.Core.Logging; using Tekla.Structures.Dialog; @@ -27,41 +24,94 @@ public partial class MainForm : PluginFormBase const int GWL_HWNDPARENT = -8; private static Avalonia.Application AvaloniaApp { get; set; } + public Model Model { get; private set; } + public static Window MainWindow { get; private set; } + public static ConnectorBindingsTeklaStructures Bindings { get; set; } + /// + /// Initializes a new instance of the MainForm class. + /// public MainForm() + { + InitializeComponents(); + SetupApplication(); + } + + /// + /// Initializes the components of the MainForm. + /// + private void InitializeComponents() { Load += MainForm_Load; - if (MainWindow == null) + + if (MainWindow != null) { - // Link to model. - Model = new Model(); - Bindings = new ConnectorBindingsTeklaStructures(Model); + return; + } + Model = new Model(); + Bindings = new ConnectorBindingsTeklaStructures(Model); + } + + /// + /// Sets up the application, including event subscriptions, UI build, and model bindings. + /// + [SuppressMessage( + category: "Design", + checkId: "CA1031:Do not catch general exception types", + Justification = "Exception is logged and plugin window doesn't populate." + )] + private static void SetupApplication() + { + if (MainWindow == null) + { try { - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolve); - - Setup.Init(Bindings.GetHostAppNameVersion(), Bindings.GetHostAppName()); - BuildAvaloniaApp().Start(AppMain, null); - var viewModel = new MainViewModel(Bindings); - MainWindow = new DesktopUI2.Views.MainWindow { DataContext = viewModel }; - - Bindings.OpenTeklaStructures(); + SubscribeToEvents(); + BuildAndShowMainWindow(); + SetTeklaAsOwner(); } catch (Exception ex) { - SpeckleLog.Logger.Fatal(ex, "Failed to create main form"); + SpeckleLog.Logger.Error(ex, "Failed to create main form interface with {errorMessage}", ex.Message); + MainWindow = null; + return; } } - MainWindow.Show(); - MainWindow.Activate(); - MainWindow.Focus(); + MainWindow?.Show(); + MainWindow?.Activate(); + MainWindow?.Focus(); + } + + /// + /// Subscribes to necessary application events. + /// + private static void SubscribeToEvents() => + AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolve); - //set Tekla app as owner + /// + /// Builds and displays the main window of the application. + /// + private static void BuildAndShowMainWindow() + { + Setup.Init(Bindings.GetHostAppNameVersion(), Bindings.GetHostAppName()); + BuildAvaloniaApp().Start(AppMain, null); + + var viewModel = new MainViewModel(Bindings); + MainWindow = new DesktopUI2.Views.MainWindow { DataContext = viewModel }; + + Bindings.OpenTeklaStructures(); + } + + /// + /// Sets the Tekla application as the owner of the main window. + /// + private static void SetTeklaAsOwner() + { var hwnd = MainWindow.PlatformImpl.Handle.Handle; SetWindowLongPtr(hwnd, GWL_HWNDPARENT, Tekla.Structures.Dialog.MainWindow.Frame.Handle); } diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainPlugin.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainPlugin.cs index 93ce6c7b20..da57319e84 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainPlugin.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/MainPlugin.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Tekla.Structures.Plugins; diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/StreamStateManager/StreamStateManager.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/StreamStateManager/StreamStateManager.cs index 0aadd517fd..9408665257 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/StreamStateManager/StreamStateManager.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/StreamStateManager/StreamStateManager.cs @@ -1,20 +1,22 @@ +using System; using DesktopUI2.Models; using Speckle.Newtonsoft.Json; using System.Collections.Generic; using System.IO; using System.Text; +using Speckle.Core.Logging; using Tekla.Structures.Model; namespace ConnectorTeklaStructures.Storage; public static class StreamStateManager { - private static string _speckleFilePath; + private static string s_speckleFilePath; public static List ReadState(Model model) { var strings = ReadSpeckleFile(model); - if (strings == "") + if (string.IsNullOrEmpty(strings)) { return new List(); } @@ -22,74 +24,112 @@ public static List ReadState(Model model) { return JsonConvert.DeserializeObject>(strings); } - catch + catch (JsonException ex) { + SpeckleLog.Logger.Warning( + "Failed to deserialize saved stream state list: " + $"{ex.Message}. Resetting to an empty list." + ); return new List(); } } /// - /// Writes the stream states to the .txt file in speckle folder + /// Writes the stream states to the {TeklaStructuresModelName}.txt file in speckle folder /// that exists or is created in the folder where the TeklaStructures model exists. /// /// /// public static void WriteStreamStateList(Model model, List streamStates) { - if (_speckleFilePath == null) + if (s_speckleFilePath == null) { GetOrCreateSpeckleFilePath(model); } - FileStream fileStream = new(_speckleFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); + if (s_speckleFilePath == null) + { + return; + } + try { - using (var streamWriter = new StreamWriter(fileStream)) + FileStream fileStream = new(s_speckleFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); + if (!fileStream.CanWrite) { - streamWriter.Write(JsonConvert.SerializeObject(streamStates) as string); - streamWriter.Flush(); + return; } + + using var streamWriter = new StreamWriter(fileStream); + string streamStateString = JsonConvert.SerializeObject(streamStates); + if (string.IsNullOrEmpty(streamStateString)) + { + return; + } + + streamWriter.Write(streamStateString); + streamWriter.Flush(); + } + catch (Exception ex) when (!ex.IsFatal()) + { + throw new SpeckleException($"Failed to write stream state list to file: {ex.Message}"); } - catch { } } + /// + /// Clears the contents of the stream state file associated with the specified model. + /// + /// + /// This method sets the length of the stream state file to zero, effectively clearing its contents. + /// It is important to ensure that no other process is writing to the file when this method is called. + /// If the file path is not set or the file does not exist, the method will return early without action. + /// + /// The model associated with the stream state file. This is used to determine or create the file path if it is not already set. public static void ClearStreamStateList(Model model) { - if (_speckleFilePath == null) + if (s_speckleFilePath == null) { GetOrCreateSpeckleFilePath(model); } - FileStream fileStream = new(_speckleFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); + if (s_speckleFilePath == null || !File.Exists(s_speckleFilePath)) + { + return; + } + + FileStream fileStream = null; try { + fileStream = new FileStream(s_speckleFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); fileStream.SetLength(0); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.Error($"Failed to clear stream state list: {ex.Message}"); + } + finally + { + fileStream?.Dispose(); + } } /// /// We need a folder in TeklaStructures model folder named "speckle" and a file in it - /// called ".txt". This function create this file and folder if + /// called "{TeklaStructuresModelName}.txt". This function create this file and folder if /// they doesn't exists and returns it, otherwise just returns the file path /// /// private static void GetOrCreateSpeckleFilePath(Model model) { - string TeklaStructuresModelfilePath = model.GetInfo().ModelPath; - if (TeklaStructuresModelfilePath == "") + string teklaStructuresModelfilePath = model.GetInfo().ModelPath; + if (string.IsNullOrEmpty(teklaStructuresModelfilePath)) { // TeklaStructures model is probably not saved, so speckle shouldn't do much - _speckleFilePath = null; + s_speckleFilePath = null; return; } - //string TeklaStructuresFileName = Path.GetFileNameWithoutExtension(TeklaStructuresModelfilePath); - //string TeklaStructuresModelFolder = Path.GetDirectoryName(TeklaStructuresModelfilePath); - //string speckleFolderPath = Path.Combine(TeklaStructuresModelFolder, "speckle"); - //string speckleFilePath = Path.Combine(TeklaStructuresModelFolder, "speckle", $"{TeklaStructuresFileName}.txt"); - string TeklaStructuresFileName = Path.GetFileNameWithoutExtension(model.GetInfo().ModelName); - string speckleFolderPath = Path.Combine(TeklaStructuresModelfilePath, "speckle"); - string speckleFilePath = Path.Combine(speckleFolderPath, $"{TeklaStructuresFileName}.txt"); + string teklaStructuresFileName = Path.GetFileNameWithoutExtension(model.GetInfo().ModelName); + string speckleFolderPath = Path.Combine(teklaStructuresModelfilePath, "speckle"); + string speckleFilePath = Path.Combine(speckleFolderPath, $"{teklaStructuresFileName}.txt"); try { @@ -97,46 +137,72 @@ private static void GetOrCreateSpeckleFilePath(Model model) { Directory.CreateDirectory(speckleFolderPath); } + if (!File.Exists(speckleFilePath)) { - File.CreateText(speckleFilePath); + using (File.CreateText(speckleFilePath)) + { + // No content initialization needed + } } - _speckleFilePath = speckleFilePath; + + s_speckleFilePath = speckleFilePath; } - catch + catch (Exception ex) when (!ex.IsFatal()) { - _speckleFilePath = null; - return; + // Combine handling for non-fatal exceptions + string errorMessage = ex switch + { + IOException => $"IO error occurred while accessing {speckleFilePath}: {ex.Message}", + UnauthorizedAccessException => $"Access to {speckleFilePath} denied: {ex.Message}", + _ => $"An unexpected error occurred while processing {speckleFilePath}: {ex.Message}" + }; + + SpeckleLog.Logger.Error($"Could not create or retrieve the Speckle Stream State File: {errorMessage}"); + s_speckleFilePath = null; } } /// - /// Reads the "/speckle/.txt" file and returns the string in it + /// Reads the "/speckle/{TeklaStructuresModelName}.txt" file and returns the string in it /// /// private static string ReadSpeckleFile(Model model) { - if (_speckleFilePath == null) + if (s_speckleFilePath == null) { GetOrCreateSpeckleFilePath(model); } - if (_speckleFilePath == null) + if (s_speckleFilePath == null) { return ""; } - FileStream fileStream = new(_speckleFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + FileStream fileStream = null; try { - using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) + fileStream = new FileStream(s_speckleFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + using var streamReader = new StreamReader(fileStream, Encoding.UTF8); + return streamReader.ReadToEnd(); + } + catch (Exception ex) when (!ex.IsFatal()) + { + // Handle non-fatal exceptions + string errorMessage = ex switch { - return streamReader.ReadToEnd(); - } + IOException => $"IO error occurred while reading from {s_speckleFilePath}: {ex.Message}", + UnauthorizedAccessException => $"Access to {s_speckleFilePath} denied: {ex.Message}", + _ => $"An unexpected error occurred while reading from {s_speckleFilePath}: {ex.Message}" + }; + + SpeckleLog.Logger.Error($"Could not read the Speckle Stream State File: {errorMessage}"); } - catch + finally { - return ""; + fileStream?.Dispose(); } + + return ""; } } diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructure.Settings.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructure.Settings.cs index a88b21c5aa..59e149b589 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructure.Settings.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructure.Settings.cs @@ -1,10 +1,6 @@ using DesktopUI2; -using DesktopUI2.Models; -using DesktopUI2.ViewModels; using System.Collections.Generic; -using System.Text; using DesktopUI2.Models.Settings; -using System.Linq; namespace Speckle.ConnectorTeklaStructures.UI; diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.ClientOperations.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.ClientOperations.cs index 7619de95ab..752bc807de 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.ClientOperations.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.ClientOperations.cs @@ -1,12 +1,7 @@ -using System; using System.Collections.Generic; using DesktopUI2; using DesktopUI2.Models; -using DesktopUI2.ViewModels; -using Speckle.Core.Logging; using ConnectorTeklaStructures.Storage; -using System.Linq; -using System.Threading.Tasks; namespace Speckle.ConnectorTeklaStructures.UI; diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.Selection.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.Selection.cs index d9dd25857f..5efb80c314 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.Selection.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.Selection.cs @@ -1,9 +1,6 @@ using DesktopUI2; -using DesktopUI2.Models; using DesktopUI2.Models.Filters; -using DesktopUI2.ViewModels; using Speckle.ConnectorTeklaStructures.Util; -using System; using System.Collections.Generic; using Tekla.Structures.Model; diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.cs index 5a2ccc3af6..59f021860d 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/UI/ConnectorBindingsTeklaStructures.cs @@ -4,7 +4,6 @@ using DesktopUI2.Models; using Speckle.Core.Models; using Speckle.ConnectorTeklaStructures.Util; -using System.Timers; using Tekla.Structures.Model; using Speckle.Core.Kits; diff --git a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/Util/ConnectorTeklaStructuresUtils.cs b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/Util/ConnectorTeklaStructuresUtils.cs index 505e5c0c12..22254cc7ee 100644 --- a/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/Util/ConnectorTeklaStructuresUtils.cs +++ b/ConnectorTeklaStructures/ConnectorTeklaStructuresShared/Util/ConnectorTeklaStructuresUtils.cs @@ -1,11 +1,7 @@ -using Speckle.ConnectorTeklaStructures.UI; using Speckle.Core.Kits; using Speckle.Core.Logging; -using Speckle.Core.Models; -using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Tekla.Structures.Model; namespace Speckle.ConnectorTeklaStructures.Util; diff --git a/Core/.config/dotnet-tools.json b/Core/.config/dotnet-tools.json deleted file mode 100644 index d1ac7eef4d..0000000000 --- a/Core/.config/dotnet-tools.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "csharpier": { - "version": "0.21.0", - "commands": [ - "dotnet-csharpier" - ] - } - } -} \ No newline at end of file diff --git a/Core/Core.sln b/Core/Core.sln index cd669fa534..c106800f97 100644 --- a/Core/Core.sln +++ b/Core/Core.sln @@ -4,18 +4,12 @@ VisualStudioVersion = 16.0.30011.22 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "Core\Core.csproj", "{CB85D2B2-9837-40B8-91DB-3C0636B1174D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsUnit", "Tests\TestsUnit.csproj", "{2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsIntegration", "IntegrationTests\TestsIntegration.csproj", "{4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FF890E88-185B-4A99-9391-6342F22279D0}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig README.md = README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleApp", "Examples\ExampleApp.csproj", "{73BBCC3C-E649-4977-A34A-7CF424D638E6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDBTransport", "Transports\MongoDBTransport\MongoDBTransport.csproj", "{4450B0E9-D663-4F13-AF96-6A41B1A3B5C9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Transports", "Transports", "{424ECC59-E693-4678-AFAC-C00F2D8AE735}" @@ -24,6 +18,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A3E889EB EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiskTransport", "Transports\DiskTransport\DiskTransport.csproj", "{815A9C70-BF5F-4718-AACB-9E50B26F4630}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Tests.Unit", "Tests\Speckle.Core.Tests.Unit\Speckle.Core.Tests.Unit.csproj", "{72030F4F-8509-4745-8BF4-01AFEB93EF07}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Tests.Integration", "Tests\Speckle.Core.Tests.Integration\Speckle.Core.Tests.Integration.csproj", "{51922311-4D42-46DB-BB16-CDEF9337C0BF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,18 +32,6 @@ Global {CB85D2B2-9837-40B8-91DB-3C0636B1174D}.Debug|Any CPU.Build.0 = Debug|Any CPU {CB85D2B2-9837-40B8-91DB-3C0636B1174D}.Release|Any CPU.ActiveCfg = Release|Any CPU {CB85D2B2-9837-40B8-91DB-3C0636B1174D}.Release|Any CPU.Build.0 = Release|Any CPU - {2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE}.Release|Any CPU.Build.0 = Release|Any CPU - {4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61}.Release|Any CPU.Build.0 = Release|Any CPU - {73BBCC3C-E649-4977-A34A-7CF424D638E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {73BBCC3C-E649-4977-A34A-7CF424D638E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {73BBCC3C-E649-4977-A34A-7CF424D638E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {73BBCC3C-E649-4977-A34A-7CF424D638E6}.Release|Any CPU.Build.0 = Release|Any CPU {4450B0E9-D663-4F13-AF96-6A41B1A3B5C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4450B0E9-D663-4F13-AF96-6A41B1A3B5C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {4450B0E9-D663-4F13-AF96-6A41B1A3B5C9}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -54,15 +40,23 @@ Global {815A9C70-BF5F-4718-AACB-9E50B26F4630}.Debug|Any CPU.Build.0 = Debug|Any CPU {815A9C70-BF5F-4718-AACB-9E50B26F4630}.Release|Any CPU.ActiveCfg = Release|Any CPU {815A9C70-BF5F-4718-AACB-9E50B26F4630}.Release|Any CPU.Build.0 = Release|Any CPU + {72030F4F-8509-4745-8BF4-01AFEB93EF07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72030F4F-8509-4745-8BF4-01AFEB93EF07}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72030F4F-8509-4745-8BF4-01AFEB93EF07}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72030F4F-8509-4745-8BF4-01AFEB93EF07}.Release|Any CPU.Build.0 = Release|Any CPU + {51922311-4D42-46DB-BB16-CDEF9337C0BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51922311-4D42-46DB-BB16-CDEF9337C0BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51922311-4D42-46DB-BB16-CDEF9337C0BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51922311-4D42-46DB-BB16-CDEF9337C0BF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2EDE05B7-2B21-4C0B-9EA5-3BC7A52315BE} = {A3E889EB-76D7-4A6E-A3FB-BCAEAC2634FC} - {4A79F5D2-3B66-43E3-BE33-0BB79FBFDC61} = {A3E889EB-76D7-4A6E-A3FB-BCAEAC2634FC} {4450B0E9-D663-4F13-AF96-6A41B1A3B5C9} = {424ECC59-E693-4678-AFAC-C00F2D8AE735} {815A9C70-BF5F-4718-AACB-9E50B26F4630} = {424ECC59-E693-4678-AFAC-C00F2D8AE735} + {72030F4F-8509-4745-8BF4-01AFEB93EF07} = {A3E889EB-76D7-4A6E-A3FB-BCAEAC2634FC} + {51922311-4D42-46DB-BB16-CDEF9337C0BF} = {A3E889EB-76D7-4A6E-A3FB-BCAEAC2634FC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1378F8F4-B354-4DB6-8052-A1A69B59BC2C} diff --git a/Core/Core/Api/Exceptions.cs b/Core/Core/Api/Exceptions.cs index 699286e800..7d10bd9974 100644 --- a/Core/Core/Api/Exceptions.cs +++ b/Core/Core/Api/Exceptions.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.Linq; @@ -13,8 +11,8 @@ namespace Speckle.Core.Api; /// public class SpeckleGraphQLException : SpeckleException { - private GraphQLRequest _request; - public readonly GraphQLResponse? Response; + private readonly GraphQLRequest _request; + public GraphQLResponse? Response { get; } public SpeckleGraphQLException(string message, GraphQLRequest request, GraphQLResponse? response) : base(message) diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ActivityOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ActivityOperations.cs index 17feb41ec4..34250ecb8a 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ActivityOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ActivityOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.Threading; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.BranchOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.BranchOperations.cs index a371935a92..1c3a67b181 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.BranchOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.BranchOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -18,7 +16,7 @@ public partial class Client /// public async Task> StreamGetBranchesWithLimitRetry(string streamId, int commitsLimit = 10) { - List? branches = null; + List branches; try { branches = await StreamGetBranches(streamId, ServerLimits.BRANCH_GET_LIMIT, commitsLimit).ConfigureAwait(true); @@ -178,10 +176,12 @@ public async Task ModelGet(string projectId, string modelId, Cancellatio cancellationToken ) .ConfigureAwait(false); - var branch = new Branch(); - branch.description = res["project"]["model"]["description"]; - branch.id = res["project"]["model"]["id"]; - branch.name = res["project"]["model"]["name"]; + var branch = new Branch + { + description = res["project"]["model"]["description"], + id = res["project"]["model"]["id"], + name = res["project"]["model"]["name"] + }; return branch; } diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommentOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommentOperations.cs index b43baa36b4..20feaaf3be 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommentOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommentOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Threading; using System.Threading.Tasks; using GraphQL; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommitOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommitOperations.cs index b32b6a795b..d76bc43037 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommitOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.CommitOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObjectOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObjectOperations.cs index 9ea3c3ed56..79e9f8b90f 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObjectOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObjectOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Threading; using System.Threading.Tasks; using GraphQL; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObsoleteOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObsoleteOperations.cs index 4148e1d1f8..e52cf28103 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObsoleteOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ObsoleteOperations.cs @@ -1,4 +1,3 @@ -#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -21,6 +20,7 @@ public partial class Client /// true if invites are supported /// if Speckle Server version is less than v2.6.4 [Obsolete("We're not supporting 2.6.4 version any more", true)] + [SuppressMessage("Style", "IDE1006:Naming Styles")] public async Task _CheckStreamInvitesSupported(CancellationToken cancellationToken = default) { var version = ServerVersion ?? await GetServerVersion(cancellationToken).ConfigureAwait(false); diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ServerOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ServerOperations.cs index f7a5ec7bf7..3533c4f234 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ServerOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.ServerOperations.cs @@ -1,5 +1,3 @@ -#nullable enable - using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.StreamOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.StreamOperations.cs index 079821640b..f90a6849f3 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.StreamOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.StreamOperations.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Threading; diff --git a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.UserOperations.cs b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.UserOperations.cs index 939f9aee2c..a79764e551 100644 --- a/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.UserOperations.cs +++ b/Core/Core/Api/GraphQL/Client.GraphqlCleintOperations/Client.UserOperations.cs @@ -1,4 +1,3 @@ -#nullable enable using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Branch.cs b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Branch.cs index dcb95c1c0b..a27910a071 100644 --- a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Branch.cs +++ b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Branch.cs @@ -1,12 +1,8 @@ +#nullable disable using System; using GraphQL; using Speckle.Core.Api.SubscriptionModels; -// // public partial class Log -// // { - -// } - namespace Speckle.Core.Api; public partial class Client @@ -16,7 +12,7 @@ public partial class Client public delegate void BranchCreatedHandler(object sender, BranchInfo e); public event BranchCreatedHandler OnBranchCreated; - public IDisposable BranchCreatedSubscription; + public IDisposable BranchCreatedSubscription { get; private set; } /// /// Subscribe to events of branch created for a stream @@ -42,7 +38,7 @@ public void SubscribeBranchCreated(string streamId) public delegate void BranchUpdatedHandler(object sender, BranchInfo e); public event BranchUpdatedHandler OnBranchUpdated; - public IDisposable BranchUpdatedSubscription; + public IDisposable BranchUpdatedSubscription { get; private set; } /// /// Subscribe to events of branch updated for a stream @@ -69,7 +65,7 @@ public void SubscribeBranchUpdated(string streamId, string branchId = null) public delegate void BranchDeletedHandler(object sender, BranchInfo e); public event BranchDeletedHandler OnBranchDeleted; - public IDisposable BranchDeletedSubscription; + public IDisposable BranchDeletedSubscription { get; private set; } /// /// Subscribe to events of branch deleted for a stream diff --git a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Commit.cs b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Commit.cs index ff264699a8..a3614ae68a 100644 --- a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Commit.cs +++ b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Commit.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using GraphQL; using Speckle.Core.Api.SubscriptionModels; diff --git a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Stream.cs b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Stream.cs index 062f0e22bb..a62e757fd6 100644 --- a/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Stream.cs +++ b/Core/Core/Api/GraphQL/Client.Subscriptions/Client.Subscriptions.Stream.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using GraphQL; using Speckle.Core.Api.SubscriptionModels; @@ -65,7 +66,6 @@ public void SubscribeStreamUpdated(string id) /// /// Subscribe to events of streams removed for the current user /// - /// public void SubscribeUserStreamRemoved() { var request = new GraphQLRequest { Query = @"subscription { userStreamRemoved }" }; diff --git a/Core/Core/Api/GraphQL/Client.cs b/Core/Core/Api/GraphQL/Client.cs index 65f147752b..bacfa63bc0 100644 --- a/Core/Core/Api/GraphQL/Client.cs +++ b/Core/Core/Api/GraphQL/Client.cs @@ -1,4 +1,3 @@ -# nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -24,18 +23,14 @@ namespace Speckle.Core.Api; -public partial class Client : IDisposable +public sealed partial class Client : IDisposable { + [Obsolete] internal Client() { } public Client(Account account) { - if (account == null) - { - throw new SpeckleException("Provided account is null."); - } - - Account = account; + Account = account ?? throw new SpeckleException("Provided account is null."); HttpClient = Http.GetHttpProxyClient(null, TimeSpan.FromSeconds(30)); Http.AddAuthHeader(HttpClient, account.token); @@ -56,7 +51,6 @@ public Client(Account account) { return Http.CanAddAuth(account.token, out string? authValue) ? new { Authorization = authValue } : null; }, - OnWebsocketConnected = OnWebSocketConnect }, new NewtonsoftJsonSerializer(), HttpClient @@ -106,12 +100,7 @@ public void Dispose() CommentActivitySubscription?.Dispose(); GQLClient?.Dispose(); } - catch { } - } - - public Task OnWebSocketConnect(GraphQLHttpClient client) - { - return Task.CompletedTask; + catch (Exception ex) when (!ex.IsFatal()) { } } internal async Task ExecuteWithResiliencePolicies(Func> func) @@ -132,7 +121,7 @@ internal async Task ExecuteWithResiliencePolicies(Func> func) delay, (ex, timeout, context) => { - var graphqlEx = ex as SpeckleGraphQLException; + var graphqlEx = (SpeckleGraphQLException)ex; SpeckleLog.Logger .ForContext("graphqlExtensions", graphqlEx.Extensions) .ForContext("graphqlErrorMessages", graphqlEx.ErrorMessages) @@ -149,9 +138,12 @@ internal async Task ExecuteWithResiliencePolicies(Func> func) return await graphqlRetry.ExecuteAsync(func).ConfigureAwait(false); } + /// "FORBIDDEN" on "UNAUTHORIZED" response from server + /// All other request errors + /// The requested a cancel public async Task ExecuteGraphQLRequest(GraphQLRequest request, CancellationToken cancellationToken = default) { - using IDisposable context0 = LogContext.Push(_createEnrichers(request)); + using IDisposable context0 = LogContext.Push(CreateEnrichers(request)); SpeckleLog.Logger.Debug("Starting execution of graphql request to get {resultType}", typeof(T).Name); var timer = new Stopwatch(); @@ -199,7 +191,7 @@ public async Task ExecuteGraphQLRequest(GraphQLRequest request, Cancellati } // we log and wrap anything that is not a graphql exception. // this makes sure, that any graphql operation only throws SpeckleGraphQLExceptions - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Warning( ex, @@ -230,7 +222,7 @@ internal void MaybeThrowFromGraphQLErrors(GraphQLRequest request, GraphQLResp // The errors reflect the Apollo server v2 API, which is deprecated. It is bound to change, // once we migrate to a newer version. var errors = response.Errors; - if (errors != null && errors.Any()) + if (errors != null && errors.Length != 0) { var errorMessages = errors.Select(e => e.Message); if ( @@ -250,8 +242,7 @@ internal void MaybeThrowFromGraphQLErrors(GraphQLRequest request, GraphQLResp if ( errors.Any( e => - e.Extensions != null - && (e.Extensions.Contains(new KeyValuePair("code", "STREAM_NOT_FOUND"))) + e.Extensions != null && e.Extensions.Contains(new KeyValuePair("code", "STREAM_NOT_FOUND")) ) ) { @@ -273,7 +264,7 @@ internal void MaybeThrowFromGraphQLErrors(GraphQLRequest request, GraphQLResp } } - private Dictionary _convertExpandoToDict(ExpandoObject expando) + private Dictionary ConvertExpandoToDict(ExpandoObject expando) { var variables = new Dictionary(); foreach (KeyValuePair kvp in expando) @@ -281,7 +272,7 @@ internal void MaybeThrowFromGraphQLErrors(GraphQLRequest request, GraphQLResp object value; if (kvp.Value is ExpandoObject ex) { - value = _convertExpandoToDict(ex); + value = ConvertExpandoToDict(ex); } else { @@ -293,12 +284,12 @@ internal void MaybeThrowFromGraphQLErrors(GraphQLRequest request, GraphQLResp return variables; } - private ILogEventEnricher[] _createEnrichers(GraphQLRequest request) + private ILogEventEnricher[] CreateEnrichers(GraphQLRequest request) { // i know this is double (de)serializing, but we need a recursive convert to // dict here var expando = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(request.Variables)); - var variables = request.Variables != null && expando != null ? _convertExpandoToDict(expando) : null; + var variables = request.Variables != null && expando != null ? ConvertExpandoToDict(expando) : null; return new ILogEventEnricher[] { new PropertyEnricher("serverUrl", ServerUrl), @@ -310,7 +301,7 @@ private ILogEventEnricher[] _createEnrichers(GraphQLRequest request) internal IDisposable SubscribeTo(GraphQLRequest request, Action callback) { - using (LogContext.Push(_createEnrichers(request))) + using (LogContext.Push(CreateEnrichers(request))) { try { @@ -374,7 +365,7 @@ internal IDisposable SubscribeTo(GraphQLRequest request, Action ca } ); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Warning( ex, diff --git a/Core/Core/Api/GraphQL/Models.cs b/Core/Core/Api/GraphQL/Models.cs index 8f0097ad19..2af16e3d00 100644 --- a/Core/Core/Api/GraphQL/Models.cs +++ b/Core/Core/Api/GraphQL/Models.cs @@ -1,6 +1,6 @@ +#nullable disable using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; namespace Speckle.Core.Api; @@ -379,15 +379,23 @@ public class ServerInfo { public string name { get; set; } public string company { get; set; } - public string url { get; set; } public string version { get; set; } public string adminContact { get; set; } public string description { get; set; } - //NOTE: this field is not returned from the GQL API - //it is manually populated by checking against the response headers - //TODO: deprecate after the transition from fe1 to fe2 + /// + /// This field is not returned from the GQL API, + /// it should populated on construction from the response headers. + /// see + /// public bool frontend2 { get; set; } + + /// + /// This field is not returned from the GQL API, + /// it should populated on construction. + /// see + /// + public string url { get; set; } } public class StreamData diff --git a/Core/Core/Api/GraphQL/Serializer/ConstantCaseEnumConverter.cs b/Core/Core/Api/GraphQL/Serializer/ConstantCaseEnumConverter.cs index e8d950f8a8..7088d10b20 100644 --- a/Core/Core/Api/GraphQL/Serializer/ConstantCaseEnumConverter.cs +++ b/Core/Core/Api/GraphQL/Serializer/ConstantCaseEnumConverter.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Linq; using System.Reflection; @@ -7,7 +9,7 @@ namespace Speckle.Core.Api.GraphQL.Serializer; -public class ConstantCaseEnumConverter : StringEnumConverter +internal class ConstantCaseEnumConverter : StringEnumConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { diff --git a/Core/Core/Api/GraphQL/Serializer/MapConverter.cs b/Core/Core/Api/GraphQL/Serializer/MapConverter.cs index ee09aacb85..0784343807 100644 --- a/Core/Core/Api/GraphQL/Serializer/MapConverter.cs +++ b/Core/Core/Api/GraphQL/Serializer/MapConverter.cs @@ -1,6 +1,7 @@ #nullable disable using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using GraphQL; using Speckle.Newtonsoft.Json; @@ -8,7 +9,7 @@ namespace Speckle.Core.Api.GraphQL.Serializer; -public class MapConverter : JsonConverter +internal sealed class MapConverter : JsonConverter { public override void WriteJson(JsonWriter writer, Map value, JsonSerializer serializer) { @@ -34,6 +35,11 @@ JsonSerializer serializer throw new ArgumentException("This converter can only parse when the root element is a JSON Object."); } + [SuppressMessage( + "Maintainability", + "CA1508:Avoid dead conditional code", + Justification = "False positive, see https://github.com/dotnet/roslyn-analyzers/issues/6893" + )] private object ReadToken(JToken token) { return token switch diff --git a/Core/Core/Api/GraphQL/Serializer/NewtonsoftJsonSerializer.cs b/Core/Core/Api/GraphQL/Serializer/NewtonsoftJsonSerializer.cs index 6eb97f00d3..3509559b63 100644 --- a/Core/Core/Api/GraphQL/Serializer/NewtonsoftJsonSerializer.cs +++ b/Core/Core/Api/GraphQL/Serializer/NewtonsoftJsonSerializer.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.IO; using System.Text; @@ -11,7 +12,7 @@ namespace Speckle.Core.Api.GraphQL.Serializer; -public class NewtonsoftJsonSerializer : IGraphQLWebsocketJsonSerializer +internal sealed class NewtonsoftJsonSerializer : IGraphQLWebsocketJsonSerializer { public NewtonsoftJsonSerializer() : this(DefaultJsonSerializerSettings) { } diff --git a/Core/Core/Api/GraphQL/SubscriptionModels.cs b/Core/Core/Api/GraphQL/SubscriptionModels.cs index b2dabbfb76..f1b253b610 100644 --- a/Core/Core/Api/GraphQL/SubscriptionModels.cs +++ b/Core/Core/Api/GraphQL/SubscriptionModels.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; diff --git a/Core/Core/Api/Helpers.cs b/Core/Core/Api/Helpers.cs index a4c136b0e2..dc3e2ef1c4 100644 --- a/Core/Core/Api/Helpers.cs +++ b/Core/Core/Api/Helpers.cs @@ -1,9 +1,9 @@ +#nullable disable using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; -using System.Globalization; -using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; @@ -21,51 +21,8 @@ namespace Speckle.Core.Api; public static class Helpers { - public const string ReleasesUrl = "https://releases.speckle.dev"; - private static string _feedsEndpoint = ReleasesUrl + "/manager2/feeds"; - - /// - /// Envirenment Variable that allows to overwrite the - /// /// - private static string _speckleUserDataEnvVar = "SPECKLE_USERDATA_PATH"; - - /// - /// Returns the correct location of the Speckle installation folder. Usually this would be the user's %appdata%/Speckle folder, unless the install was made for all users. - /// - /// The location of the Speckle installation folder - [Obsolete("Please use Helpers/SpecklePathProvider.InstallSpeckleFolderPath", true)] - public static string InstallSpeckleFolderPath => Path.Combine(InstallApplicationDataPath, "Speckle"); - - /// - /// Returns the correct location of the Speckle folder for the current user. Usually this would be the user's %appdata%/Speckle folder. - /// - /// The location of the Speckle installation folder - [Obsolete("Please use Helpers/SpecklePathProvider.UserSpeckleFolderPath()", true)] - public static string UserSpeckleFolderPath => Path.Combine(UserApplicationDataPath, "Speckle"); - - /// - /// Returns the correct location of the AppData folder where Speckle is installed. Usually this would be the user's %appdata% folder, unless the install was made for all users. - /// This folder contains Kits and othe data that can be shared among users of the same machine. - /// - /// The location of the AppData folder where Speckle is installed - [Obsolete("Please use Helpers/SpecklePathProvider.InstallApplicationDataPath ", true)] - public static string InstallApplicationDataPath => - Assembly.GetAssembly(typeof(Helpers)).Location.Contains("ProgramData") - ? Environment.GetFolderPath( - Environment.SpecialFolder.CommonApplicationData, - Environment.SpecialFolderOption.Create - ) - : UserApplicationDataPath; - - /// - /// Returns the location of the User Application Data folder for the current roaming user, which contains user specific data such as accounts and cache. - /// - /// The location of the user's `%appdata%` folder. - [Obsolete("Please use Helpers/SpecklePathProvider.UserApplicationDataPath", true)] - public static string UserApplicationDataPath => - !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(_speckleUserDataEnvVar)) - ? Environment.GetEnvironmentVariable(_speckleUserDataEnvVar) - : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create); + public const string RELEASES_URL = "https://releases.speckle.dev"; + private const string FEEDS_ENDPOINT = RELEASES_URL + "/manager2/feeds"; /// /// Helper method to Receive from a Speckle Server. @@ -73,14 +30,12 @@ public static class Helpers /// Stream URL or Id to receive from. If the URL contains branchName, commitId or objectId those will be used, otherwise the latest commit from main will be received. /// Account to use. If not provided the default account will be used. /// Action invoked on progress iterations. - /// Action invoked on internal errors. /// Action invoked once the total count of objects is known. /// public static async Task Receive( string stream, Account account = null, Action> onProgressAction = null, - Action onErrorAction = null, Action onTotalChildrenCountKnown = null ) { @@ -90,7 +45,7 @@ public static async Task Receive( { account ??= await sw.GetAccount().ConfigureAwait(false); } - catch (SpeckleException e) + catch (SpeckleException) { if (string.IsNullOrEmpty(sw.StreamId)) { @@ -129,7 +84,7 @@ public static async Task Receive( var branchName = string.IsNullOrEmpty(sw.BranchName) ? "main" : sw.BranchName; var branch = await client.BranchGet(sw.StreamId, branchName, 1).ConfigureAwait(false); - if (!branch.commits.items.Any()) + if (branch.commits.items.Count == 0) { throw new SpeckleException("The selected branch has no commits."); } @@ -152,10 +107,8 @@ public static async Task Receive( .Receive( objectId, transport, - onErrorAction: onErrorAction, onProgressAction: onProgressAction, - onTotalChildrenCountKnown: onTotalChildrenCountKnown, - disposeTransports: true + onTotalChildrenCountKnown: onTotalChildrenCountKnown ) .ConfigureAwait(false); @@ -173,7 +126,7 @@ await client ) .ConfigureAwait(false); } - catch + catch (Exception ex) when (!ex.IsFatal()) { // Do nothing! } @@ -188,7 +141,6 @@ await client /// Account to use. If not provided the default account will be used. /// Toggle for the default cache. If set to false, it will only send to the provided transports. /// Action invoked on progress iterations. - /// Action invoked on internal errors. /// public static async Task Send( string stream, @@ -198,20 +150,17 @@ public static async Task Send( int totalChildrenCount = 0, Account account = null, bool useDefaultCache = true, - Action> onProgressAction = null, - Action onErrorAction = null + Action> onProgressAction = null ) { var sw = new StreamWrapper(stream); using var client = new Client(account ?? await sw.GetAccount().ConfigureAwait(false)); - var transport = new ServerTransport(client.Account, sw.StreamId); + using ServerTransport transport = new(client.Account, sw.StreamId); var branchName = string.IsNullOrEmpty(sw.BranchName) ? "main" : sw.BranchName; - var objectId = await Operations - .Send(data, new List { transport }, useDefaultCache, onProgressAction, onErrorAction, true) - .ConfigureAwait(false); + var objectId = await Operations.Send(data, transport, useDefaultCache, onProgressAction).ConfigureAwait(false); Analytics.TrackEvent(client.Account, Analytics.Events.Send); @@ -237,30 +186,27 @@ public static async Task Send( /// public static async Task IsConnectorUpdateAvailable(string slug) { -#if DEBUG - if (slug == "dui2") + //when debugging the version is not correct, so don't bother + if (!Analytics.IsReleaseMode) { - slug = "revit"; + return false; } - //when debugging the version is not correct, so don't bother - return false; -#endif try { - HttpClient client = Http.GetHttpProxyClient(); - var response = await client.GetStringAsync($"{_feedsEndpoint}/{slug}.json").ConfigureAwait(false); + using HttpClient client = Http.GetHttpProxyClient(); + var response = await client.GetStringAsync($"{FEEDS_ENDPOINT}/{slug}.json").ConfigureAwait(false); var connector = JsonSerializer.Deserialize(response); - var os = Os.Win; + var os = Os.Win; //TODO: This won't work for linux if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { os = Os.OSX; } var versions = connector.Versions.Where(x => x.Os == os).OrderByDescending(x => x.Date).ToList(); - var stables = versions.Where(x => !x.Prerelease); - if (!stables.Any()) + var stables = versions.Where(x => !x.Prerelease).ToArray(); + if (stables.Length == 0) { return false; } @@ -274,7 +220,7 @@ public static async Task IsConnectorUpdateAvailable(string slug) return true; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.ForContext("slug", slug).Warning(ex, "Failed to check for connector updates"); } @@ -354,8 +300,9 @@ public static string TimeAgo(DateTime timestamp) } [Pure] - public static string PluralS(int num) - { - return num != 1 ? "s" : ""; - } + public static string PluralS(int num) => num != 1 ? "s" : ""; + + [Obsolete("Renamed to " + nameof(RELEASES_URL))] + [SuppressMessage("Style", "IDE1006:Naming Styles")] + public const string ReleasesUrl = RELEASES_URL; } diff --git a/Core/Core/Api/Operations/Operations.Receive.Obsolete.cs b/Core/Core/Api/Operations/Operations.Receive.Obsolete.cs new file mode 100644 index 0000000000..02a7de42c4 --- /dev/null +++ b/Core/Core/Api/Operations/Operations.Receive.Obsolete.cs @@ -0,0 +1,533 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Serilog.Context; +using Speckle.Core.Logging; +using Speckle.Core.Models; +using Speckle.Core.Serialisation; +using Speckle.Core.Transports; +using Speckle.Newtonsoft.Json; + +namespace Speckle.Core.Api; + +#pragma warning disable CA1068, IDE1006 + +[Obsolete("Serializer v1 is deprecated")] +public enum SerializerVersion +{ + V1, + V2 +} + +public static partial class Operations +{ + private const string RECEIVE_DEPRECATION_MESSAGE = """ + This method overload is obsolete, consider using a non-obsolete overload. + 1.SerializerVersion selection will no longer be supported going foward (serializer v1 is now deprecated). + 2.Use of disposeTransports will no longer be supported going forward (you should dispose your own transports). + 3 OnErrorAction is no longer used (instead functions with throw exceptions for consistancy and clear stack trace) + """; + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + CancellationToken cancellationToken, + ITransport? remoteTransport, + ITransport? localTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports + ) + { + return Receive( + objectId, + cancellationToken, + remoteTransport, + localTransport, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + CancellationToken cancellationToken, + ITransport? remoteTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports, + SerializerVersion serializerVersion + ) + { + return Receive( + objectId, + cancellationToken, + remoteTransport, + null, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + serializerVersion + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + CancellationToken cancellationToken, + ITransport? remoteTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports + ) + { + return Receive( + objectId, + cancellationToken, + remoteTransport, + null, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + CancellationToken cancellationToken, + ITransport? remoteTransport, + bool disposeTransports + ) + { + return Receive( + objectId, + cancellationToken, + remoteTransport, + null, + null, + null, + null, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + ITransport? localTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports, + SerializerVersion serializerVersion + ) + { + return Receive( + objectId, + CancellationToken.None, + remoteTransport, + localTransport, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + serializerVersion + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + ITransport? localTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports + ) + { + return Receive( + objectId, + CancellationToken.None, + remoteTransport, + localTransport, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports + ) + { + return Receive( + objectId, + CancellationToken.None, + remoteTransport, + null, + onProgressAction, + onErrorAction, + onTotalChildrenCountKnown, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + ITransport? localTransport, + bool disposeTransports + ) + { + return Receive( + objectId, + CancellationToken.None, + remoteTransport, + localTransport, + null, + null, + null, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive(string objectId, ITransport? remoteTransport, bool disposeTransports) + { + return Receive( + objectId, + CancellationToken.None, + remoteTransport, + null, + null, + null, + null, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive(string objectId, bool disposeTransports) + { + return Receive( + objectId, + CancellationToken.None, + null, + null, + null, + null, + null, + disposeTransports, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + ITransport? localTransport, + Action? onErrorAction + ) + { + return Receive( + objectId, + default, + remoteTransport, + localTransport, + null, + onErrorAction, + null, + false, + SerializerVersion.V2 + ); + } + + /// + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static Task Receive( + string objectId, + ITransport? remoteTransport, + Action? onErrorAction + ) + { + return Receive(objectId, default, remoteTransport, null, null, onErrorAction, null, false, SerializerVersion.V2); + } + + /// + /// Receives an object from a transport. + /// + /// + /// This overload is deprecated. You should consider using + /// + ///
+ /// The new overload no longer support switching as v1 is now deprecated. + ///
+ /// We also no longer offer the option to . + /// You should instead handle disposal yourself + /// using conventional mechanisms like the using keyword or try finally block
+ ///
+ /// This function overload will be kept around for several releases, but will eventually be removed. + ///
+ /// + /// The transport to receive from. + /// Leave null to use the default cache. + /// Action invoked on progress iterations. + /// Action invoked on internal errors. + /// Action invoked once the total count of objects is known. + /// + [Obsolete(RECEIVE_DEPRECATION_MESSAGE)] + public static async Task Receive( + string objectId, + CancellationToken cancellationToken, + ITransport? remoteTransport, + ITransport? localTransport, + Action>? onProgressAction, + Action? onErrorAction, + Action? onTotalChildrenCountKnown, + bool disposeTransports, + SerializerVersion serializerVersion + ) + { + var hasUserProvidedLocalTransport = localTransport != null; + localTransport ??= new SQLiteTransport(); + using (LogContext.PushProperty("remoteTransportContext", remoteTransport?.TransportContext)) + using (LogContext.PushProperty("localTransportContext", localTransport.TransportContext)) + using (LogContext.PushProperty("objectId", objectId)) + { + var timer = Stopwatch.StartNew(); + SpeckleLog.Logger.Information( + "Starting receive {objectId} from transports {localTransport} / {remoteTransport}", + objectId, + localTransport.TransportName, + remoteTransport?.TransportName + ); + + BaseObjectSerializer? serializer = null; + JsonSerializerSettings? settings = null; + BaseObjectDeserializerV2? serializerV2 = null; + if (serializerVersion == SerializerVersion.V1) + { + (serializer, settings) = GetSerializerInstance(); + } + else + { + serializerV2 = new BaseObjectDeserializerV2(); + } + + var internalProgressAction = GetInternalProgressAction(onProgressAction); + + localTransport.OnProgressAction = internalProgressAction; + localTransport.CancellationToken = cancellationToken; + + if (serializerVersion == SerializerVersion.V1) + { + serializer!.ReadTransport = localTransport; + serializer.OnProgressAction = internalProgressAction; + serializer.OnErrorAction = onErrorAction; + serializer.CancellationToken = cancellationToken; + } + else + { + serializerV2!.ReadTransport = localTransport; + serializerV2.OnProgressAction = internalProgressAction; + serializerV2.OnErrorAction = onErrorAction; + serializerV2.CancellationToken = cancellationToken; + if (remoteTransport is IBlobCapableTransport t) + { + serializerV2.BlobStorageFolder = t.BlobStorageFolder; + } + } + + // First we try and get the object from the local transport. If it's there, we assume all its children are there, and proceed with deserialisation. + // This assumption is hard-wired into the SDK. Read below. + var objString = localTransport.GetObject(objectId); + + if (objString != null) + { + // Shoot out the total children count + var partial = JsonConvert.DeserializeObject(objString); + if (partial == null) + { + throw new SpeckleDeserializeException( + $"Failed to deserialize {nameof(objString)} into {nameof(Placeholder)}" + ); + } + + if (partial.__closure != null) + { + onTotalChildrenCountKnown?.Invoke(partial.__closure.Count); + } + + Base? localRes = DeserializeStringToBase(serializerVersion, objString, settings, serializerV2); + + if ((disposeTransports || !hasUserProvidedLocalTransport) && localTransport is IDisposable dispLocal) + { + dispLocal.Dispose(); + } + + if (disposeTransports && remoteTransport != null && remoteTransport is IDisposable dispRemote) + { + dispRemote.Dispose(); + } + + timer.Stop(); + SpeckleLog.Logger + .ForContext("deserializerElapsed", serializerV2?.Elapsed) + .ForContext( + "transportElapsedBreakdown", + new[] { localTransport, remoteTransport } + .Where(t => t != null) + .ToDictionary(t => t!.TransportName, t => t!.Elapsed) + ) + .Information( + "Finished receiving {objectId} from {source} in {elapsed} seconds", + objectId, + localTransport.TransportName, + timer.Elapsed.TotalSeconds + ); + return localRes; + } + + if (remoteTransport == null) + { + var ex = new SpeckleException( + $"Could not find specified object using the local transport {localTransport.TransportName}, and you didn't provide a fallback remote from which to pull it." + ); + + SpeckleLog.Logger.Error(ex, "Cannot receive object from the given transports {exceptionMessage}", ex.Message); + throw ex; + } + + // If we've reached this stage, it means that we didn't get a local transport hit on our object, so we will proceed to get it from the provided remote transport. + // This is done by copying itself and all its children from the remote transport into the local one. + remoteTransport.OnProgressAction = internalProgressAction; + remoteTransport.CancellationToken = cancellationToken; + + SpeckleLog.Logger.Debug( + "Cannot find object {objectId} in the local transport, hitting remote {transportName}", + remoteTransport.TransportName + ); + objString = await remoteTransport + .CopyObjectAndChildren(objectId, localTransport, onTotalChildrenCountKnown) + .ConfigureAwait(false); + + // Wait for the local transport to finish "writing" - in this case, it signifies that the remote transport has done pushing copying objects into it. (TODO: I can see some scenarios where latency can screw things up, and we should rather wait on the remote transport). + await localTransport.WriteComplete().ConfigureAwait(false); + + // Proceed to deserialise the object, now safely knowing that all its children are present in the local (fast) transport. + + Base? res = DeserializeStringToBase(serializerVersion, objString, settings, serializerV2); + if ((disposeTransports || !hasUserProvidedLocalTransport) && localTransport is IDisposable dl) + { + dl.Dispose(); + } + + if (disposeTransports && remoteTransport is IDisposable dr) + { + dr.Dispose(); + } + + SpeckleLog.Logger + .ForContext("deserializerElapsed", serializerV2?.Elapsed) + .ForContext( + "transportElapsedBreakdown", + new[] { localTransport, remoteTransport } + .Where(t => t != null) + .ToDictionary(t => t.TransportName, t => t.Elapsed) + ) + .Information( + "Finished receiving {objectId} from {source} in {elapsed} seconds", + objectId, + remoteTransport.TransportName, + timer.Elapsed.TotalSeconds + ); + return res; + + // Summary: + // Basically, receiving an object (and all its subchildren) operates with two transports, one that is potentially slow, and one that is fast. + // The fast transport ("localTransport") is used syncronously inside the deserialisation routine to get the value of nested references and set them. The slow transport ("remoteTransport") is used to get the raw data and populate the local transport with all necessary data for a successful deserialisation of the object. + // Note: if properly implemented, there is no hard distinction between what is a local or remote transport; it's still just a transport. So, for example, if you want to receive an object without actually writing it first to a local transport, you can just pass a Server/S3 transport as a local transport. + // This is not reccommended, but shows what you can do. Another tidbit: the local transport does not need to be disk-bound; it can easily be an in memory transport. In memory transports are the fastest ones, but they're of limited use for more + } + } + + [Obsolete("Serializer v1 is deprecated, use other overload(s)")] + private static Base? DeserializeStringToBase( + SerializerVersion serializerVersion, + string objString, + JsonSerializerSettings? settings, + BaseObjectDeserializerV2? serializerV2 + ) + { + if (serializerVersion == SerializerVersion.V1) + { + return JsonConvert.DeserializeObject(objString, settings); + } + else + { + return serializerV2!.Deserialize(objString); + } + } +} + +[Obsolete("Use " + nameof(TransportHelpers.Placeholder))] +internal sealed class Placeholder +{ + public Dictionary? __closure { get; set; } = new(); +} + +#pragma warning restore CA1068, IDE1006 diff --git a/Core/Core/Api/Operations/Operations.Receive.cs b/Core/Core/Api/Operations/Operations.Receive.cs index f7759e818e..2c8d1d98c4 100644 --- a/Core/Core/Api/Operations/Operations.Receive.cs +++ b/Core/Core/Api/Operations/Operations.Receive.cs @@ -1,5 +1,3 @@ -# nullable enable - using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -12,180 +10,89 @@ using Speckle.Core.Models; using Speckle.Core.Serialisation; using Speckle.Core.Transports; -using Speckle.Newtonsoft.Json; namespace Speckle.Core.Api; -public enum SerializerVersion -{ - V1, - V2 -} - public static partial class Operations { /// - /// Receives an object from a transport. + /// Receives an object (and all its sub-children) from the two provided s. + ///
+ /// Will first try and find objects using the (the faster transport) + /// If not found, will attempt to copy the objects from the into the before deserialization ///
- /// - /// The transport to receive from. - /// Leave null to use the default cache. - /// Action invoked on progress iterations. - /// Action invoked on internal errors. - /// Action invoked once the total count of objects is known. - /// - public static Task Receive( + /// + /// If Transports are properly implemented, there is no hard distinction between what is a local or remote transport; it's still just an . + ///
So, for example, if you want to receive an object without actually writing it first to a local transport, you can just pass a as a local transport. + ///
This is not recommended, but shows what you can do. Another tidbit: the local transport does not need to be disk-bound; it can easily be an in . In memory transports are the fastest ones, but they're of limited use for larger datasets + ///
+ /// The id of the object to receive + /// The remote transport (slower). If , will assume all objects are present in + /// The local transport (faster). If , will use a default cache + /// Action invoked on progress iterations + /// Action invoked once the total count of objects is known + /// + /// Failed to retrieve objects from the provided transport(s) + /// Deserialization of the requested object(s) failed + /// requested cancel + /// The requested Speckle Object + public static async Task Receive( string objectId, ITransport? remoteTransport = null, ITransport? localTransport = null, Action>? onProgressAction = null, - Action? onErrorAction = null, Action? onTotalChildrenCountKnown = null, - bool disposeTransports = false, - SerializerVersion serializerVersion = SerializerVersion.V2 + CancellationToken cancellationToken = default ) { - return Receive( - objectId, - CancellationToken.None, - remoteTransport, - localTransport, - onProgressAction, - onErrorAction, - onTotalChildrenCountKnown, - disposeTransports, - serializerVersion - ); - } - - /// - /// Receives an object from a transport. - /// - /// - /// A cancellation token that can be used by other objects or threads to send notice of cancellation. - /// The transport to receive from. - /// Leave null to use the default cache. - /// Action invoked on progress iterations. - /// Action invoked on internal errors. - /// Action invoked once the total count of objects is known. - /// - public static async Task Receive( - string objectId, - CancellationToken cancellationToken, - ITransport? remoteTransport = null, - ITransport? localTransport = null, - Action>? onProgressAction = null, - Action? onErrorAction = null, - Action? onTotalChildrenCountKnown = null, - bool disposeTransports = false, - SerializerVersion serializerVersion = SerializerVersion.V2 - ) - { - var hasUserProvidedLocalTransport = localTransport != null; - localTransport ??= new SQLiteTransport(); - using (LogContext.PushProperty("remoteTransportContext", remoteTransport?.TransportContext)) - using (LogContext.PushProperty("localTransportContext", localTransport.TransportContext)) - using (LogContext.PushProperty("objectId", objectId)) - { - var timer = Stopwatch.StartNew(); - SpeckleLog.Logger.Information( - "Starting receive {objectId} from transports {localTransport} / {remoteTransport}", - objectId, - localTransport.TransportName, - remoteTransport?.TransportName - ); - - BaseObjectSerializer? serializer = null; - JsonSerializerSettings? settings = null; - BaseObjectDeserializerV2? serializerV2 = null; - if (serializerVersion == SerializerVersion.V1) - { - (serializer, settings) = GetSerializerInstance(); - } - else - { - serializerV2 = new BaseObjectDeserializerV2(); - } + // Setup Progress Reporting + var internalProgressAction = GetInternalProgressAction(onProgressAction); - var localProgressDict = new ConcurrentDictionary(); - var internalProgressAction = GetInternalProgressAction(localProgressDict, onProgressAction); - - localTransport.OnErrorAction = onErrorAction; - localTransport.OnProgressAction = internalProgressAction; - localTransport.CancellationToken = cancellationToken; - - if (serializerVersion == SerializerVersion.V1) - { - serializer!.ReadTransport = localTransport; - serializer.OnProgressAction = internalProgressAction; - serializer.OnErrorAction = onErrorAction; - serializer.CancellationToken = cancellationToken; - } - else - { - serializerV2!.ReadTransport = localTransport; - serializerV2.OnProgressAction = internalProgressAction; - serializerV2.OnErrorAction = onErrorAction; - serializerV2.CancellationToken = cancellationToken; - if (remoteTransport is IBlobCapableTransport t) - { - serializerV2.BlobStorageFolder = t.BlobStorageFolder; - } - } + // Setup Local Transport + using IDisposable? d1 = UseDefaultTransportIfNull(localTransport, out localTransport); + localTransport.OnProgressAction = internalProgressAction; + localTransport.CancellationToken = cancellationToken; - // First we try and get the object from the local transport. If it's there, we assume all its children are there, and proceed with deserialisation. - // This assumption is hard-wired into the SDK. Read below. - var objString = localTransport.GetObject(objectId); + // Setup Remote Transport + if (remoteTransport is not null) + { + remoteTransport.OnProgressAction = internalProgressAction; + remoteTransport.CancellationToken = cancellationToken; + } - if (objString != null) + // Setup Serializer + BaseObjectDeserializerV2 serializerV2 = + new() { - // Shoot out the total children count - var partial = JsonConvert.DeserializeObject(objString); - if (partial == null) - { - throw new SpeckleDeserializeException( - $"Failed to deserialize {nameof(objString)} into {nameof(Placeholder)}" - ); - } - - if (partial.__closure != null) - { - onTotalChildrenCountKnown?.Invoke(partial.__closure.Count); - } - - Base? localRes = DeserializeStringToBase(serializerVersion, objString, settings, serializerV2); - - if ((disposeTransports || !hasUserProvidedLocalTransport) && localTransport is IDisposable dispLocal) - { - dispLocal.Dispose(); - } - - if (disposeTransports && remoteTransport != null && remoteTransport is IDisposable dispRemote) - { - dispRemote.Dispose(); - } + ReadTransport = localTransport, + OnProgressAction = internalProgressAction, + CancellationToken = cancellationToken, + BlobStorageFolder = (remoteTransport as IBlobCapableTransport)?.BlobStorageFolder + }; + + // Setup Logging + using IDisposable d2 = LogContext.PushProperty("remoteTransportContext", remoteTransport?.TransportContext); + using IDisposable d3 = LogContext.PushProperty("localTransportContext", localTransport.TransportContext); + using IDisposable d4 = LogContext.PushProperty("objectId", objectId); + var timer = Stopwatch.StartNew(); + + // Receive Json + SpeckleLog.Logger.Information( + "Starting receive {objectId} from transports {localTransport} / {remoteTransport}", + objectId, + localTransport.TransportName, + remoteTransport?.TransportName + ); - timer.Stop(); - SpeckleLog.Logger - .ForContext("deserializerElapsed", serializerV2?.Elapsed) - .ForContext( - "transportElapsedBreakdown", - new[] { localTransport, remoteTransport } - .Where(t => t != null) - .ToDictionary(t => t!.TransportName, t => t!.Elapsed) - ) - .Information( - "Finished receiving {objectId} from {source} in {elapsed} seconds", - objectId, - localTransport.TransportName, - timer.Elapsed.TotalSeconds - ); - return localRes; - } + // Try Local Receive + string? objString = LocalReceive(objectId, localTransport, onTotalChildrenCountKnown); - if (remoteTransport == null) + if (objString is null) + { + // Fall back to remote + if (remoteTransport is null) { - var ex = new SpeckleException( + var ex = new TransportException( $"Could not find specified object using the local transport {localTransport.TransportName}, and you didn't provide a fallback remote from which to pull it." ); @@ -193,114 +100,107 @@ public static partial class Operations throw ex; } - // If we've reached this stage, it means that we didn't get a local transport hit on our object, so we will proceed to get it from the provided remote transport. - // This is done by copying itself and all its children from the remote transport into the local one. - remoteTransport.OnErrorAction = onErrorAction; - remoteTransport.OnProgressAction = internalProgressAction; - remoteTransport.CancellationToken = cancellationToken; - SpeckleLog.Logger.Debug( - "Cannot find object {objectId} in the local transport, hitting remote {transportName}.", + "Cannot find object {objectId} in the local transport, hitting remote {transportName}", + objectId, remoteTransport.TransportName ); - objString = await remoteTransport - .CopyObjectAndChildren(objectId, localTransport, onTotalChildrenCountKnown) - .ConfigureAwait(false); - // Wait for the local transport to finish "writing" - in this case, it signifies that the remote transport has done pushing copying objects into it. (TODO: I can see some scenarios where latency can screw things up, and we should rather wait on the remote transport). - await localTransport.WriteComplete().ConfigureAwait(false); - - // Proceed to deserialise the object, now safely knowing that all its children are present in the local (fast) transport. - - Base? res = DeserializeStringToBase(serializerVersion, objString, settings, serializerV2); - if ((disposeTransports || !hasUserProvidedLocalTransport) && localTransport is IDisposable dl) - { - dl.Dispose(); - } - - if (disposeTransports && remoteTransport is IDisposable dr) - { - dr.Dispose(); - } + objString = await RemoteReceive(objectId, remoteTransport, localTransport, onTotalChildrenCountKnown) + .ConfigureAwait(false); + } - SpeckleLog.Logger - .ForContext("deserializerElapsed", serializerV2.Elapsed) - .ForContext( - "transportElapsedBreakdown", - new[] { localTransport, remoteTransport } - .Where(t => t != null) - .ToDictionary(t => t.TransportName, t => t.Elapsed) - ) - .Information( - "Finished receiving {objectId} from {source} in {elapsed} seconds", - objectId, - remoteTransport.TransportName, - timer.Elapsed.TotalSeconds - ); - return res; + // Proceed to deserialize the object, now safely knowing that all its children are present in the local (fast) transport. + Base res = serializerV2.Deserialize(objString); + + timer.Stop(); + SpeckleLog.Logger + .ForContext("deserializerElapsed", serializerV2.Elapsed) + .ForContext( + "transportElapsedBreakdown", + new[] { localTransport, remoteTransport } + .Where(t => t != null) + .Select(t => new KeyValuePair(t!.TransportName, t.Elapsed)) + .ToArray() + ) + .Information( + "Finished receiving {objectId} from {source} in {elapsed} seconds", + objectId, + remoteTransport?.TransportName, + timer.Elapsed.TotalSeconds + ); - // Summary: - // Basically, receiving an object (and all its subchildren) operates with two transports, one that is potentially slow, and one that is fast. - // The fast transport ("localTransport") is used syncronously inside the deserialisation routine to get the value of nested references and set them. The slow transport ("remoteTransport") is used to get the raw data and populate the local transport with all necessary data for a successful deserialisation of the object. - // Note: if properly implemented, there is no hard distinction between what is a local or remote transport; it's still just a transport. So, for example, if you want to receive an object without actually writing it first to a local transport, you can just pass a Server/S3 transport as a local transport. - // This is not reccommended, but shows what you can do. Another tidbit: the local transport does not need to be disk-bound; it can easily be an in memory transport. In memory transports are the fastest ones, but they're of limited use for more - } + return res; } - private static Base? DeserializeStringToBase( - SerializerVersion serializerVersion, - string objString, - JsonSerializerSettings? settings, - BaseObjectDeserializerV2? serializerV2 + /// + /// Try and get the object from the local transport. If it's there, we assume all its children are there + /// This assumption is hard-wired into the + /// + /// + /// + /// + /// + /// + internal static string? LocalReceive( + string objectId, + ITransport localTransport, + Action? onTotalChildrenCountKnown ) { - Base? localRes; - if (serializerVersion == SerializerVersion.V1) + string? objString = localTransport.GetObject(objectId); + if (objString is null) { - localRes = JsonConvert.DeserializeObject(objString, settings); + return null; } - else - { - try - { - localRes = serializerV2!.Deserialize(objString); - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception ex) - { - SpeckleLog.Logger.Error(ex, "A deserialization error has occurred {exceptionMessage}", ex.Message); - if (serializerV2.OnErrorAction == null) - { - throw; - } - serializerV2.OnErrorAction.Invoke( - $"A deserialization error has occurred: {ex.Message}", - new SpeckleDeserializeException("A deserialization error has occurred", ex) - ); - localRes = null; - } - } + // Shoot out the total children count + var closures = TransportHelpers.GetClosureTable(objString); + + onTotalChildrenCountKnown?.Invoke(closures?.Count ?? 0); - return localRes; + return objString; } - internal class Placeholder + /// + /// Copies the requested object and all its children from to + /// + /// + /// + /// + /// + /// + /// + /// Remote transport was not specified + private static async Task RemoteReceive( + string objectId, + ITransport remoteTransport, + ITransport localTransport, + Action? onTotalChildrenCountKnown + ) { - public Dictionary? __closure { get; set; } = new(); + var objString = await remoteTransport + .CopyObjectAndChildren(objectId, localTransport, onTotalChildrenCountKnown) + .ConfigureAwait(false); + + // DON'T THINK THIS IS NEEDED CopyObjectAndChildren should call this + // Wait for the local transport to finish "writing" - in this case, it signifies that the remote transport has done pushing copying objects into it. (TODO: I can see some scenarios where latency can screw things up, and we should rather wait on the remote transport). + await localTransport.WriteComplete().ConfigureAwait(false); + + return objString; } - public class SpeckleDeserializeException : SpeckleException + private static IDisposable? UseDefaultTransportIfNull(ITransport? userTransport, out ITransport actualLocalTransport) { - public SpeckleDeserializeException() { } - - public SpeckleDeserializeException(string message, Exception? inner = null) - : base(message, inner) { } + if (userTransport is not null) + { + actualLocalTransport = userTransport; + return null; + } - public SpeckleDeserializeException(string message) - : base(message) { } + //User did not specify a transport, default to SQLite + SQLiteTransport defaultLocalTransport = new(); + actualLocalTransport = defaultLocalTransport; + return defaultLocalTransport; } } diff --git a/Core/Core/Api/Operations/Operations.Send.Obsolete.cs b/Core/Core/Api/Operations/Operations.Send.Obsolete.cs new file mode 100644 index 0000000000..2d07a601eb --- /dev/null +++ b/Core/Core/Api/Operations/Operations.Send.Obsolete.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Serilog.Context; +using Speckle.Core.Logging; +using Speckle.Core.Models; +using Speckle.Core.Serialisation; +using Speckle.Core.Transports; +using Speckle.Newtonsoft.Json; +using Speckle.Newtonsoft.Json.Linq; + +namespace Speckle.Core.Api; + +public static partial class Operations +{ + private const string DEPRECATION_NOTICE = """ + This Send overload has been replaced by an overload with fewer function arguments. + We are no longer supporting SerializerV1, OnErrorAction, or handling disposal of transports. + Consider switching one of the other send overloads instead. + This function will be kept around for several releases, but will eventually be removed. + """; + + /// + [Obsolete("This overload has been deprecated along with serializer v1. Use other Send overloads instead.")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + public static Task Send(Base @object) => Send(@object, CancellationToken.None); + + /// + [Obsolete("This overload has been deprecated along with serializer v1. Use other Send overloads instead.")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + public static Task Send( + Base @object, + List? transports, + bool useDefaultCache, + Action>? onProgressAction, + Action? onErrorAction, + bool disposeTransports, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) => + Send( + @object, + CancellationToken.None, + transports, + useDefaultCache, + onProgressAction, + onErrorAction, + disposeTransports, + serializerVersion + ); + + /// + [Obsolete("This overload has been deprecated along with serializer v1. Use other Send overloads instead.")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + public static Task Send( + Base @object, + List? transports, + bool useDefaultCache, + bool disposeTransports, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) => + Send( + @object, + CancellationToken.None, + transports, + useDefaultCache, + null, + null, + disposeTransports, + serializerVersion + ); + + /// + [Obsolete("This overload has been deprecated along with serializer v1. Use other Send overloads instead.")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + public static Task Send( + Base @object, + bool disposeTransports, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) => Send(@object, CancellationToken.None, null, true, null, null, disposeTransports, serializerVersion); + + /// + /// Sends an object via the provided transports. Defaults to the local cache. + /// + /// + /// This overload is deprecated. You should consider using + ///
+ ///
or + ///
+ ///
+ /// These new overloads no longer support switching as v1 is now deprecated. + ///
+ /// We also no longer offer the option to . + /// You should instead handle disposal yourself + /// using conventional mechanisms like the using keyword.
+ ///
+ /// This function overload will be kept around for several releases, but will eventually be removed. + ///
+ /// The object you want to send. + /// A cancellation token that can be used by other objects or threads to send notice of cancellation. + /// Where you want to send them. + /// Toggle for the default cache. If set to false, it will only send to the provided transports. + /// Action that gets triggered on every progress tick (keeps track of all transports). + /// Use this to capture and handle any errors from within the transports. + /// + /// + /// The id (hash) of the object. + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + [Obsolete(DEPRECATION_NOTICE)] + public static async Task Send( + Base @object, + CancellationToken cancellationToken, + List? transports = null, + bool useDefaultCache = true, + Action>? onProgressAction = null, + Action? onErrorAction = null, + bool disposeTransports = false, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) + { + transports ??= new List(); + using var sqLiteTransport = new SQLiteTransport { TransportName = "LC" }; + + if (transports.Count == 0 && useDefaultCache == false) + { + throw new ArgumentException( + "You need to provide at least one transport: cannot send with an empty transport list and no default cache.", + nameof(transports) + ); + } + + if (useDefaultCache) + { + transports.Insert(0, sqLiteTransport); + } + + var transportContext = transports.ToDictionary(t => t.TransportName, t => t.TransportContext); + + // make sure all logs in the operation have the proper context + using (LogContext.PushProperty("transportContext", transportContext)) + using (LogContext.PushProperty("correlationId", Guid.NewGuid().ToString())) + { + var sendTimer = Stopwatch.StartNew(); + SpeckleLog.Logger.Information("Starting send operation"); + + var internalProgressAction = GetInternalProgressAction(onProgressAction); + + BaseObjectSerializer? serializer = null; + JsonSerializerSettings? settings = null; + BaseObjectSerializerV2? serializerV2 = null; + if (serializerVersion == SerializerVersion.V1) + { + (serializer, settings) = GetSerializerInstance(); + serializer.WriteTransports = transports; + serializer!.OnProgressAction = internalProgressAction; + serializer.CancellationToken = cancellationToken; + serializer.OnErrorAction = onErrorAction; + } + else + { + serializerV2 = new BaseObjectSerializerV2(transports, internalProgressAction, cancellationToken); + } + + foreach (var t in transports) + { + t.OnProgressAction = internalProgressAction; + t.CancellationToken = cancellationToken; + t.BeginWrite(); + } + + string obj; + List transportAwaits; + if (serializerVersion == SerializerVersion.V1) + { + obj = JsonConvert.SerializeObject(@object, settings); + transportAwaits = serializer!.WriteTransports.Select(t => t.WriteComplete()).ToList(); + } + else + { + obj = serializerV2!.Serialize(@object); + transportAwaits = serializerV2.WriteTransports.Select(t => t.WriteComplete()).ToList(); + } + + if (cancellationToken.IsCancellationRequested) + { + SpeckleLog.Logger.Information( + "Send operation cancelled after {elapsed} seconds", + sendTimer.Elapsed.TotalSeconds + ); + cancellationToken.ThrowIfCancellationRequested(); + } + + await Task.WhenAll(transportAwaits).ConfigureAwait(false); + + foreach (var t in transports) + { + t.EndWrite(); + if (useDefaultCache && t is SQLiteTransport lc && lc.TransportName == "LC") + { + lc.Dispose(); + continue; + } + if (disposeTransports && t is IDisposable disp) + { + disp.Dispose(); + } + } + + if (cancellationToken.IsCancellationRequested) + { + SpeckleLog.Logger.Information("Send operation cancelled after {elapsed}", sendTimer.Elapsed.TotalSeconds); + cancellationToken.ThrowIfCancellationRequested(); + } + + var idToken = JObject.Parse(obj).GetValue("id"); + if (idToken == null) + { + throw new SpeckleException("Failed to get id of serialized object"); + } + + var hash = idToken.ToString(); + + sendTimer.Stop(); + SpeckleLog.Logger + .ForContext("transportElapsedBreakdown", transports.ToDictionary(t => t.TransportName, t => t.Elapsed)) + .ForContext("note", "the elapsed summary doesn't need to add up to the total elapsed... Threading magic...") + .ForContext("serializerElapsed", serializerV2?.Elapsed) + .Information( + "Finished sending {objectCount} objects after {elapsed}, result {objectId}", + transports.Max(t => t.SavedObjectCount), + sendTimer.Elapsed.TotalSeconds, + hash + ); + return hash; + } + } +} diff --git a/Core/Core/Api/Operations/Operations.Send.cs b/Core/Core/Api/Operations/Operations.Send.cs index 2f6fb4b030..882a831c24 100644 --- a/Core/Core/Api/Operations/Operations.Send.cs +++ b/Core/Core/Api/Operations/Operations.Send.cs @@ -1,4 +1,3 @@ -#nullable enable using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -11,81 +10,75 @@ using Speckle.Core.Models; using Speckle.Core.Serialisation; using Speckle.Core.Transports; -using Speckle.Newtonsoft.Json; using Speckle.Newtonsoft.Json.Linq; namespace Speckle.Core.Api; public static partial class Operations { - #region Pushing objects - /// - /// Sends an object via the provided transports. Defaults to the local cache. + /// Sends a Speckle Object to the provided and (optionally) the default local cache /// - /// The object you want to send. - /// Where you want to send them. - /// Toggle for the default cache. If set to false, it will only send to the provided transports. - /// Action that gets triggered on every progress tick (keeps track of all transports). - /// Use this to capture and handle any errors from within the transports. - /// The id (hash) of the object. - public static Task Send( - Base @object, - List? transports = null, - bool useDefaultCache = true, + /// + /// + /// When , an additional will be included + /// The or was + /// + /// using ServerTransport destination = new(account, streamId); + /// string objectId = await Send(mySpeckleObject, destination, true); + /// + public static async Task Send( + Base value, + ITransport transport, + bool useDefaultCache, Action>? onProgressAction = null, - Action? onErrorAction = null, - bool disposeTransports = false, - SerializerVersion serializerVersion = SerializerVersion.V2 + CancellationToken cancellationToken = default ) { - return Send( - @object, - CancellationToken.None, - transports, - useDefaultCache, - onProgressAction, - onErrorAction, - disposeTransports, - serializerVersion - ); + if (transport is null) + { + throw new ArgumentNullException(nameof(transport), "Expected a transport to be explicitly specified"); + } + + List transports = new() { transport }; + using SQLiteTransport? localCache = useDefaultCache ? new SQLiteTransport { TransportName = "LC" } : null; + if (localCache is not null) + { + transports.Add(localCache); + } + + return await Send(value, transports, onProgressAction, cancellationToken).ConfigureAwait(false); } /// - /// Sends an object via the provided transports. Defaults to the local cache. + /// Sends a Speckle Object to the provided /// - /// The object you want to send. - /// A cancellation token that can be used by other objects or threads to send notice of cancellation. - /// Where you want to send them. - /// Toggle for the default cache. If set to false, it will only send to the provided transports. - /// Action that gets triggered on every progress tick (keeps track of all transports). - /// Use this to capture and handle any errors from within the transports. - /// The id (hash) of the object. + /// Only sends to the specified transports, the default local cache won't be used unless you also pass it in + /// The id (hash) of the object sent + /// The object you want to send + /// Where you want to send them + /// Action that gets triggered on every progress tick (keeps track of all transports) + /// + /// No transports were specified + /// The was + /// Serialization or Send operation was unsuccessful + /// One or more failed to send + /// The requested cancellation public static async Task Send( - Base @object, - CancellationToken cancellationToken, - List? transports = null, - bool useDefaultCache = true, + Base value, + IReadOnlyCollection transports, Action>? onProgressAction = null, - Action? onErrorAction = null, - bool disposeTransports = false, - SerializerVersion serializerVersion = SerializerVersion.V2 + CancellationToken cancellationToken = default ) { - transports ??= new List(); - using var sqLiteTransport = new SQLiteTransport { TransportName = "LC" }; - - if (transports.Count == 0 && useDefaultCache == false) + if (value is null) { - throw new ArgumentException( - "You need to provide at least one transport: cannot send with an empty transport list and no default cache.", - nameof(transports) - ); + throw new ArgumentNullException(nameof(value)); } - if (useDefaultCache) + if (transports.Count == 0) { - transports.Insert(0, sqLiteTransport); + throw new ArgumentException("Expected at least on transport to be specified", nameof(transports)); } var transportContext = transports.ToDictionary(t => t.TransportName, t => t.TransportContext); @@ -97,108 +90,49 @@ public static async Task Send( var sendTimer = Stopwatch.StartNew(); SpeckleLog.Logger.Information("Starting send operation"); - BaseObjectSerializer? serializer = null; - JsonSerializerSettings? settings = null; - BaseObjectSerializerV2? serializerV2 = null; - if (serializerVersion == SerializerVersion.V1) - { - (serializer, settings) = GetSerializerInstance(); - } - else - { - serializerV2 = new BaseObjectSerializerV2(); - } - - var localProgressDict = new ConcurrentDictionary(); - var internalProgressAction = GetInternalProgressAction(localProgressDict, onProgressAction); + var internalProgressAction = GetInternalProgressAction(onProgressAction); - if (serializerVersion == SerializerVersion.V1) - { - serializer!.OnProgressAction = internalProgressAction; - serializer.CancellationToken = cancellationToken; - serializer.OnErrorAction = onErrorAction; - } - else - { - serializerV2!.OnProgressAction = internalProgressAction; - serializerV2.CancellationToken = cancellationToken; - serializerV2.OnErrorAction = onErrorAction; - } + BaseObjectSerializerV2 serializerV2 = new(transports, internalProgressAction, cancellationToken); foreach (var t in transports) { t.OnProgressAction = internalProgressAction; t.CancellationToken = cancellationToken; - t.OnErrorAction = onErrorAction; t.BeginWrite(); - - if (serializerVersion == SerializerVersion.V1) - { - serializer!.WriteTransports.Add(t); - } - else - { - serializerV2!.WriteTransports.Add(t); - } } - string obj; - List transportAwaits; - if (serializerVersion == SerializerVersion.V1) - { - obj = JsonConvert.SerializeObject(@object, settings); - transportAwaits = serializer!.WriteTransports.Select(t => t.WriteComplete()).ToList(); - } - else + string hash; + try { - obj = serializerV2!.Serialize(@object); - transportAwaits = serializerV2.WriteTransports.Select(t => t.WriteComplete()).ToList(); + hash = await SerializerSend(value, serializerV2, cancellationToken).ConfigureAwait(false); } - - if (cancellationToken.IsCancellationRequested) + catch (Exception ex) when (!ex.IsFatal()) { SpeckleLog.Logger.Information( - "Send operation cancelled after {elapsed} seconds", + ex, + "Send operation failed after {elapsed} seconds", sendTimer.Elapsed.TotalSeconds ); - cancellationToken.ThrowIfCancellationRequested(); - } - - await Task.WhenAll(transportAwaits).ConfigureAwait(false); - - foreach (var t in transports) - { - t.EndWrite(); - if (useDefaultCache && t is SQLiteTransport lc && lc.TransportName == "LC") - { - lc.Dispose(); - continue; - } - if (disposeTransports && t is IDisposable disp) + if (ex is OperationCanceledException or SpeckleException) { - disp.Dispose(); + throw; } - } - if (cancellationToken.IsCancellationRequested) - { - SpeckleLog.Logger.Information("Send operation cancelled after {elapsed}", sendTimer.Elapsed.TotalSeconds); - cancellationToken.ThrowIfCancellationRequested(); + throw new SpeckleException("Send operation was unsuccessful", ex); } - - var idToken = JObject.Parse(obj).GetValue("id"); - if (idToken == null) + finally { - throw new SpeckleException("Failed to get id of serialized object"); + foreach (var t in transports) + { + t.EndWrite(); + } } - var hash = idToken.ToString(); - sendTimer.Stop(); SpeckleLog.Logger .ForContext("transportElapsedBreakdown", transports.ToDictionary(t => t.TransportName, t => t.Elapsed)) .ForContext("note", "the elapsed summary doesn't need to add up to the total elapsed... Threading magic...") - .ForContext("serializerElapsed", serializerV2?.Elapsed) + .ForContext("serializerElapsed", serializerV2.Elapsed) .Information( "Finished sending {objectCount} objects after {elapsed}, result {objectId}", transports.Max(t => t.SavedObjectCount), @@ -209,5 +143,26 @@ public static async Task Send( } } - #endregion + /// + internal static async Task SerializerSend( + Base value, + BaseObjectSerializerV2 serializer, + CancellationToken cancellationToken = default + ) + { + string obj = serializer.Serialize(value); + Task[] transportAwaits = serializer.WriteTransports.Select(t => t.WriteComplete()).ToArray(); + + cancellationToken.ThrowIfCancellationRequested(); + + await Task.WhenAll(transportAwaits).ConfigureAwait(false); + + JToken? idToken = JObject.Parse(obj).GetValue("id"); + if (idToken == null) + { + throw new SpeckleException("Failed to get id of serialized object"); + } + + return idToken.ToString(); + } } diff --git a/Core/Core/Api/Operations/Operations.Serialize.cs b/Core/Core/Api/Operations/Operations.Serialize.cs index 4dab4c4191..bd3bea972c 100644 --- a/Core/Core/Api/Operations/Operations.Serialize.cs +++ b/Core/Core/Api/Operations/Operations.Serialize.cs @@ -1,45 +1,58 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading; +using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Serialisation; using Speckle.Newtonsoft.Json; namespace Speckle.Core.Api; -// TODO: cleanup a bit public static partial class Operations { /// /// Serializes a given object. + /// /// - /// if you want to save and persist an object to a Speckle Transport or Server, + /// If you want to save and persist an object to Speckle Transport or Server, /// please use any of the "Send" methods. - /// See + /// /// - ///
- /// + /// The object to serialise + /// /// A json string representation of the object. - public static string Serialize(Base @object) + public static string Serialize(Base value, CancellationToken cancellationToken = default) { - return Serialize(@object, CancellationToken.None); + var serializer = new BaseObjectSerializerV2 { CancellationToken = cancellationToken }; + return serializer.Serialize(value); } - /// - /// Serializes a given object. - /// /// - /// If you want to save and persist an object to Speckle Transport or Server, - /// please use any of the "Send" methods. - /// + /// Note: if you want to pull an object from a Speckle Transport or Server, + /// please use + /// /// - /// - /// Propagates notification that operations should be canceled. - /// A json string representation of the object. + /// The json string representation of a speckle object that you want to deserialize + /// + /// + /// was null + /// was not valid JSON + /// cannot be deserialised to type + /// contains closure references (see Remarks) + public static Base Deserialize(string value, CancellationToken cancellationToken = default) + { + var deserializer = new BaseObjectDeserializerV2 { CancellationToken = cancellationToken }; + return deserializer.Deserialize(value); + } + + #region obsolete + + [Obsolete("Serializer v1 is deprecated, use other overload(s)")] public static string Serialize( - Base @object, - CancellationToken cancellationToken, - SerializerVersion serializerVersion = SerializerVersion.V2 + Base value, + SerializerVersion serializerVersion, + CancellationToken cancellationToken = default ) { if (serializerVersion == SerializerVersion.V1) @@ -47,120 +60,92 @@ public static string Serialize( var (serializer, settings) = GetSerializerInstance(); serializer.CancellationToken = cancellationToken; - return JsonConvert.SerializeObject(@object, settings); + return JsonConvert.SerializeObject(value, settings); } else { - var serializer = new BaseObjectSerializerV2(); - serializer.CancellationToken = cancellationToken; - return serializer.Serialize(@object); + return Serialize(value, cancellationToken); } } - /// - /// Serializes a list of objects. Note: if you want to save and persist objects to speckle, please use any of the "Send" methods. - /// - /// - /// - [Obsolete("Please use the Serialize(Base @object) function. This function will be removed in later versions.")] - public static string Serialize(List objects) + [Obsolete("Serializer v1 is deprecated, use other overload(s)")] + public static Base Deserialize( + string value, + SerializerVersion serializerVersion, + CancellationToken cancellationToken = default + ) { - var (_, settings) = GetSerializerInstance(); - return JsonConvert.SerializeObject(objects, settings); + if (serializerVersion == SerializerVersion.V1) + { + var (serializer, settings) = GetSerializerInstance(); + serializer.CancellationToken = cancellationToken; + var ret = JsonConvert.DeserializeObject(value, settings); + return ret ?? throw new SpeckleException($"{nameof(value)} failed to deserialize to a {nameof(Base)} object"); + } + + return Deserialize(value, cancellationToken); } - /// - /// Serializes a list of objects. Note: if you want to save and persist objects to speckle, please use any of the "Send" methods. - /// - /// - /// - [Obsolete("Please use the Serialize(Base @object) function. This function will be removed in later versions.")] - public static string Serialize(Dictionary objects) + [Obsolete("Please use the Deserialize(string value) function.", true)] + public static List DeserializeArray( + string objectArr, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) { - var (_, settings) = GetSerializerInstance(); - return JsonConvert.SerializeObject(objects, settings); + throw new NotImplementedException(); } - /// - /// Deserializes a given object. - /// - /// - /// Note: if you want to pull an object from a Speckle Transport or Server, - /// please use any of the - /// - /// The json string representation of a speckle object that you want to deserialise. - /// - public static Base Deserialize(string @object) + [Obsolete( + "Please use the Deserialize(Base @object) function. This function will be removed in later versions.", + true + )] + public static Dictionary DeserializeDictionary(string dictionary) { - return Deserialize(@object, CancellationToken.None); + throw new NotImplementedException(); } - /// - /// Deserializes a given object. - /// - /// - /// Note: if you want to pull an object from a Speckle Transport or Server, - /// please use any of the - /// . - /// - /// The json string representation of a speckle object that you want to deserialise. - /// Propagates notification that operations should be canceled. - /// + [Obsolete("Use overload that takes cancellation token last")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] public static Base Deserialize( string @object, CancellationToken cancellationToken, SerializerVersion serializerVersion = SerializerVersion.V2 ) { - if (serializerVersion == SerializerVersion.V1) - { - var (serializer, settings) = GetSerializerInstance(); - serializer.CancellationToken = cancellationToken; - return JsonConvert.DeserializeObject(@object, settings); - } + return Deserialize(@object, serializerVersion, cancellationToken); + } - var deserializer = new BaseObjectDeserializerV2(); - deserializer.CancellationToken = cancellationToken; - return deserializer.Deserialize(@object); + [Obsolete("Use overload that takes cancellation token last")] + [SuppressMessage("Naming", "CA1720:Identifier contains type name")] + public static string Serialize( + Base @object, + CancellationToken cancellationToken, + SerializerVersion serializerVersion = SerializerVersion.V2 + ) + { + return Serialize(@object, serializerVersion, cancellationToken); } /// - /// Deserializes a list of objects into an array. Note: if you want to pull an object from speckle (either local or remote), please use any of the "Receive" methods. + /// Serializes a list of objects. Note: if you want to save and persist objects to speckle, please use any of the "Send" methods. /// - /// + /// /// - [Obsolete("Please use the Deserialize(Base @object) function. This function will be removed in later versions.")] - public static List DeserializeArray( - string objectArr, - SerializerVersion serializerVersion = SerializerVersion.V2 - ) + [Obsolete("Please use the Serialize(Base value) function. This function will be removed in later versions.", true)] + public static string Serialize(List objects) { - if (serializerVersion == SerializerVersion.V1) - { - var (_, settings) = GetSerializerInstance(); - return JsonConvert.DeserializeObject>(objectArr, settings); - } - - var deserializer = new BaseObjectDeserializerV2(); - List deserialized = deserializer.DeserializeTransportObject(objectArr) as List; - List ret = new(); - foreach (object obj in deserialized) - { - ret.Add((Base)obj); - } - - return ret; + throw new NotImplementedException(); } /// - /// Deserializes a dictionary object. Note: if you want to pull an object from speckle (either local or remote), please use any of the "Receive" methods. + /// Serializes a list of objects. Note: if you want to save and persist objects to speckle, please use any of the "Send" methods. /// - /// + /// /// - [Obsolete("Please use the Deserialize(Base @object) function. This function will be removed in later versions.")] - public static Dictionary DeserializeDictionary(string dictionary) + [Obsolete("Please use the Serialize(Base value) function. This function will be removed in later versions.")] + public static string Serialize(Dictionary objects) { - var (_, settings) = GetSerializerInstance(); - return JsonConvert.DeserializeObject>(dictionary, settings); + throw new NotImplementedException(); } + #endregion } diff --git a/Core/Core/Api/Operations/Operations.cs b/Core/Core/Api/Operations/Operations.cs index 701eb257fa..83e153b662 100644 --- a/Core/Core/Api/Operations/Operations.cs +++ b/Core/Core/Api/Operations/Operations.cs @@ -10,13 +10,14 @@ namespace Speckle.Core.Api; /// /// Exposes several key methods for interacting with Speckle.Core. /// Serialize/Deserialize -/// Push/Pull (methods to serialize & send data to one or more servers) +/// Push/Pull (methods to serialize and send data to one or more servers) /// public static partial class Operations { /// /// Convenience method to instantiate an instance of the default object serializer and settings pre-populated with it. /// + [Obsolete("V1 Serializer is deprecated. Use " + nameof(BaseObjectSerializerV2))] public static (BaseObjectSerializer, JsonSerializerSettings) GetSerializerInstance() { var serializer = new BaseObjectSerializer(); @@ -33,28 +34,29 @@ public static (BaseObjectSerializer, JsonSerializerSettings) GetSerializerInstan } /// - /// Factory for progress actions used internally inside send & receive methods. + /// Factory for progress actions used internally inside send and receive methods. /// - /// /// /// - private static Action GetInternalProgressAction( - ConcurrentDictionary localProgressDict, - Action> onProgressAction = null + private static Action? GetInternalProgressAction( + Action>? onProgressAction ) { + if (onProgressAction is null) + { + return null; + } + + var localProgressDict = new ConcurrentDictionary(); + return (name, processed) => { - if (localProgressDict.ContainsKey(name)) + if (!localProgressDict.TryAdd(name, processed)) { localProgressDict[name] += processed; } - else - { - localProgressDict[name] = processed; - } - onProgressAction?.Invoke(localProgressDict); + onProgressAction.Invoke(localProgressDict); }; } } diff --git a/Core/Core/Core.csproj b/Core/Core/Core.csproj index 2060364fdd..2b74ff5528 100644 --- a/Core/Core/Core.csproj +++ b/Core/Core/Core.csproj @@ -12,11 +12,27 @@ $(PackageTags) core true true + enable + + true + + $(WarningsNotAsErrors); + CA1000; CA1001; CA1003; CA1024; CA1033; CA1034; CA1051; CA1055; CA1063; CA1065; + CA1502; CA1506; + CA1708; CA1710; CA1711; CA1716; CA1720; CA1721; CA1724; + CA1816; CA1851; CA1861; + CA2201; + CS0419; CS0618; CS0659; CS0809; + CS8600; CS8602; CS8603; CS8604; + IDE0032; IDE0059; IDE0130; IDE1006; + + + - - + + true @@ -25,16 +26,14 @@ latest-AllEnabledByDefault none true - - + true - - CA5399; + + CA5399;CA1862; - CS1591;CS1573;CS1572;CS1570;CS1587;CS1574; - CS1711;CS1734; + CS1591;CS1573; CS8618; @@ -65,23 +64,45 @@ CA5376; CA5377; CA5378; CA5379; CA5380; CA5381; CA5382; CA5383; CA5384; CA5385; CA5386; CA5387; CA5388; CA5389; CA5390; CA5391; CA5392; CA5393; CA5395; CA5396; CA5397; CA5398; - CA5400; CA5401; CA5402; CA5403; CA5404; CA5405 + CA5400; CA5401; CA5402; CA5403; CA5404; CA5405; + + + + CS0183; CS0184; CS0197; CS0420; CS0465; CS0602; CS0626; CS0657; CS0658; CS0672; CS0684; CS0688; + CS1030; CS1058; CS1060; CS1200; CS1201; CS1202; CS1203; + CS1522; CS1589; CS1590; CS1592; CS1598; + CS1607; CS1616; CS1633; CS1634; CS1635; CS1645; CS1658; CS1682; CS1683; CS1684; CS1685; CS1687; CS1690; CS1691; CS1692; CS1694; CS1695; CS1696; CS1697; CS1699; + CS1707; CS1709; CS1720; CS1723; CS1762; + CS1911; CS1956; CS1957; + CS2002; CS2014; CS2023; CS2029; + CS3000; CS3001; CS3002; CS3003; CS3004; CS3005; CS3006; CS3008; CS3009; CS3010; CS3011; CS3012; CS3013; CS3014; CS3015; CS3017; CS3018; CS3022; CS3023; CS3024; CS3026; CS3027; + CS5000; + + + + + + + + + + - false $(WarningsAsErrors); - IDE0011;IDE0090;IDE0161; + IDE0011;IDE0090;IDE0161;IDE0005; + CA1806;CA1806;CA1806;CA1031; diff --git a/Directory.Build.targets b/Directory.Build.targets index 3a20134bf9..bfe533e029 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -19,7 +19,7 @@ Objects - + + + Recommended + + $(NoWarn); + + CS0618;CA1034;CA2201;CA1051;CA1040;CA1724; + IDE0044;IDE0130;CA1508; + + CA5394;CA2007;CA1852;CA1819;CA1711;CA1063;CA1816;CA2234; + + false + + + + + + diff --git a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/Converter.AutocadCivil.Utils.cs b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/Converter.AutocadCivil.Utils.cs index b02fee4864..abe25556eb 100644 --- a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/Converter.AutocadCivil.Utils.cs +++ b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/Converter.AutocadCivil.Utils.cs @@ -1,17 +1,15 @@ using System; -using System.Linq; using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; -using Objects.Other; using Speckle.Core.Kits; using Speckle.Core.Models; -using Autodesk.AutoCAD.Colors; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.EditorInput; +using Speckle.Core.Logging; #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 using Autodesk.Aec.ApplicationServices; @@ -51,19 +49,15 @@ public static Base GetObjectExtensionDictionaryAsBase(this DBObject source) var extensionDictionary = tr.GetObject(source.ExtensionDictionary, OpenMode.ForRead, false) as DBDictionary; foreach (var entry in extensionDictionary) { - var xRecord = tr.GetObject(entry.Value, OpenMode.ForRead) as Xrecord; // sometimes these can be RXClass objects, in property sets - if (xRecord != null) + if (tr.GetObject(entry.Value, OpenMode.ForRead) is Xrecord xRecord) // sometimes these can be RXClass objects, in property sets { var entryBase = new Base(); foreach (var xEntry in xRecord.Data) { entryBase[xEntry.TypeCode.ToString()] = xEntry.Value; } - try - { - extensionDictionaryBase[$"{entry.Key}"] = entryBase; - } - catch (Exception e) { } + + extensionDictionaryBase[$"{entry.Key}"] = entryBase; } } @@ -73,7 +67,7 @@ public static Base GetObjectExtensionDictionaryAsBase(this DBObject source) public partial class ConverterAutocadCivil { - public static string invalidAutocadChars = @"<>/\:;""?*|=,‘"; + private const string INVALID_CHARS = @"<>/\:;""?*|=,‘"; private Dictionary _lineTypeDictionary = new(); public Dictionary LineTypeDictionary @@ -98,14 +92,27 @@ public Dictionary LineTypeDictionary /// /// /// - public static string RemoveInvalidAutocadChars(string str) + public static string RemoveInvalidChars(string str) { // using this to handle rhino nested layer syntax // replace "::" layer delimiter with "$" (acad standard) string cleanDelimiter = str.Replace("::", "$"); // remove all other invalid chars - return Regex.Replace(cleanDelimiter, $"[{invalidAutocadChars}]", string.Empty); + return Regex.Replace(cleanDelimiter, $"[{INVALID_CHARS}]", string.Empty); + } + + public static void AddNameAndDescriptionProperty(string name, string description, Base @base) + { + if (!string.IsNullOrEmpty(name)) + { + @base["name"] = name; + } + + if (!string.IsNullOrEmpty(description)) + { + @base["description"] = description; + } } /// @@ -116,14 +123,23 @@ public static string RemoveInvalidAutocadChars(string str) public static bool GetHandle(string str, out Handle handle) { handle = new Handle(); + if (string.IsNullOrEmpty(str)) + { + return false; + } + + long l; try { - handle = new Handle(Convert.ToInt64(str, 16)); + l = Convert.ToInt64(str, 16); } - catch + catch (Exception ex) when (ex is ArgumentException or FormatException or OverflowException) { return false; } + + handle = new Handle(l); + return true; } @@ -137,7 +153,7 @@ public List GetExistingElementsByApplicationId(string applicationId) { var ids = new List(); - if (applicationId == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) + if (applicationId == null || ReceiveMode == ReceiveMode.Create) { return ids; } @@ -192,7 +208,7 @@ public List GetExistingElementsByApplicationId(string applicationId) public ObjectId GetFromObjectIdCollection(string name, ObjectIdCollection collection, bool useFirstIfNull = false) { var id = ObjectId.Null; - if ((string.IsNullOrEmpty(name) && !useFirstIfNull) || (string.IsNullOrEmpty(name) && collection.Count == 0)) + if (string.IsNullOrEmpty(name) && !useFirstIfNull || string.IsNullOrEmpty(name) && collection.Count == 0) { return id; } @@ -223,6 +239,46 @@ public ObjectId GetFromObjectIdCollection(string name, ObjectIdCollection collec return id; } + public LayerTableRecord GetLayer(string path, OpenMode mode = OpenMode.ForRead) + { + if (!string.IsNullOrEmpty(path)) + { + var layerTable = (LayerTable)Trans.GetObject(Doc.Database.LayerTableId, OpenMode.ForRead); + if (layerTable.Has(path)) + { + return (LayerTableRecord)Trans.GetObject(layerTable[path], mode); + } + } + + return null; + } + + public bool MakeLayer(string name, out LayerTableRecord layer) + { + layer = null; + + if (!string.IsNullOrEmpty(name)) + { + var layerTable = (LayerTable)Trans.GetObject(Doc.Database.LayerTableId, OpenMode.ForWrite); + + LayerTableRecord newLayer = new() { Name = name }; + try + { + layerTable.Add(newLayer); + Trans.AddNewlyCreatedDBObject(newLayer, true); + layer = newLayer; + return true; + } + catch (Exception e) when (!e.IsFatal()) + { + // Couldn't create a layer, but can use default layer instead. + SpeckleLog.Logger.Error(e, $"Could not add new layer {name} to the layer table"); + } + } + + return false; + } + #region Reference Point // CAUTION: these strings need to have the same values as in the connector bindings @@ -236,9 +292,7 @@ private Matrix3d ReferencePointTransform if (_transform == null || _transform == new Matrix3d()) { // get from settings - var referencePointSetting = Settings.ContainsKey("reference-point") - ? Settings["reference-point"] - : string.Empty; + var referencePointSetting = Settings.TryGetValue("reference-point", out string value) ? value : string.Empty; _transform = GetReferencePointTransform(referencePointSetting); } return _transform; @@ -411,7 +465,7 @@ private string UnitToSpeckle(UnitsValue units) case UnitsValue.Undefined: return Units.None; default: - throw new Speckle.Core.Logging.SpeckleException($"The Unit System \"{units}\" is unsupported."); + throw new SpeckleException($"The Unit System \"{units}\" is unsupported."); } } diff --git a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Civil.cs b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Civil.cs index 2b40be01a2..b81e00b677 100644 --- a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Civil.cs +++ b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Civil.cs @@ -7,6 +7,7 @@ using Autodesk.AutoCAD.DatabaseServices; using Autodesk.Civil.ApplicationServices; +using Autodesk.Civil.DatabaseServices; using CivilDB = Autodesk.Civil.DatabaseServices; using Civil = Autodesk.Civil; using Autodesk.AutoCAD.Geometry; @@ -16,22 +17,19 @@ using Objects.BuiltElements.Civil; using Alignment = Objects.BuiltElements.Alignment; using Arc = Objects.Geometry.Arc; -using Interval = Objects.Primitive.Interval; using Polycurve = Objects.Geometry.Polycurve; -using Curve = Objects.Geometry.Curve; using Featureline = Objects.BuiltElements.Featureline; using Line = Objects.Geometry.Line; using Point = Objects.Geometry.Point; -using Brep = Objects.Geometry.Brep; using Mesh = Objects.Geometry.Mesh; using Pipe = Objects.BuiltElements.Pipe; -using Plane = Objects.Geometry.Plane; using Polyline = Objects.Geometry.Polyline; using Profile = Objects.BuiltElements.Profile; using Spiral = Objects.Geometry.Spiral; using SpiralType = Objects.Geometry.SpiralType; using Station = Objects.BuiltElements.Station; using Structure = Objects.BuiltElements.Structure; +using Speckle.Core.Logging; namespace Objects.Converter.AutocadCivil; @@ -39,79 +37,33 @@ public partial class ConverterAutocadCivil { private bool GetCivilDocument(ApplicationObject appObj, out CivilDocument doc) { - BlockTableRecord modelSpaceRecord = Doc.Database.GetModelSpace(); doc = CivilApplication.ActiveDocument; if (doc is null) { appObj.Update(status: ApplicationObject.State.Failed, logItem: $"Could not retrieve civil3d document"); } - return doc is null ? false : true; + return doc is not null; } // stations public Station StationToSpeckle(CivilDB.Station station) { - var _station = new Station(); - _station.location = PointToSpeckle(station.Location); - _station.type = station.StationType.ToString(); - _station.number = station.RawStation; - _station.units = ModelUnits; + var speckleStation = new Station + { + location = PointToSpeckle(station.Location), + type = station.StationType.ToString(), + number = station.RawStation, + units = ModelUnits + }; - return _station; + return speckleStation; } // alignments public CivilAlignment AlignmentToSpeckle(CivilDB.Alignment alignment) { - var _alignment = new CivilAlignment(); - - // get alignment props - _alignment.type = alignment.AlignmentType.ToString(); - _alignment.offset = alignment.IsOffsetAlignment ? alignment.OffsetAlignmentInfo.NominalOffset : 0; - if (alignment.SiteName != null) - { - _alignment.site = alignment.SiteName; - } - - if (alignment.StyleName != null) - { - _alignment.style = alignment.StyleName; - } - - if (alignment.Description != null) - { - _alignment["description"] = alignment.Description; - } - - if (alignment.Name != null) - { - _alignment.name = alignment.Name; - } - - // get alignment stations - _alignment.startStation = alignment.StartingStation; - _alignment.endStation = alignment.EndingStation; - var stations = alignment.GetStationSet(CivilDB.StationTypes.All).ToList(); - List _stations = stations.Select(o => StationToSpeckle(o)).ToList(); - if (_stations.Count > 0) - { - _alignment["@stations"] = _stations; - } - - // handle station equations - var equations = new List(); - var directions = new List(); - foreach (var stationEquation in alignment.StationEquations) - { - equations.AddRange(new List { stationEquation.RawStationBack, stationEquation.StationBack, stationEquation.StationAhead }); - bool equationIncreasing = (stationEquation.EquationType.Equals(CivilDB.StationEquationType.Increasing)) ? true : false; - directions.Add(equationIncreasing); - } - _alignment.stationEquations = equations; - _alignment.stationEquationDirections = directions; - - // get alignment profiles + // get the profiles var profiles = new List(); foreach (ObjectId profileId in alignment.GetProfileIds()) { @@ -122,7 +74,16 @@ public CivilAlignment AlignmentToSpeckle(CivilDB.Alignment alignment) profiles.Add(convertedProfile); } } - _alignment.profiles = profiles; + + // get the station equations + var equations = new List(); + var directions = new List(); + foreach (StationEquation stationEquation in alignment.StationEquations) + { + equations.AddRange(new List { stationEquation.RawStationBack, stationEquation.StationBack, stationEquation.StationAhead }); + bool equationIncreasing = stationEquation.EquationType.Equals(StationEquationType.Increasing); + directions.Add(equationIncreasing); + } // get the alignment subentity curves List curves = new(); @@ -135,22 +96,24 @@ public CivilAlignment AlignmentToSpeckle(CivilDB.Alignment alignment) double length = 0; for (int j = 0; j < entity.SubEntityCount; j++) { - CivilDB.AlignmentSubEntity subEntity = entity[j]; + AlignmentSubEntity subEntity = entity[j]; ICurve segment = null; switch (subEntity.SubEntityType) { - case CivilDB.AlignmentSubEntityType.Arc: - var arc = subEntity as CivilDB.AlignmentSubEntityArc; + case AlignmentSubEntityType.Arc: + var arc = subEntity as AlignmentSubEntityArc; segment = AlignmentArcToSpeckle(arc); break; - case CivilDB.AlignmentSubEntityType.Line: - var line = subEntity as CivilDB.AlignmentSubEntityLine; + case AlignmentSubEntityType.Line: + var line = subEntity as AlignmentSubEntityLine; segment = AlignmentLineToSpeckle(line); break; - case CivilDB.AlignmentSubEntityType.Spiral: - var spiral = subEntity as CivilDB.AlignmentSubEntitySpiral; + case AlignmentSubEntityType.Spiral: + var spiral = subEntity as AlignmentSubEntitySpiral; segment = AlignmentSpiralToSpeckle(spiral, alignment); break; + default: + break; } if (segment != null) { @@ -172,26 +135,76 @@ public CivilAlignment AlignmentToSpeckle(CivilDB.Alignment alignment) curves.Add(polycurve); } } - _alignment.curves = curves; + CivilAlignment speckleAlignment = new() + { + type = alignment.AlignmentType.ToString(), + profiles = profiles, + curves = curves, + startStation = alignment.StartingStation, + endStation = alignment.EndingStation, + stationEquations = equations, + stationEquationDirections = directions, + offset = alignment.IsOffsetAlignment ? alignment.OffsetAlignmentInfo.NominalOffset : 0, + site = alignment.SiteName ?? "", + style = alignment.StyleName ?? "" + }; + + AddNameAndDescriptionProperty(alignment.Name, alignment.Description, speckleAlignment); + + // get design speeds + var designSpeeds = DesignSpeedsToSpeckle(alignment.DesignSpeeds); + if (designSpeeds.Count > 0) + { + speckleAlignment["@designSpeeds"] = designSpeeds; + } + + // get alignment stations and design speeds + List stations = new(); + foreach (CivilDB.Station station in alignment.GetStationSet(StationTypes.All)) + { + stations.Add(StationToSpeckle(station)); + } + if (stations.Count > 0) + { + speckleAlignment["@stations"] = stations; + } // if offset alignment, also set parent and offset side if (alignment.IsOffsetAlignment) { - _alignment["offsetSide"] = alignment.OffsetAlignmentInfo.Side.ToString(); - try + OffsetAlignmentInfo offsetInfo = alignment.OffsetAlignmentInfo; + speckleAlignment["offsetSide"] = offsetInfo.Side.ToString(); + if (Trans.GetObject(offsetInfo.ParentAlignmentId, OpenMode.ForRead) is CivilDB.Alignment parent && parent.Name != null) { - var parent = Trans.GetObject(alignment.OffsetAlignmentInfo.ParentAlignmentId, OpenMode.ForRead) as CivilDB.Alignment; - if (parent != null && parent.Name != null) - { - _alignment.parent = parent.Name; - } + speckleAlignment.parent = parent.Name; + } + } + + return speckleAlignment; + } + + private List DesignSpeedsToSpeckle(DesignSpeedCollection designSpeeds) + { + List speckleDesignSpeeds = new(); + + foreach (DesignSpeed designSpeed in designSpeeds) + { + Base speckleDesignSpeed = new(); + speckleDesignSpeed["number"] = designSpeed.SpeedNumber; + speckleDesignSpeed["station"] = designSpeed.Station; + speckleDesignSpeed["value"] = designSpeed.Value; + if (!string.IsNullOrEmpty(designSpeed.Comment)) + { + speckleDesignSpeed["comment"] = designSpeed.Comment; } - catch { } + + speckleDesignSpeeds.Add(speckleDesignSpeed); } - return _alignment; + return speckleDesignSpeeds; } + public ApplicationObject AlignmentToNative(Alignment alignment) { var appObj = new ApplicationObject(alignment.id, alignment.speckle_type) { applicationId = alignment.applicationId }; @@ -205,10 +218,10 @@ public ApplicationObject AlignmentToNative(Alignment alignment) } // create or retrieve alignment, and parent if it exists - CivilDB.Alignment _alignment = existingObjs.Any() ? Trans.GetObject(existingObjs.FirstOrDefault(), OpenMode.ForWrite) as CivilDB.Alignment : null; + CivilDB.Alignment existingAlignment = existingObjs.Any() ? Trans.GetObject(existingObjs.FirstOrDefault(), OpenMode.ForWrite) as CivilDB.Alignment : null; var parent = civilAlignment != null ? GetFromObjectIdCollection(civilAlignment.parent, civilDoc.GetAlignmentIds()) : ObjectId.Null; bool isUpdate = true; - if (_alignment == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) // just create a new alignment + if (existingAlignment == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) // just create a new alignment { isUpdate = false; @@ -218,7 +231,7 @@ public ApplicationObject AlignmentToNative(Alignment alignment) var layer = Doc.Database.LayerZero; // type - var type = CivilDB.AlignmentType.Centerline; + var type = AlignmentType.Centerline; if (civilAlignment != null) { if (Enum.TryParse(civilAlignment.type, out CivilDB.AlignmentType civilType)) @@ -252,55 +265,48 @@ public ApplicationObject AlignmentToNative(Alignment alignment) GetFromObjectIdCollection(civilAlignment["label"] as string, labelStyles, true) : civilDoc.Styles.LabelSetStyles.AlignmentLabelSetStyles.First(); #endregion - try + // create the alignment + var id = ObjectId.Null; + switch (type) { - // add new alignment to doc - // ⚠ this will throw if name is not unique!! - var id = ObjectId.Null; - switch (type) - { - case CivilDB.AlignmentType.Offset: - // create only if parent exists in doc - if (parent == ObjectId.Null) - { - goto default; - } + case AlignmentType.Offset: + // create only if parent exists in doc + if (parent == ObjectId.Null || civilAlignment.offset == 0) + { + id = CreateDefaultAlignment(civilDoc, name, site, layer, style, label); + } + try + { + id = CivilDB.Alignment.CreateOffsetAlignment(name, parent, civilAlignment.offset, style); + } + catch (ArgumentException) // throws when name is invalid or offset is too large + { + // try to recreate with a unique name try - { - id = CivilDB.Alignment.CreateOffsetAlignment(name, parent, civilAlignment.offset, style); - } - catch { id = CivilDB.Alignment.CreateOffsetAlignment(CivilDB.Alignment.GetNextUniqueName(name), parent, civilAlignment.offset, style); } - break; - default: - try - { - id = CivilDB.Alignment.Create(civilDoc, name, site, layer, style, label); - } - catch + catch (ArgumentException) { - id = CivilDB.Alignment.Create(civilDoc, CivilDB.Alignment.GetNextUniqueName(name), site, layer, style, label); + id = CreateDefaultAlignment(civilDoc, name, site, layer, style, label); } - break; - } - if (!id.IsValid) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"Create method returned null"); - return appObj; - } - _alignment = Trans.GetObject(id, OpenMode.ForWrite) as CivilDB.Alignment; + } + break; + default: + id =CreateDefaultAlignment(civilDoc, name, site, layer, style, label); + break; } - catch (System.Exception e) + + if (!id.IsValid) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"{e.Message}"); + appObj.Update(status: ApplicationObject.State.Failed, logItem: $"Create method returned null"); return appObj; } + existingAlignment = Trans.GetObject(id, OpenMode.ForWrite) as CivilDB.Alignment; } - if (_alignment == null) + if (existingAlignment == null) { appObj.Update(status: ApplicationObject.State.Failed, logItem: $"returned null after bake"); return appObj; @@ -308,20 +314,20 @@ public ApplicationObject AlignmentToNative(Alignment alignment) if (isUpdate) { - appObj.Container = _alignment.Layer; // set the appobj container to be the same layer as the existing alignment + appObj.Container = existingAlignment.Layer; // set the appobj container to be the same layer as the existing alignment } if (parent != ObjectId.Null) { - _alignment.OffsetAlignmentInfo.NominalOffset = civilAlignment.offset; // just update the offset + existingAlignment.OffsetAlignmentInfo.NominalOffset = civilAlignment.offset; // just update the offset } else { // create alignment entity curves - var entities = _alignment.Entities; + var entities = existingAlignment.Entities; if (isUpdate) { - _alignment.Entities.Clear(); // remove existing curves + existingAlignment.Entities.Clear(); // remove existing curves } foreach (var curve in alignment.curves) @@ -331,50 +337,64 @@ public ApplicationObject AlignmentToNative(Alignment alignment) } // set start station - _alignment.ReferencePointStation = alignment.startStation; + existingAlignment.ReferencePointStation = alignment.startStation; + + // set design speeds if any + if (civilAlignment["@designSpeeds"] is List speeds) + { + foreach (object speed in speeds) + { + if (speed is Base speedBase && speedBase["station"] is double station && speedBase["value"] is double value) + { + existingAlignment.DesignSpeeds.Add(station, value); + } + } + } // update appobj var status = isUpdate ? ApplicationObject.State.Updated : ApplicationObject.State.Created; - appObj.Update(status: status, createdId: _alignment.Handle.ToString(), convertedItem: _alignment); + appObj.Update(status: status, createdId: existingAlignment.Handle.ToString(), convertedItem: existingAlignment); return appObj; } #region helper methods - private SpiralType SpiralTypeToSpeckle(Civil.SpiralType type) + private ObjectId CreateDefaultAlignment(CivilDocument civilDoc, string name, ObjectId site, ObjectId layer, ObjectId style, ObjectId label) { - switch (type) - { - case Civil.SpiralType.Clothoid: - return SpiralType.Clothoid; - case Civil.SpiralType.Bloss: - return SpiralType.Bloss; - case Civil.SpiralType.BiQuadratic: - return SpiralType.Biquadratic; - case Civil.SpiralType.CubicParabola: - return SpiralType.CubicParabola; - case Civil.SpiralType.Sinusoidal: - return SpiralType.Sinusoid; - default: - return SpiralType.Unknown; + ObjectId id = ObjectId.Null; + try // throws when name already exsits or objectIds are invalid + { + id = CivilDB.Alignment.Create(civilDoc, name, site, layer, style, label); + } + catch (ArgumentException) + { + id = CivilDB.Alignment.Create(civilDoc, CivilDB.Alignment.GetNextUniqueName(name), site, layer, style, label); } + return id; + } + + private SpiralType SpiralTypeToSpeckle(Civil.SpiralType type) + { + return type switch + { + Civil.SpiralType.Clothoid => SpiralType.Clothoid, + Civil.SpiralType.Bloss => SpiralType.Bloss, + Civil.SpiralType.BiQuadratic => SpiralType.Biquadratic, + Civil.SpiralType.CubicParabola => SpiralType.CubicParabola, + Civil.SpiralType.Sinusoidal => SpiralType.Sinusoid, + _ => SpiralType.Unknown, + }; } private Civil.SpiralType SpiralTypeToNative(SpiralType type) { - switch (type) - { - case SpiralType.Clothoid: - return Civil.SpiralType.Clothoid; - case SpiralType.Bloss: - return Civil.SpiralType.Bloss; - case SpiralType.Biquadratic: - return Civil.SpiralType.BiQuadratic; - case SpiralType.CubicParabola: - return Civil.SpiralType.CubicParabola; - case SpiralType.Sinusoid: - return Civil.SpiralType.Sinusoidal; - default: - return Civil.SpiralType.Clothoid; - } + return type switch + { + SpiralType.Clothoid => Civil.SpiralType.Clothoid, + SpiralType.Bloss => Civil.SpiralType.Bloss, + SpiralType.Biquadratic => Civil.SpiralType.BiQuadratic, + SpiralType.CubicParabola => Civil.SpiralType.CubicParabola, + SpiralType.Sinusoid => Civil.SpiralType.Sinusoidal, + _ => Civil.SpiralType.Clothoid, + }; } private void AddAlignmentEntity(ICurve curve, ref CivilDB.AlignmentEntityCollection entities) { @@ -415,10 +435,10 @@ private void AddAlignmentEntity(ICurve curve, ref CivilDB.AlignmentEntityCollect } private Line AlignmentLineToSpeckle(CivilDB.AlignmentSubEntityLine line) { - var _line = LineToSpeckle(new LineSegment2d(line.StartPoint, line.EndPoint)); - return _line; + var speckleLine = LineToSpeckle(new LineSegment2d(line.StartPoint, line.EndPoint)); + return speckleLine; } - private Arc AlignmentArcToSpeckle(CivilDB.AlignmentSubEntityArc arc) + private Arc AlignmentArcToSpeckle(AlignmentSubEntityArc arc) { // calculate midpoint of chord as between start and end point Point2d chordMid = new((arc.StartPoint.X + arc.EndPoint.X) / 2, (arc.StartPoint.Y + arc.EndPoint.Y) / 2); @@ -436,67 +456,77 @@ private Arc AlignmentArcToSpeckle(CivilDB.AlignmentSubEntityArc arc) Point2d midPoint = chordMid.Add(unitMidVector.MultiplyBy(sagitta)); try { - if (arc.GreaterThan180) // sometimes this prop throws an exception?? + if (arc.GreaterThan180) // this can throw : The property gets an invalid value according to the entity's constraint type. { midPoint = chordMid.Add(unitMidVector.Negate().MultiplyBy(2 * arc.Radius - sagitta)); } } - catch { } + catch (InvalidOperationException){ } // continue with original midpoint if GreaterThan180 doesn't apply to this arc // create arc - var _arc = new CircularArc2d(arc.StartPoint, midPoint, arc.EndPoint); - return ArcToSpeckle(_arc); + var speckleArc = ArcToSpeckle(new CircularArc2d(arc.StartPoint, midPoint, arc.EndPoint)); + return speckleArc; } - private Spiral AlignmentSpiralToSpeckle(CivilDB.AlignmentSubEntitySpiral spiral, CivilDB.Alignment alignment) + private Spiral AlignmentSpiralToSpeckle(AlignmentSubEntitySpiral spiral, CivilDB.Alignment alignment) { - var _spiral = new Spiral(); - _spiral.startPoint = PointToSpeckle(spiral.StartPoint); - _spiral.endPoint = PointToSpeckle(spiral.EndPoint); - _spiral.length = spiral.Length; - _spiral.pitch = 0; - _spiral.spiralType = SpiralTypeToSpeckle(spiral.SpiralDefinition); - // get plane - var vX = new Vector3d(System.Math.Cos(spiral.StartDirection) + spiral.StartPoint.X, System.Math.Sin(spiral.StartDirection) + spiral.StartPoint.Y, 0); - var vY = vX.RotateBy(System.Math.PI / 2, Vector3d.ZAxis); + var vX = new Vector3d(Math.Cos(spiral.StartDirection) + spiral.StartPoint.X, Math.Sin(spiral.StartDirection) + spiral.StartPoint.Y, 0); + var vY = vX.RotateBy(Math.PI / 2, Vector3d.ZAxis); var plane = new Acad.Plane(new Point3d(spiral.RadialPoint.X, spiral.RadialPoint.Y, 0), vX, vY); - _spiral.plane = PlaneToSpeckle(plane); // get turns - int turnDirection = (spiral.Direction == CivilDB.SpiralDirectionType.DirectionLeft) ? 1 : -1; - _spiral.turns = turnDirection * spiral.Delta / (System.Math.PI * 2); + int turnDirection = (spiral.Direction == SpiralDirectionType.DirectionLeft) ? 1 : -1; + double turns = turnDirection * spiral.Delta / (Math.PI * 2); + + // create speckle spiral + Spiral speckleSpiral = new() + { + startPoint = PointToSpeckle(spiral.StartPoint), + endPoint = PointToSpeckle(spiral.EndPoint), + length = spiral.Length, + pitch = 0, + spiralType = SpiralTypeToSpeckle(spiral.SpiralDefinition), + plane = PlaneToSpeckle(plane), + turns = turns + }; // create polyline display, default tessellation length is 1 var tessellation = 1; - int spiralSegmentCount = System.Convert.ToInt32(System.Math.Ceiling(spiral.Length / tessellation)); + int spiralSegmentCount = Convert.ToInt32(Math.Ceiling(spiral.Length / tessellation)); spiralSegmentCount = (spiralSegmentCount < 10) ? 10 : spiralSegmentCount; double spiralSegmentLength = spiral.Length / spiralSegmentCount; - - List points = new(); - points.Add(spiral.StartPoint); + + List points = new() + { + spiral.StartPoint + }; for (int i = 1; i < spiralSegmentCount; i++) { double x = 0; double y = 0; double z = 0; - alignment.PointLocation(spiral.StartStation + (i * spiralSegmentLength), 0, tolerance, ref x, ref y, ref z); + alignment.PointLocation(spiral.StartStation + i * spiralSegmentLength, 0, tolerance, ref x, ref y, ref z); points.Add(new Point2d(x, y)); } + points.Add(spiral.EndPoint); double length = 0; for (int j = 1; j < points.Count; j++) { length += points[j].GetDistanceTo(points[j - 1]); } - var poly = new Polyline(); - poly.value = points.SelectMany(o => PointToSpeckle(o).ToList()).ToList(); - poly.units = ModelUnits; - poly.closed = (spiral.StartPoint != spiral.EndPoint) ? false : true; - poly.length = length; - _spiral.displayValue = poly; - - return _spiral; + + Polyline poly = new() + { + value = points.SelectMany(o => PointToSpeckle(o).ToList()).ToList(), + units = ModelUnits, + closed = spiral.StartPoint == spiral.EndPoint, + length = length + }; + speckleSpiral.displayValue = poly; + + return speckleSpiral; } #endregion @@ -505,38 +535,25 @@ private Spiral AlignmentSpiralToSpeckle(CivilDB.AlignmentSubEntitySpiral spiral, public CivilProfile ProfileToSpeckle(CivilDB.Profile profile) { // TODO: get surface name of surface profiles from profile view - var _profile = new CivilProfile(); - - // get profile props - _profile.type = profile.ProfileType.ToString(); - _profile.offset = profile.Offset; - if (profile.StyleName != null) + CivilProfile speckleProfile = new() { - _profile.style = profile.StyleName; - } + type = profile.ProfileType.ToString(), + offset = profile.Offset, + style = profile.StyleName ?? "", + startStation = profile.StartingStation, + endStation = profile.EndingStation + }; - if (profile.Description != null) - { - _profile["description"] = profile.Description; - } - - if (profile.Name != null) - { - _profile.name = profile.Name; - } - - // get profile stations - _profile.startStation = profile.StartingStation; - _profile.endStation = profile.EndingStation; + AddNameAndDescriptionProperty(profile.Name, profile.Description, speckleProfile); // get the profile entity curves List curves = new(); for (int i = 0; i < profile.Entities.Count; i++) { - CivilDB.ProfileEntity entity = profile.Entities[i]; + ProfileEntity entity = profile.Entities[i]; switch (entity.EntityType) { - case CivilDB.ProfileEntityType.Circular: + case ProfileEntityType.Circular: var circular = ProfileArcToSpeckle(entity as CivilDB.ProfileCircular); if (circular != null) { @@ -544,7 +561,7 @@ public CivilProfile ProfileToSpeckle(CivilDB.Profile profile) } break; - case CivilDB.ProfileEntityType.Tangent: + case ProfileEntityType.Tangent: var tangent = ProfileLineToSpeckle(entity as CivilDB.ProfileTangent); if (tangent != null) { @@ -552,8 +569,8 @@ public CivilProfile ProfileToSpeckle(CivilDB.Profile profile) } break; - case CivilDB.ProfileEntityType.ParabolaSymmetric: - case CivilDB.ProfileEntityType.ParabolaAsymmetric: + case ProfileEntityType.ParabolaSymmetric: + case ProfileEntityType.ParabolaAsymmetric: default: var segment = ProfileGenericToSpeckle(entity.StartStation, entity.StartElevation, entity.EndStation, entity.EndElevation); if (segment != null) @@ -564,50 +581,50 @@ public CivilProfile ProfileToSpeckle(CivilDB.Profile profile) break; } } - _profile.curves = curves; + speckleProfile.curves = curves; // if offset profile, get offset distance and parent - _profile.offset = profile.Offset; - try + speckleProfile.offset = profile.Offset; + if (profile.ProfileType is ProfileType.OffsetProfile && profile.OffsetParameters.ParentProfileId != ObjectId.Null) { - if (profile.OffsetParameters.ParentProfileId != ObjectId.Null) + if (Trans.GetObject(profile.OffsetParameters.ParentProfileId, OpenMode.ForRead) is CivilDB.Profile parent && parent.Name != null) { - var parent = Trans.GetObject(profile.OffsetParameters.ParentProfileId, OpenMode.ForRead) as CivilDB.Profile; - if (parent != null && parent.Name != null) - { - _profile.parent = parent.Name; - } + speckleProfile.parent = parent.Name; } } - catch { } // get points of vertical intersection (PVIs) List pvisConverted = new(); var pvis = new Point3dCollection(); - foreach (CivilDB.ProfilePVI pvi in profile.PVIs) + foreach (ProfilePVI pvi in profile.PVIs) { - pvisConverted.Add(PointToSpeckle(new Point2d(pvi.Station, pvi.Elevation))); - pvis.Add(new Point3d(pvi.Station, pvi.Elevation, 0)); + double pviStation = 0; +#if CIVIL2024 + pviStation = pvi.RawStation; +#else + pviStation = pvi.Station; +#endif + pvisConverted.Add(PointToSpeckle(new Point2d(pviStation, pvi.Elevation))); + pvis.Add(new Point3d(pviStation, pvi.Elevation, 0)); } - _profile.pvis = pvisConverted; - + speckleProfile.pvis = pvisConverted; if (pvisConverted.Count > 1) { - _profile.displayValue = PolylineToSpeckle(pvis, profile.Closed); + speckleProfile.displayValue = PolylineToSpeckle(pvis, profile.Closed); } - _profile.units = ModelUnits; + speckleProfile.units = ModelUnits; - return _profile; + return speckleProfile; } - private Line ProfileLineToSpeckle(CivilDB.ProfileTangent tangent) + private Line ProfileLineToSpeckle(ProfileTangent tangent) { var start = new Point2d(tangent.StartStation, tangent.StartElevation); var end = new Point2d(tangent.EndStation, tangent.EndElevation); return LineToSpeckle(new LineSegment2d(start, end)); } - private Arc ProfileArcToSpeckle(CivilDB.ProfileCircular circular) + private Arc ProfileArcToSpeckle(ProfileCircular circular) { var start = new Point2d(circular.StartStation, circular.StartElevation); var end = new Point2d(circular.EndStation, circular.EndElevation); @@ -621,122 +638,31 @@ private Line ProfileGenericToSpeckle(double startStation, double startElevation, return LineToSpeckle(new LineSegment2d(start, end)); } - /* - public ApplicationObject ProfileToNative(Profile profile) - { - var appObj = new ApplicationObject(profile.id, profile.speckle_type) { applicationId = profile.applicationId }; - var existingObjs = GetExistingElementsByApplicationId(profile.applicationId); - var civilProfile = profile as CivilProfile; - - // get civil doc - if (!GetCivilDocument(out CivilDocument civilDoc)) - return appObj; - - // create or retrieve alignment, and parent if it exists - CivilDB.Profile _profile = existingObjs.Any() ? Trans.GetObject(existingObjs.FirstOrDefault(), OpenMode.ForWrite) as CivilDB.Profile : null; - var parent = civilProfile != null ? GetFromObjectIdCollection(civilProfile.parent, civilDoc.get()) : ObjectId.Null; - bool isUpdate = true; - if (_profile == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) // just create a new profile - { - isUpdate = false; - - // get civil props for creation -#region properties - var name = string.IsNullOrEmpty(profile.name) ? profile.applicationId : profile.name; // names need to be unique on creation (but not send i guess??) - var layer = Doc.Database.LayerZero; - - // type - var type = CivilDB.ProfileType.File; - if (civilProfile != null) - if (Enum.TryParse(civilProfile.type, out CivilDB.ProfileType civilType)) - type = civilType; - - // style - var docStyles = new ObjectIdCollection(); - foreach (ObjectId styleId in civilDoc.Styles.ProfileStyles) docStyles.Add(styleId); - var style = civilProfile != null ? - GetFromObjectIdCollection(civilProfile.style, docStyles, true) : civilDoc.Styles.ProfileStyles.First(); - -#endregion - - try - { - // add new profile to doc - // ⚠ this will throw if name is not unique!! - var id = ObjectId.Null; - switch (type) - { - // A surface profile—often called an existing ground (EG) profile—is extracted from a surface, showing the changes in elevation along a particular route - case CivilDB.ProfileType.EG: - - if (parent == ObjectId.Null) goto default; - try - { - id = CivilDB.Profile.CreateFromSurface(Doc, ); - } - catch - { - } - break; - default: - try - { - id = CivilDB.Profile.CreateFromGeCurve(); - } - catch - { - - } - break; - } - if (!id.IsValid) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"Create method returned null"); - return appObj; - } - _profile = Trans.GetObject(id, OpenMode.ForWrite) as CivilDB.Profile; - } - catch (System.Exception e) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"{e.Message}"); - return appObj; - } - } - - if (_profile == null) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"returned null after bake"); - return appObj; - } - - } - */ - // featurelines public Featureline FeatureLineToSpeckle(CivilDB.FeatureLine featureline) { // get all points var points = new List(); - var _points = featureline.GetPoints(Civil.FeatureLinePointType.AllPoints); - foreach (Point3d point in _points) + Point3dCollection allPoints = featureline.GetPoints(Civil.FeatureLinePointType.AllPoints); + foreach (Point3d point in allPoints) { points.Add(PointToSpeckle(point)); } // get elevation points var ePoints = new List(); - var _ePoints = featureline.GetPoints(Civil.FeatureLinePointType.ElevationPoint); - foreach (Point3d ePoint in _ePoints) + Point3dCollection elevationPoints = featureline.GetPoints(Civil.FeatureLinePointType.ElevationPoint); + foreach (Point3d ePoint in elevationPoints) { - ePoints.Add(_points.IndexOf(ePoint)); + ePoints.Add(allPoints.IndexOf(ePoint)); } // get pi points var piPoints = new List(); - var _piPoints = featureline.GetPoints(Civil.FeatureLinePointType.PIPoint); - foreach (Point3d piPoint in _piPoints) + Point3dCollection intersectionPoints = featureline.GetPoints(Civil.FeatureLinePointType.PIPoint); + foreach (Point3d piPoint in intersectionPoints) { - piPoints.Add(_points.IndexOf(piPoint)); + piPoints.Add(allPoints.IndexOf(piPoint)); } /* @@ -749,21 +675,24 @@ public Featureline FeatureLineToSpeckle(CivilDB.FeatureLine featureline) */ // get displayvalue - var polyline = PolylineToSpeckle(new Polyline3d(Poly3dType.SimplePoly, _piPoints, false)); + var polyline = PolylineToSpeckle(new Polyline3d(Poly3dType.SimplePoly, intersectionPoints, false)); // featureline - var _featureline = new Featureline(); - _featureline.curve = CurveToSpeckle(featureline.BaseCurve, ModelUnits); - _featureline.units = ModelUnits; - _featureline.displayValue = new List() { polyline }; - _featureline["@piPoints"] = piPoints; - _featureline["@elevationPoints"] = ePoints; - - if (!string.IsNullOrEmpty(featureline.Name)) { _featureline["name"] = featureline.Name; } - if (!string.IsNullOrEmpty(featureline.Description)) { _featureline["description"] = featureline.Description; } - if (featureline.SiteId != null) { _featureline["site"] = featureline.SiteId.ToString(); } - - return _featureline; + Featureline speckleFeatureline = new() + { + curve = CurveToSpeckle(featureline.BaseCurve, ModelUnits), + units = ModelUnits, + displayValue = new List() { polyline } + }; + AddNameAndDescriptionProperty(featureline.Name, featureline.Description, speckleFeatureline); + speckleFeatureline["@piPoints"] = piPoints; + speckleFeatureline["@elevationPoints"] = ePoints; + if (featureline.SiteId != null) + { + speckleFeatureline["site"] = featureline.SiteId.ToString(); + } + + return speckleFeatureline; } private Featureline FeaturelineToSpeckle(CivilDB.CorridorFeatureLine featureline) @@ -791,28 +720,23 @@ private Featureline FeaturelineToSpeckle(CivilDB.CorridorFeatureLine featureline var baseCurve = PolylineToSpeckle(new Polyline3d(Poly3dType.SimplePoly, baseCurvePoints, false)); // create featureline - var _featureline = new Featureline(); - _featureline.points = points; - _featureline.curve = baseCurve; - if (!string.IsNullOrEmpty(featureline.CodeName)) { _featureline.name = featureline.CodeName; } - _featureline.displayValue = polylines; - _featureline.units = ModelUnits; - - return _featureline; - } - - public CivilDB.FeatureLine FeatureLineToNative(Polycurve polycurve) - { - return null; + var speckleFeatureline = new Featureline + { + points = points, + curve = baseCurve, + name = featureline.CodeName ?? "", + displayValue = polylines, + units = ModelUnits + }; + + return speckleFeatureline; } // surfaces - public Mesh SurfaceToSpeckle(CivilDB.TinSurface surface) + public Mesh SurfaceToSpeckle(TinSurface surface) { - Mesh mesh = null; - // output vars - var _vertices = new List(); + List vertices = new(); var faces = new List(); foreach (var triangle in surface.GetTriangles(false)) { @@ -830,14 +754,14 @@ public Mesh SurfaceToSpeckle(CivilDB.TinSurface surface) var faceIndices = new List(); foreach (var vertex in triangleVertices) { - if (!_vertices.Contains(vertex)) + if (!vertices.Contains(vertex)) { - faceIndices.Add(_vertices.Count); - _vertices.Add(vertex); + faceIndices.Add(vertices.Count); + vertices.Add(vertex); } else { - faceIndices.Add(_vertices.IndexOf(vertex)); + faceIndices.Add(vertices.IndexOf(vertex)); } } @@ -847,32 +771,33 @@ public Mesh SurfaceToSpeckle(CivilDB.TinSurface surface) triangle.Dispose(); } - var vertices = _vertices.SelectMany(o => PointToSpeckle(o).ToList()).ToList(); + var speckleVertices = vertices.SelectMany(o => PointToSpeckle(o).ToList()).ToList(); - mesh = new Mesh(vertices, faces); - mesh.units = ModelUnits; - mesh.bbox = BoxToSpeckle(surface.GeometricExtents); + var mesh = new Mesh(speckleVertices, faces) + { + units = ModelUnits, + bbox = BoxToSpeckle(surface.GeometricExtents) + }; // add tin surface props - var props = Speckle.Core.Models.Utilities.GetApplicationProps(surface, typeof(CivilDB.TinSurface), false); + AddNameAndDescriptionProperty(surface.Name, surface.Description, mesh); + Base props = Utilities.GetApplicationProps(surface, typeof(TinSurface), false); mesh[CivilPropName] = props; return mesh; } - public Mesh SurfaceToSpeckle(CivilDB.GridSurface surface) + public Mesh SurfaceToSpeckle(GridSurface surface) { - Mesh mesh = null; - // output vars - var _vertices = new List(); + var _vertices = new List(); var faces = new List(); foreach (var cell in surface.GetCells(false)) { // get vertices var faceIndices = new List(); - foreach (var vertex in new List() {cell.BottomLeftVertex, cell.BottomRightVertex, cell.TopLeftVertex, cell.TopRightVertex}) + foreach (var vertex in new List() {cell.BottomLeftVertex, cell.BottomRightVertex, cell.TopLeftVertex, cell.TopRightVertex}) { if (!_vertices.Contains(vertex.Location)) { @@ -893,21 +818,21 @@ public Mesh SurfaceToSpeckle(CivilDB.GridSurface surface) } var vertices = _vertices.Select(o => PointToSpeckle(o).ToList()).SelectMany(o => o).ToList(); - mesh = new Mesh(vertices, faces); - mesh.units = ModelUnits; - mesh.bbox = BoxToSpeckle(surface.GeometricExtents); + var mesh = new Mesh(vertices, faces) + { + units = ModelUnits, + bbox = BoxToSpeckle(surface.GeometricExtents) + }; // add grid surface props - if (!string.IsNullOrEmpty(surface.DisplayName)){ mesh["name"] = surface.DisplayName; } - if (!string.IsNullOrEmpty(surface.Description)){ mesh["description"] = surface.Description; } + AddNameAndDescriptionProperty(surface.Name, surface.Description, mesh); return mesh; } public object CivilSurfaceToNative(Mesh mesh) { - var props = mesh[CivilPropName] as Base; - if (props == null) + if (mesh[CivilPropName] is not Base props) { return null; } @@ -932,45 +857,44 @@ public ApplicationObject TinSurfaceToNative(Mesh mesh, Base props) } // create or retrieve tin surface - CivilDB.TinSurface _surface = existingObjs.Any() ? Trans.GetObject(existingObjs.FirstOrDefault(), OpenMode.ForWrite) as CivilDB.TinSurface : null; + CivilDB.TinSurface surface = existingObjs.Any() ? Trans.GetObject(existingObjs.FirstOrDefault(), OpenMode.ForWrite) as CivilDB.TinSurface : null; bool isUpdate = true; - if (_surface == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) // just create a new surface + if (surface == null || ReceiveMode == Speckle.Core.Kits.ReceiveMode.Create) // just create a new surface { isUpdate = false; // get civil props for creation - var name = string.IsNullOrEmpty(props["Name"] as string) ? mesh.applicationId : props["Name"] as string; - var layer = Doc.Database.LayerZero; - var docStyles = new ObjectIdCollection(); + var name = string.IsNullOrEmpty(mesh["name"] as string) ? + string.IsNullOrEmpty(mesh.applicationId) ? + mesh.id : + mesh.applicationId : + mesh["name"] as string; + ObjectId layer = Doc.Database.LayerZero; + ObjectIdCollection docStyles = new(); + ObjectId style = ObjectId.Null; foreach (ObjectId styleId in civilDoc.Styles.SurfaceStyles) { docStyles.Add(styleId); } - - var style = props["style"] as string != null ? - GetFromObjectIdCollection(props["style"] as string, docStyles) : civilDoc.Styles.SurfaceStyles.First(); + + if (docStyles.Count != 0 ) + { + style = GetFromObjectIdCollection(props["style"] as string, docStyles, true); + } // add new surface to doc - // ⚠ this will throw if name is empty? var id = ObjectId.Null; - try - { - id = CivilDB.TinSurface.Create(name, style); - } - catch (System.Exception e) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: $"{e.Message}"); - return appObj; - } + id = style == ObjectId.Null ? TinSurface.Create(Doc.Database, name) : TinSurface.Create(name, style); if (!id.IsValid) { appObj.Update(status: ApplicationObject.State.Failed, logItem: $"Create method returned null"); return appObj; } - _surface = Trans.GetObject(id, OpenMode.ForWrite) as CivilDB.TinSurface; + + surface = Trans.GetObject(id, OpenMode.ForWrite) as TinSurface; } - if (_surface == null) + if (surface == null) { appObj.Update(status: ApplicationObject.State.Failed, logItem: $"retrieved or baked surface was null"); return appObj; @@ -978,15 +902,15 @@ public ApplicationObject TinSurfaceToNative(Mesh mesh, Base props) if (isUpdate) { - appObj.Container = _surface.Layer; // set the appobj container to be the same layer as the existing alignment - _surface.DeleteVertices(_surface.Vertices); // remove existing vertices + appObj.Container = surface.Layer; // set the appobj container to be the same layer as the existing alignment + surface.DeleteVertices(surface.Vertices); // remove existing vertices } // add all vertices var vertices = new Point3dCollection(); var meshVertices = mesh.GetPoints().Select(o => PointToNative(o)).ToList(); meshVertices.ForEach(o => vertices.Add(o)); - _surface.AddVertices(vertices); + surface.AddVertices(vertices); // loop through faces to create an edge dictionary by vertex, which includes all other vertices this vertex is connected to int i = 0; @@ -1019,7 +943,7 @@ public ApplicationObject TinSurfaceToNative(Mesh mesh, Base props) // loop through each surface vertex edge and create any that don't exist foreach (Point3d edgeStart in edges.Keys) { - var vertex = _surface.FindVertexAtXY(edgeStart.X, edgeStart.Y); + var vertex = surface.FindVertexAtXY(edgeStart.X, edgeStart.Y); var correctEdges = new List(); foreach (CivilDB.TinSurfaceEdge currentEdge in vertex.Edges) { @@ -1039,21 +963,21 @@ public ApplicationObject TinSurfaceToNative(Mesh mesh, Base props) continue; } - var a1 = _surface.FindVertexAtXY(edgeStart.X, edgeStart.Y); - var a2 = _surface.FindVertexAtXY(vertexToAdd.X, vertexToAdd.Y); - _surface.AddLine(a1, a2); + var a1 = surface.FindVertexAtXY(edgeStart.X, edgeStart.Y); + var a2 = surface.FindVertexAtXY(vertexToAdd.X, vertexToAdd.Y); + surface.AddLine(a1, a2); a1.Dispose(); a2.Dispose(); } } // loop through and delete any edges - var edgesToDelete = new List(); - foreach(CivilDB.TinSurfaceVertex vertex in _surface.Vertices) + var edgesToDelete = new List(); + foreach(TinSurfaceVertex vertex in surface.Vertices) { if (vertex.Edges.Count > edges[vertex.Location].Count) { - foreach (CivilDB.TinSurfaceEdge modifiedEdge in vertex.Edges) + foreach (TinSurfaceEdge modifiedEdge in vertex.Edges) { if (!edges[vertex.Location].Contains(modifiedEdge.Vertex2.Location) && !edges[modifiedEdge.Vertex2.Location].Contains(vertex.Location)) { @@ -1066,13 +990,13 @@ public ApplicationObject TinSurfaceToNative(Mesh mesh, Base props) } if (edgesToDelete.Count > 0) { - _surface.DeleteLines(edgesToDelete); - _surface.Rebuild(); + surface.DeleteLines(edgesToDelete); + surface.Rebuild(); } // update appobj var status = isUpdate ? ApplicationObject.State.Updated : ApplicationObject.State.Created; - appObj.Update(status: status, createdId: _surface.Handle.ToString(), convertedItem: _surface); + appObj.Update(status: status, createdId: surface.Handle.ToString(), convertedItem: surface); return appObj; } @@ -1086,21 +1010,29 @@ public Structure StructureToSpeckle(CivilDB.Structure structure) pipeIds.Add(structure.get_ConnectedPipe(i).ToString()); } - var _structure = new Structure(); - - _structure.location = PointToSpeckle(structure.Location, ModelUnits); - _structure.pipeIds = pipeIds; - _structure.displayValue = new List() { SolidToSpeckle(structure.Solid3dBody, out List notes) }; - _structure.units = ModelUnits; + Structure speckleStructure = new() + { + location = PointToSpeckle(structure.Location, ModelUnits), + pipeIds = pipeIds, + displayValue = new List() { SolidToSpeckle(structure.Solid3dBody, out List_) }, + units = ModelUnits + }; // assign additional structure props - _structure["name"] = (structure.DisplayName != null) ? structure.DisplayName : ""; - _structure["description"] = (structure.Description != null) ? structure.Description : ""; - try{ _structure["grate"] = structure.Grate; } catch{ } - try{ _structure["station"] = structure.Station; } catch{ } - try{ _structure["network"] = structure.NetworkName; } catch{ } + AddNameAndDescriptionProperty(structure.Name, structure.Description, speckleStructure); + + try + { + speckleStructure["grate"] = structure.Grate; + speckleStructure["station"] = structure.Station; + speckleStructure["network"] = structure.NetworkName; + } + catch (Exception e) when (!e.IsFatal()) + { + // Couldn't set non-essential structure properties + } - return _structure; + return speckleStructure; } // pipes @@ -1108,10 +1040,10 @@ public Structure StructureToSpeckle(CivilDB.Structure structure) public Pipe PipeToSpeckle(CivilDB.Pipe pipe) { // get the pipe curve - ICurve curve = null; + ICurve curve; switch (pipe.SubEntityType) { - case CivilDB.PipeSubEntityType.Straight: + case PipeSubEntityType.Straight: var line = new Acad.LineSegment3d(pipe.StartPoint, pipe.EndPoint); curve = LineToSpeckle(line); break; @@ -1120,46 +1052,41 @@ public Pipe PipeToSpeckle(CivilDB.Pipe pipe) break; } - var _pipe = new Pipe(); - _pipe.baseCurve = curve; - _pipe.diameter = pipe.InnerDiameterOrWidth; - _pipe.length = pipe.Length3DToInsideEdge; - _pipe.displayValue = new List { SolidToSpeckle(pipe.Solid3dBody, out List notes) }; - _pipe.units = ModelUnits; - - // assign additional pipe props - if (pipe.Name != null) - { - _pipe["name"] = pipe.Name; - } - - if (pipe.Description != null) + Pipe specklePipe = new() { - _pipe["description"] = pipe.Description; - } + baseCurve = curve, + diameter = pipe.InnerDiameterOrWidth, + length = pipe.Length3DToInsideEdge, + displayValue = new List { SolidToSpeckle(pipe.Solid3dBody, out List notes) }, + units = ModelUnits + }; - try { _pipe["shape"] = pipe.CrossSectionalShape.ToString(); } catch { } - try { _pipe["slope"] = pipe.Slope; } catch { } - try { _pipe["flowDirection"] = pipe.FlowDirection.ToString(); } catch { } - try { _pipe["flowRate"] = pipe.FlowRate; } catch { } - try { _pipe["network"] = pipe.NetworkName; } catch { } - try { _pipe["startOffset"] = pipe.StartOffset; } catch { } - try { _pipe["endOffset"] = pipe.EndOffset; } catch { } - try { _pipe["startStation"] = pipe.StartStation; } catch { } - try { _pipe["endStation"] = pipe.EndStation; } catch { } - try { _pipe["startStructure"] = pipe.StartStructureId.ToString(); } catch { } - try { _pipe["endStructure"] = pipe.EndStructureId.ToString(); } catch { } - - return _pipe; + // assign additional pipe props + AddNameAndDescriptionProperty(pipe.Name, pipe.Description, specklePipe); + + try { specklePipe["shape"] = pipe.CrossSectionalShape.ToString(); } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["slope"] = pipe.Slope; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["flowDirection"] = pipe.FlowDirection.ToString(); } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["flowRate"] = pipe.FlowRate; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["network"] = pipe.NetworkName; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["startOffset"] = pipe.StartOffset; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["endOffset"] = pipe.EndOffset; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["startStation"] = pipe.StartStation; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["endStation"] = pipe.EndStation; } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["startStructure"] = pipe.StartStructureId.ToString(); } catch(Exception ex) when(!ex.IsFatal()) { } + try { specklePipe["endStructure"] = pipe.EndStructureId.ToString(); } catch(Exception ex) when(!ex.IsFatal()) { } + + return specklePipe; } - public Pipe PipeToSpeckle(CivilDB.PressurePipe pipe) + + public Pipe PipeToSpeckle(PressurePipe pipe) { // get the pipe curve - ICurve curve = null; + ICurve curve; switch (pipe.BaseCurve) { - case AcadDB.Line o: - var line = new Acad.LineSegment3d(pipe.StartPoint, pipe.EndPoint); + case AcadDB.Line: + var line = new LineSegment3d(pipe.StartPoint, pipe.EndPoint); curve = LineToSpeckle(line); break; default: @@ -1167,126 +1094,117 @@ public Pipe PipeToSpeckle(CivilDB.PressurePipe pipe) break; } - var _pipe = new Pipe(); - _pipe.baseCurve = curve; - _pipe.diameter = pipe.InnerDiameter; - _pipe.length = pipe.Length3DCenterToCenter; - _pipe.displayValue = new List { SolidToSpeckle(pipe.Get3dBody(), out List notes) }; - _pipe.units = ModelUnits; - - // assign additional pipe props - if (pipe.Name != null) + Pipe specklePipe = new() { - _pipe["name"] = pipe.Name; - } + baseCurve = curve, + diameter = pipe.InnerDiameter, + length = pipe.Length3DCenterToCenter, + displayValue = new List { SolidToSpeckle(pipe.Get3dBody(), out List notes) }, + units = ModelUnits + }; - _pipe["description"] = (pipe.Description != null) ? pipe.Description : ""; - _pipe["isPressurePipe"] = true; - try { _pipe["partType"] = pipe.PartType.ToString(); } catch { } - try { _pipe["slope"] = pipe.Slope; } catch { } - try { _pipe["network"] = pipe.NetworkName; } catch { } - try { _pipe["startOffset"] = pipe.StartOffset; } catch { } - try { _pipe["endOffset"] = pipe.EndOffset; } catch { } - try { _pipe["startStation"] = pipe.StartStation; } catch { } - try { _pipe["endStation"] = pipe.EndStation; } catch { } - - return _pipe; + // assign additional pipe props + AddNameAndDescriptionProperty(pipe.Name, pipe.Description, specklePipe); + specklePipe["isPressurePipe"] = true; + + try { specklePipe["partType"] = pipe.PartType.ToString(); } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["slope"] = pipe.Slope; } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["network"] = pipe.NetworkName; } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["startOffset"] = pipe.StartOffset; } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["endOffset"] = pipe.EndOffset; } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["startStation"] = pipe.StartStation; } catch (Exception e) when (!e.IsFatal()) { } + try { specklePipe["endStation"] = pipe.EndStation; } catch (Exception e) when (!e.IsFatal()) { } + + return specklePipe; } // corridors // this is composed of assemblies, alignments, and profiles, use point codes to generate featurelines (which will have the 3d curve) - public Base CorridorToSpeckle(CivilDB.Corridor corridor) + public Base CorridorToSpeckle(Corridor corridor) { - var _corridor = new Base(); - List alignments = new(); List profiles = new(); List featurelines = new(); - foreach (var baseline in corridor.Baselines) + foreach (Baseline baseline in corridor.Baselines) { // get the collection of featurelines for this baseline - foreach (var mainFeaturelineCollection in baseline.MainBaselineFeatureLines.FeatureLineCollectionMap) // main featurelines + foreach (FeatureLineCollection mainFeaturelineCollection in baseline.MainBaselineFeatureLines.FeatureLineCollectionMap) // main featurelines { - foreach (var featureline in mainFeaturelineCollection) + foreach (CorridorFeatureLine featureline in mainFeaturelineCollection) { featurelines.Add(FeaturelineToSpeckle(featureline)); } } - foreach (var offsetFeaturelineCollection in baseline.OffsetBaselineFeatureLinesCol) // offset featurelines + foreach (BaselineFeatureLines offsetFeaturelineCollection in baseline.OffsetBaselineFeatureLinesCol) // offset featurelines { - foreach (var featurelineCollection in offsetFeaturelineCollection.FeatureLineCollectionMap) + foreach (FeatureLineCollection featurelineCollection in offsetFeaturelineCollection.FeatureLineCollectionMap) { - foreach (var featureline in featurelineCollection) + foreach (CorridorFeatureLine featureline in featurelineCollection) { featurelines.Add(FeaturelineToSpeckle(featureline)); } } } - // get alignment - try + // get alignment and profile if relevant + // for featureline based corridors, accessing AlignmentId and ProfileId will return NULL + // and throw an exception ""This operation on feature line based baseline is invalid". + if (!baseline.IsFeatureLineBased()) { - var alignmentId = baseline.AlignmentId; - var alignment = AlignmentToSpeckle(Trans.GetObject(alignmentId, OpenMode.ForRead) as CivilDB.Alignment); - if (alignment != null) + if (baseline.AlignmentId is ObjectId alignmentId) { - alignments.Add(alignment); + var alignment = Trans.GetObject(alignmentId, OpenMode.ForRead) as CivilDB.Alignment; + var convertedAlignment = AlignmentToSpeckle(alignment); + if (convertedAlignment != null) + { + alignments.Add(convertedAlignment); + } } - } - catch { } - - // get profile - try - { - var profileId = baseline.ProfileId; - var profile = ProfileToSpeckle(Trans.GetObject(profileId, OpenMode.ForRead) as CivilDB.Profile); - if (profile != null) + + if (baseline.ProfileId is ObjectId profileId) { - profiles.Add(profile); + var profile = Trans.GetObject(profileId, OpenMode.ForRead) as CivilDB.Profile; + var convertedProfile = ProfileToSpeckle(profile); + if (convertedProfile != null) + { + profiles.Add(convertedProfile); + } } } - catch { } } // get corridor surfaces List surfaces = new(); - foreach (var corridorSurface in corridor.CorridorSurfaces) + foreach (CorridorSurface corridorSurface in corridor.CorridorSurfaces) { try { var surface = Trans.GetObject(corridorSurface.SurfaceId, OpenMode.ForRead); - var mesh = ConvertToSpeckle(surface) as Mesh; - if (mesh != null) + if (ConvertToSpeckle(surface) is Mesh mesh) { surfaces.Add(mesh); } } - catch (Exception e) - { } - } - - _corridor["@alignments"] = alignments; - _corridor["@profiles"] = profiles; - _corridor["@featurelines"] = featurelines; - if (corridor.Name != null) - { - _corridor["name"] = corridor.Name; - } - - if (corridor.Description != null) - { - _corridor["description"] = corridor.Description; + catch (Exception e) when (!e.IsFatal()) + { + SpeckleLog.Logger.Warning(e, $"Could not convert and add surface to corridor"); + } } - _corridor["units"] = ModelUnits; - if (surfaces.Count> 0) + var corridorBase = new Base(); + corridorBase["@alignments"] = alignments; + corridorBase["@profiles"] = profiles; + corridorBase["@featurelines"] = featurelines; + AddNameAndDescriptionProperty(corridor.Name, corridor.Description, corridorBase); + corridorBase["units"] = ModelUnits; + if (surfaces.Count > 0) { - _corridor["@surfaces"] = surfaces; + corridorBase["@surfaces"] = surfaces; } - return _corridor; + return corridorBase; } } #endif diff --git a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Geometry.cs b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Geometry.cs index 473201c59d..134621830f 100644 --- a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Geometry.cs +++ b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Geometry.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.DoubleNumerics; using System.Linq; using System.Drawing; @@ -15,12 +14,6 @@ using Objects.Utils; using Arc = Objects.Geometry.Arc; using Box = Objects.Geometry.Box; -using Brep = Objects.Geometry.Brep; -using BrepEdge = Objects.Geometry.BrepEdge; -using BrepFace = Objects.Geometry.BrepFace; -using BrepLoop = Objects.Geometry.BrepLoop; -using BrepLoopType = Objects.Geometry.BrepLoopType; -using BrepTrim = Objects.Geometry.BrepTrim; using Circle = Objects.Geometry.Circle; using ControlPoint = Objects.Geometry.ControlPoint; using Curve = Objects.Geometry.Curve; @@ -33,11 +26,10 @@ using Polycurve = Objects.Geometry.Polycurve; using Polyline = Objects.Geometry.Polyline; using Spiral = Objects.Geometry.Spiral; -using Surface = Objects.Geometry.Surface; +using Transform = Objects.Other.Transform; using Vector = Objects.Geometry.Vector; using Speckle.Core.Kits; -using Objects.Geometry; -using Objects.Other; +using Speckle.Core.Logging; namespace Objects.Converter.AutocadCivil; @@ -87,11 +79,10 @@ public List> ControlPointsToSpeckle(AcadGeo.NurbSurface surfa { var point = surface.ControlPoints[count]; double weight = 1; - try + if (count < surface.Weights.Count) { weight = surface.Weights[count]; } - catch { } row.Add(new ControlPoint(point.X, point.Y, point.Z, weight, u)); count++; } @@ -226,9 +217,11 @@ private static double[] MakePerpendicular(Matrix3d matrix) // Line public Line LineToSpeckle(LineSegment2d line) { - var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), ModelUnits); - _line.length = line.Length; - _line.domain = IntervalToSpeckle(line.GetInterval()); + var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), ModelUnits) + { + length = line.Length, + domain = IntervalToSpeckle(line.GetInterval()) + }; return _line; } @@ -238,35 +231,24 @@ public Line LineToSpeckle(Line3d line, string units = null) var startParam = line.GetParameterOf(line.StartPoint); var endParam = line.GetParameterOf(line.EndPoint); - var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), u); - _line.length = line.GetLength(startParam, endParam, tolerance); - _line.domain = IntervalToSpeckle(line.GetInterval()); - _line.bbox = BoxToSpeckle(line.OrthoBoundBlock); + var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), u) + { + length = line.GetLength(startParam, endParam, tolerance), + domain = IntervalToSpeckle(line.GetInterval()), + bbox = BoxToSpeckle(line.OrthoBoundBlock) + }; return _line; } public Line LineToSpeckle(LineSegment3d line) { - var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), ModelUnits); - _line.length = line.Length; - _line.domain = IntervalToSpeckle(line.GetInterval()); - _line.bbox = BoxToSpeckle(line.OrthoBoundBlock); - return _line; - } - - public Line3d LineToNative(Line line) - { - var _line = new Line3d(PointToNative(line.start), PointToNative(line.end)); - if (line.domain != null) + var _line = new Line(PointToSpeckle(line.StartPoint), PointToSpeckle(line.EndPoint), ModelUnits) { - try - { - _line.SetInterval(IntervalToNative(line.domain)); - } - catch { } - } - + length = line.Length, + domain = IntervalToSpeckle(line.GetInterval()), + bbox = BoxToSpeckle(line.OrthoBoundBlock) + }; return _line; } @@ -274,10 +256,12 @@ public Line LineToSpeckle(AcadDB.Line line, string units = null) { var u = units ?? ModelUnits; - var _line = new Line(PointToSpeckle(line.StartPoint, u), PointToSpeckle(line.EndPoint, u), u); - _line.domain = new Interval(line.StartParam, line.EndParam); - _line.length = line.Length; - _line.bbox = BoxToSpeckle(line.GeometricExtents); + var _line = new Line(PointToSpeckle(line.StartPoint, u), PointToSpeckle(line.EndPoint, u), u) + { + domain = new Interval(line.StartParam, line.EndParam), + length = line.Length, + bbox = BoxToSpeckle(line.GeometricExtents) + }; return _line; } @@ -307,23 +291,25 @@ public Arc ArcToSpeckle(CircularArc2d arc) // find arc plane (normal is in clockwise dir) var center3 = new Point3d(arc.Center.X, arc.Center.Y, 0); - AcadGeo.Plane plane = - (arc.IsClockWise) - ? new AcadGeo.Plane(center3, Vector3d.ZAxis.MultiplyBy(-1)) - : new AcadGeo.Plane(center3, Vector3d.ZAxis); + AcadGeo.Plane plane = arc.IsClockWise + ? new AcadGeo.Plane(center3, Vector3d.ZAxis.MultiplyBy(-1)) + : new AcadGeo.Plane(center3, Vector3d.ZAxis); // calculate total angle. TODO: This needs to be validated across all possible arc orientations - var totalAngle = - (arc.IsClockWise) ? Math.Abs(arc.EndAngle - arc.StartAngle) : Math.Abs(arc.EndAngle - arc.StartAngle); + var totalAngle = arc.IsClockWise + ? Math.Abs(arc.EndAngle - arc.StartAngle) + : Math.Abs(arc.EndAngle - arc.StartAngle); // create arc - var _arc = new Arc(PlaneToSpeckle(plane), arc.Radius, arc.StartAngle, arc.EndAngle, totalAngle, ModelUnits); - _arc.startPoint = PointToSpeckle(arc.StartPoint); - _arc.endPoint = PointToSpeckle(arc.EndPoint); - _arc.midPoint = PointToSpeckle(arc.EvaluatePoint((interval.UpperBound - interval.LowerBound) / 2)); - _arc.domain = IntervalToSpeckle(interval); - _arc.length = arc.GetLength(arc.GetParameterOf(arc.StartPoint), arc.GetParameterOf(arc.EndPoint)); - _arc.bbox = BoxToSpeckle(arc.BoundBlock); + var _arc = new Arc(PlaneToSpeckle(plane), arc.Radius, arc.StartAngle, arc.EndAngle, totalAngle, ModelUnits) + { + startPoint = PointToSpeckle(arc.StartPoint), + endPoint = PointToSpeckle(arc.EndPoint), + midPoint = PointToSpeckle(arc.EvaluatePoint((interval.UpperBound - interval.LowerBound) / 2)), + domain = IntervalToSpeckle(interval), + length = arc.GetLength(arc.GetParameterOf(arc.StartPoint), arc.GetParameterOf(arc.EndPoint)), + bbox = BoxToSpeckle(arc.BoundBlock) + }; return _arc; } @@ -337,13 +323,15 @@ public Arc ArcToSpeckle(CircularArc3d arc) arc.EndAngle, Math.Abs(arc.EndAngle - arc.StartAngle), ModelUnits - ); - _arc.startPoint = PointToSpeckle(arc.StartPoint); - _arc.endPoint = PointToSpeckle(arc.EndPoint); - _arc.midPoint = PointToSpeckle(arc.EvaluatePoint((interval.UpperBound - interval.LowerBound) / 2)); - _arc.domain = IntervalToSpeckle(arc.GetInterval()); - _arc.length = arc.GetLength(arc.GetParameterOf(arc.StartPoint), arc.GetParameterOf(arc.EndPoint), tolerance); - _arc.bbox = BoxToSpeckle(arc.OrthoBoundBlock); + ) + { + startPoint = PointToSpeckle(arc.StartPoint), + endPoint = PointToSpeckle(arc.EndPoint), + midPoint = PointToSpeckle(arc.EvaluatePoint((interval.UpperBound - interval.LowerBound) / 2)), + domain = IntervalToSpeckle(arc.GetInterval()), + length = arc.GetLength(arc.GetParameterOf(arc.StartPoint), arc.GetParameterOf(arc.EndPoint), tolerance), + bbox = BoxToSpeckle(arc.OrthoBoundBlock) + }; return _arc; } @@ -370,13 +358,15 @@ public Arc ArcToSpeckle(AcadDB.Arc arc) arc.EndAngle, arc.TotalAngle, ModelUnits - ); - _arc.startPoint = PointToSpeckle(arc.StartPoint); - _arc.endPoint = PointToSpeckle(arc.EndPoint); - _arc.midPoint = PointToSpeckle(arc.GetPointAtDist(arc.Length / 2)); - _arc.domain = new Interval(arc.StartParam, arc.EndParam); - _arc.length = arc.Length; - _arc.bbox = BoxToSpeckle(arc.GeometricExtents); + ) + { + startPoint = PointToSpeckle(arc.StartPoint), + endPoint = PointToSpeckle(arc.EndPoint), + midPoint = PointToSpeckle(arc.GetPointAtDist(arc.Length / 2)), + domain = new Interval(arc.StartParam, arc.EndParam), + length = arc.Length, + bbox = BoxToSpeckle(arc.GeometricExtents) + }; return _arc; } @@ -404,9 +394,11 @@ public AcadDB.Arc ArcToNativeDB(Arc arc) // Circle public Circle CircleToSpeckle(AcadDB.Circle circle) { - var _circle = new Circle(PlaneToSpeckle(circle.GetPlane()), circle.Radius, ModelUnits); - _circle.length = circle.Circumference; - _circle.bbox = BoxToSpeckle(circle.GeometricExtents); + var _circle = new Circle(PlaneToSpeckle(circle.GetPlane()), circle.Radius, ModelUnits) + { + length = circle.Circumference, + bbox = BoxToSpeckle(circle.GeometricExtents) + }; return _circle; } @@ -421,10 +413,12 @@ public AcadDB.Circle CircleToNativeDB(Circle circle) public Ellipse EllipseToSpeckle(AcadDB.Ellipse ellipse) { var plane = new AcadGeo.Plane(ellipse.Center, ellipse.MajorAxis, ellipse.MinorAxis); - var _ellipse = new Ellipse(PlaneToSpeckle(plane), ellipse.MajorRadius, ellipse.MinorRadius, ModelUnits); - _ellipse.domain = new Interval(ellipse.StartParam, ellipse.EndParam); - _ellipse.length = ellipse.GetDistanceAtParameter(ellipse.EndParam); - _ellipse.bbox = BoxToSpeckle(ellipse.GeometricExtents); + var _ellipse = new Ellipse(PlaneToSpeckle(plane), ellipse.MajorRadius, ellipse.MinorRadius, ModelUnits) + { + domain = new Interval(ellipse.StartParam, ellipse.EndParam), + length = ellipse.GetDistanceAtParameter(ellipse.EndParam), + bbox = BoxToSpeckle(ellipse.GeometricExtents) + }; return _ellipse; } @@ -455,9 +449,11 @@ private Polyline PolylineToSpeckle(Point3dCollection points, bool closed) } var _points = vertices.SelectMany(o => PointToSpeckle(o).ToList()).ToList(); - var _polyline = new Polyline(_points, ModelUnits); - _polyline.closed = closed || vertices.First().IsEqualTo(vertices.Last()) ? true : false; - _polyline.length = length; + var _polyline = new Polyline(_points, ModelUnits) + { + closed = closed || vertices.First().IsEqualTo(vertices.Last()), + length = length + }; return _polyline; } @@ -470,10 +466,12 @@ public Polyline PolylineToSpeckle(AcadDB.Polyline polyline) // AcadDB.Polylines points.AddRange(PointToSpeckle(polyline.GetPoint3dAt(i)).ToList()); } - var _polyline = new Polyline(points, ModelUnits); - _polyline.closed = polyline.Closed || polyline.StartPoint.Equals(polyline.EndPoint) ? true : false; // hatch boundary polylines are not closed, cannot rely on .Closed prop - _polyline.length = polyline.Length; - _polyline.bbox = BoxToSpeckle(polyline.GeometricExtents); + var _polyline = new Polyline(points, ModelUnits) + { + closed = polyline.Closed || polyline.StartPoint.Equals(polyline.EndPoint), // hatch boundary polylines are not closed, cannot rely on .Closed prop + length = polyline.Length, + bbox = BoxToSpeckle(polyline.GeometricExtents) + }; return _polyline; } @@ -500,10 +498,12 @@ public Polyline PolylineToSpeckle(Polyline3d polyline) } } - var _polyline = new Polyline(points, ModelUnits); - _polyline.closed = polyline.Closed || polyline.StartPoint.Equals(polyline.EndPoint) ? true : false; - _polyline.length = polyline.Length; - _polyline.bbox = BoxToSpeckle(polyline.GeometricExtents); + var _polyline = new Polyline(points, ModelUnits) + { + closed = polyline.Closed || polyline.StartPoint.Equals(polyline.EndPoint), + length = polyline.Length, + bbox = BoxToSpeckle(polyline.GeometricExtents) + }; return _polyline; } @@ -511,9 +511,9 @@ public Polyline PolylineToSpeckle(Polyline3d polyline) public Polyline3d PolylineToNativeDB(Polyline polyline) { var vertices = new Point3dCollection(); - for (int i = 0; i < polyline.points.Count; i++) + foreach (Point point in polyline.GetPoints()) { - vertices.Add(PointToNative(polyline.points[i])); + vertices.Add(PointToNative(point)); } return new Polyline3d(Poly3dType.SimplePoly, vertices, polyline.closed); @@ -522,8 +522,6 @@ public Polyline3d PolylineToNativeDB(Polyline polyline) // Polycurve public Polycurve PolycurveToSpeckle(Polyline2d polyline) // AC polyline2d can have linear, circlular, or elliptical segments { - var polycurve = new Polycurve(units: ModelUnits) { closed = polyline.Closed }; - // extract segment curves var segments = new List(); var exploded = new DBObjectCollection(); @@ -538,14 +536,10 @@ public Polycurve PolycurveToSpeckle(Polyline2d polyline) // AC polyline2d can ha // get the connection point to the next segment - this is necessary since imported polycurves might have segments in different directions var connectionPoint = new Point3d(); var nextSegment = exploded[i + 1] as AcadDB.Curve; - if (nextSegment.StartPoint.IsEqualTo(segment.StartPoint) || nextSegment.StartPoint.IsEqualTo(segment.EndPoint)) - { - connectionPoint = nextSegment.StartPoint; - } - else - { - connectionPoint = nextSegment.EndPoint; - } + connectionPoint = + nextSegment.StartPoint.IsEqualTo(segment.StartPoint) || nextSegment.StartPoint.IsEqualTo(segment.EndPoint) + ? nextSegment.StartPoint + : nextSegment.EndPoint; previousPoint = connectionPoint; segment = GetCorrectSegmentDirection(segment, connectionPoint, true, out Point3d otherPoint); @@ -554,26 +548,31 @@ public Polycurve PolycurveToSpeckle(Polyline2d polyline) // AC polyline2d can ha { segment = GetCorrectSegmentDirection(segment, previousPoint, false, out previousPoint); } - segments.Add(CurveToSpeckle(segment)); - } - if (segments.Count() == 0) - { - throw new Exception("Failed to convert Autocad Polyline2d to Speckle Polycurve"); - } + ICurve convertedSegment = CurveToSpeckle(segment); + if (convertedSegment is null) + { + throw new ConversionException($"Could not convert a Polyline2D segment to speckle curve"); + } - polycurve.segments = segments; + segments.Add(convertedSegment); + } - polycurve.length = polyline.Length; - polycurve.bbox = BoxToSpeckle(polyline.GeometricExtents); + Polycurve polycurve = + new() + { + segments = segments, + length = polyline.Length, + closed = polyline.Closed, + bbox = BoxToSpeckle(polyline.GeometricExtents), + units = ModelUnits + }; return polycurve; } public Polycurve PolycurveToSpeckle(AcadDB.Polyline polyline) // AC polylines are polycurves with linear or arc segments { - var polycurve = new Polycurve(units: ModelUnits) { closed = polyline.Closed }; - // extract segments var segments = new List(); Point3d previousPoint = new(); @@ -603,16 +602,10 @@ public Polycurve PolycurveToSpeckle(AcadDB.Polyline polyline) // AC polylines ar } else { - if ( + connectionPoint = nextSegment.StartPoint.IsEqualTo(segment.StartPoint) || nextSegment.StartPoint.IsEqualTo(segment.EndPoint) - ) - { - connectionPoint = nextSegment.StartPoint; - } - else - { - connectionPoint = nextSegment.EndPoint; - } + ? nextSegment.StartPoint + : nextSegment.EndPoint; } previousPoint = connectionPoint; @@ -622,18 +615,25 @@ public Polycurve PolycurveToSpeckle(AcadDB.Polyline polyline) // AC polylines ar { segment = GetCorrectSegmentDirection(segment, previousPoint, false, out previousPoint); } - segments.Add(CurveToSpeckle(segment)); - } - if (segments.Count() == 0) - { - throw new Exception("Failed to convert Autocad Polyline to Speckle Polycurve"); - } + ICurve convertedSegment = CurveToSpeckle(segment); + if (convertedSegment is null) + { + throw new ConversionException($"Could not convert a Polyline segment to speckle curve"); + } - polycurve.segments = segments; + segments.Add(CurveToSpeckle(segment)); + } - polycurve.length = polyline.Length; - polycurve.bbox = BoxToSpeckle(polyline.GeometricExtents); + Polycurve polycurve = + new() + { + segments = segments, + length = polyline.Length, + closed = polyline.Closed, + bbox = BoxToSpeckle(polyline.GeometricExtents), + units = ModelUnits + }; return polycurve; } @@ -669,7 +669,7 @@ out Point3d nextPoint bool reverseDirection = false; if (isFirstSegment) { - reverseDirection = (segment.StartPoint.IsEqualTo(connectionPoint)) ? true : false; + reverseDirection = segment.StartPoint.IsEqualTo(connectionPoint); if (reverseDirection) { nextPoint = segment.StartPoint; @@ -677,7 +677,7 @@ out Point3d nextPoint } else { - reverseDirection = (segment.StartPoint.IsEqualTo(connectionPoint)) ? false : true; + reverseDirection = !segment.StartPoint.IsEqualTo(connectionPoint); if (reverseDirection) { nextPoint = segment.StartPoint; @@ -709,7 +709,7 @@ out Point3d nextPoint bool reverseDirection = false; if (isFirstSegment) { - reverseDirection = (segment.StartPoint.IsEqualTo(connectionPoint)) ? true : false; + reverseDirection = segment.StartPoint.IsEqualTo(connectionPoint); if (reverseDirection) { nextPoint = segment.StartPoint; @@ -717,14 +717,14 @@ out Point3d nextPoint } else { - reverseDirection = (segment.StartPoint.IsEqualTo(connectionPoint)) ? false : true; + reverseDirection = !segment.StartPoint.IsEqualTo(connectionPoint); if (reverseDirection) { nextPoint = segment.StartPoint; } } - return (reverseDirection) ? segment.GetReverseParameterCurve() : segment; + return reverseDirection ? segment.GetReverseParameterCurve() : segment; } private bool IsPolycurvePlanar(Polycurve polycurve) @@ -735,10 +735,7 @@ private bool IsPolycurvePlanar(Polycurve polycurve) switch (segment) { case Line o: - if (z == null) - { - z = o.start.z; - } + z ??= o.start.z; if (o.start.z != z || o.end.z != z) { @@ -747,10 +744,7 @@ private bool IsPolycurvePlanar(Polycurve polycurve) break; case Arc o: - if (z == null) - { - z = o.startPoint.z; - } + z ??= o.startPoint.z; if (o.startPoint.z != z || o.midPoint.z != z || o.endPoint.z != z) { @@ -759,10 +753,7 @@ private bool IsPolycurvePlanar(Polycurve polycurve) break; case Curve o: - if (z == null) - { - z = o.points[2]; - } + z ??= o.points[2]; for (int i = 2; i < o.points.Count; i += 3) { @@ -774,10 +765,7 @@ private bool IsPolycurvePlanar(Polycurve polycurve) break; case Spiral o: - if (z == null) - { - z = o.startPoint.z; - } + z ??= o.startPoint.z; if (o.startPoint.z != z || o.endPoint.z != z) { @@ -827,7 +815,7 @@ public AcadDB.Polyline PolycurveToNativeDB(Polycurve polycurve) count++; break; case Spiral o: - var vertices = o.displayValue.GetPoints().Select(p => PointToNative(p)).ToList(); + var vertices = o.displayValue.GetPoints().Select(PointToNative).ToList(); foreach (var vertex in vertices) { polyline.AddVertexAt(count, vertex.Convert2d(plane), 0, 0, 0); @@ -869,23 +857,26 @@ public Curve SplineToSpeckle(Spline spline) // get nurbs and geo data var data = spline.NurbsData; - var _spline = spline.GetGeCurve() as NurbCurve3d; + var nurbs = spline.GetGeCurve() as NurbCurve3d; // hack: check for incorrectly closed periodic curves (this seems like acad bug, has resulted from receiving rhino curves) bool periodicClosed = false; - if (_spline.Knots.Count < _spline.NumberOfControlPoints + _spline.Degree + 1 && spline.IsPeriodic) + if (nurbs.Knots.Count < nurbs.NumberOfControlPoints + nurbs.Degree + 1 && spline.IsPeriodic) { periodicClosed = true; } // handle the display polyline - try + AcadDB.Curve poly = spline.ToPolyline(false, true); + ICurve convertedPoly = CurveToSpeckle(poly); + if (convertedPoly is Polyline polyline) + { + curve.displayValue = polyline; + } + else { - var poly = spline.ToPolyline(false, true); - Polyline displayValue = CurveToSpeckle(poly) as Polyline; - curve.displayValue = displayValue; + SpeckleLog.Logger.Error("Could not create polyline for spline's display value."); } - catch { } // get points // NOTE: for closed periodic splines, autocad does not track last #degree points. Add the first #degree control points to the list if so. @@ -945,16 +936,17 @@ public Curve SplineToSpeckle(Spline spline) curve.degree = spline.Degree; curve.periodic = spline.IsPeriodic; curve.rational = spline.IsRational; - curve.closed = (periodicClosed) ? true : spline.Closed; - curve.length = _spline.GetLength(_spline.StartParameter, _spline.EndParameter, tolerance); - curve.domain = IntervalToSpeckle(_spline.GetInterval()); + curve.closed = periodicClosed || spline.Closed; + curve.length = nurbs.GetLength(nurbs.StartParameter, nurbs.EndParameter, tolerance); + curve.domain = IntervalToSpeckle(nurbs.GetInterval()); curve.bbox = BoxToSpeckle(spline.GeometricExtents); curve.units = ModelUnits; return curve; } - // handles polycurves with spline segments: bakes segments individually and then joins + // handles polycurves with spline segments: bakes segments individually + public ApplicationObject PolycurveSplineToNativeDB(Polycurve polycurve) { var appObj = new ApplicationObject(polycurve.id, polycurve.speckle_type) @@ -993,22 +985,9 @@ public ApplicationObject PolycurveSplineToNativeDB(Polycurve polycurve) if (first == null) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "No segments were successfully converted"); - return appObj; + throw new ConversionException($"No segments were successfully converted"); } - if (others.Count > 0) - { - try - { - first.JoinEntities(others.ToArray()); - // TODO: this always fails. Fix and edit the createdids and converted to only reflect the new joined entities - } - catch (Exception e) - { - appObj.Update(logItem: $"Could not create spline from segments: {e.Message}"); - } - } return appObj; } @@ -1048,7 +1027,7 @@ public ICurve CurveToSpeckle(Curve2d curve, string units = null) public Curve NurbsToSpeckle(NurbCurve2d curve) { - var _curve = new Curve(); + Curve _curve = new(); // get control points var points = new List(); @@ -1088,7 +1067,7 @@ public Curve NurbsToSpeckle(NurbCurve2d curve) public Curve NurbsToSpeckle(NurbCurve3d curve) { - var _curve = new Curve(); + Curve _curve = new(); // get control points var points = new List(); @@ -1132,7 +1111,7 @@ public NurbCurve3d NurbcurveToNative(Curve curve) { // process control points // NOTE: for **closed periodic** curves that have "n" control pts, curves sent from rhino will have n+degree points. Remove extra pts for autocad. - var _points = curve.GetPoints().Select(o => PointToNative(o)).ToList(); + var _points = curve.GetPoints().Select(PointToNative).ToList(); if (curve.closed && curve.periodic) { _points = _points.GetRange(0, _points.Count - curve.degree); @@ -1144,7 +1123,7 @@ public NurbCurve3d NurbcurveToNative(Curve curve) // NOTE: Autocad defines spline knots as a vector of size # control points + degree + 1. (# at start and end should match degree) // Conversions for autocad need to make sure this is satisfied, otherwise will cause protected mem crash. // NOTE: for **closed periodic** curves that have "n" control pts, # of knots should be n + 1. Remove degree = 3 knots from start and end. - var _knots = curve.knots; + List _knots = curve.knots; if (curve.knots.Count == _points.Count + curve.degree - 1) // handles rhino format curves { _knots.Insert(0, _knots[0]); @@ -1202,10 +1181,10 @@ public ICurve CurveToSpeckle(AcadDB.Curve curve, string units = null) return PolycurveToSpeckle(polyline); } - case AcadDB.Polyline2d polyline2d: + case Polyline2d polyline2d: return PolycurveToSpeckle(polyline2d); - case AcadDB.Polyline3d polyline3d: + case Polyline3d polyline3d: return PolylineToSpeckle(polyline3d); case AcadDB.Arc arc: @@ -1253,7 +1232,7 @@ public AcadDB.Curve NurbsToNativeDB(Curve curve) converted = EllipseToNativeDB(ellipse); break; case Polycurve polycurve: - if (polycurve.segments.Where(o => o is Curve).Count() > 0) + if (polycurve.segments.Any(o => o is Curve)) { var convertedPolycurve = PolycurveSplineToNativeDB(polycurve); convertedList = convertedPolycurve.Converted.Cast().ToList(); @@ -1333,72 +1312,63 @@ public Box BoxToSpeckle(BoundBlock2d bound) public Box BoxToSpeckle(BoundBlock3d bound) { - try - { - // convert min and max pts to speckle first - var min = PointToSpeckle(bound.GetMinimumPoint()); - var max = PointToSpeckle(bound.GetMaximumPoint()); - - // get dimension intervals - var xSize = new Interval(min.x, max.x); - var ySize = new Interval(min.y, max.y); - var zSize = new Interval(min.z, max.z); - - // get the base plane of the bounding box from extents and current UCS - var ucs = Doc.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d; - var plane = new AcadGeo.Plane(bound.GetMinimumPoint(), ucs.Xaxis, ucs.Yaxis); - - var box = new Box() - { - xSize = xSize, - ySize = ySize, - zSize = zSize, - basePlane = PlaneToSpeckle(plane), - volume = xSize.Length * ySize.Length * zSize.Length, - units = ModelUnits - }; - - return box; - } - catch + Box box = null; + if (bound.GetMinimumPoint() is Point3d min && bound.GetMaximumPoint() is Point3d max) { - return null; + box = GetBoxFromMinAndMaxPoints(min, max); } + return box; } public Box BoxToSpeckle(Extents3d extents) { - try + Box box = null; + if (extents.MinPoint is Point3d min && extents.MaxPoint is Point3d max) { - // convert min and max pts to speckle first - var min = PointToSpeckle(extents.MinPoint); - var max = PointToSpeckle(extents.MaxPoint); + box = GetBoxFromMinAndMaxPoints(min, max); + } + return box; + } - // get dimension intervals - var xSize = new Interval(min.x, max.x); - var ySize = new Interval(min.y, max.y); - var zSize = new Interval(min.z, max.z); + private Box GetBoxFromMinAndMaxPoints(Point3d min, Point3d max) + { + Point3d extMin = ToExternalCoordinates(min); + Point3d extMax = ToExternalCoordinates(max); - // get the base plane of the bounding box from extents and current UCS - var ucs = Doc.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d; - var plane = new AcadGeo.Plane(extents.MinPoint, ucs.Xaxis, ucs.Yaxis); + // get dimension intervals + Interval xSize = new(extMin.X, extMax.X); + Interval ySize = new(extMin.Y, extMax.Y); + Interval zSize = new(extMin.Z, extMax.Z); - var box = new Box() - { - xSize = xSize, - ySize = ySize, - zSize = zSize, - basePlane = PlaneToSpeckle(plane), - volume = xSize.Length * ySize.Length * zSize.Length, - units = ModelUnits - }; + // create box + var box = new Box() + { + xSize = xSize, + ySize = ySize, + zSize = zSize, + volume = xSize.Length * ySize.Length * zSize.Length, + units = ModelUnits + }; - return box; + // get the base plane of the bounding box from extents and current UCS + var ucs = Doc.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d; + Plane plane = null; + try + { + AcadGeo.Plane acadPlane = new(min, ucs.Xaxis, ucs.Yaxis); + plane = PlaneToSpeckle(acadPlane); } - catch + catch (Exception e) when (!e.IsFatal()) { - return null; + SpeckleLog.Logger.Error(e, "Could not create base plane for box"); } + + if (plane != null) + { + box.basePlane = plane; + } + + return box; } // Brep @@ -1408,37 +1378,15 @@ public Mesh SolidToSpeckle(Solid3d solid, out List notes, string units = } // Mesh - /* need edge & face info on polygon meshes - public Mesh MeshToSpeckle(AcadDB.PolygonMesh mesh) - { - var _vertices = new List(); - var colors = new List(); - using (Transaction tr = Doc.Database.TransactionManager.StartTransaction()) - { - foreach (ObjectId id in mesh) - { - var vertex = (PolygonMeshVertex)tr.GetObject(id, OpenMode.ForRead); - _vertices.Add(vertex.Position); - colors.Add(vertex.Color.ColorValue.ToArgb()); - } - tr.Commit(); - } - var vertices = PointsToFlatArray(_vertices); - - var speckleMesh = new Mesh(vertices, faces, colors.ToArray(), null, ModelUnits); - speckleMesh.bbox = BoxToSpeckle(mesh.GeometricExtents, true); - return speckleMesh; - } - */ // Polyface mesh vertex indexing starts at 1. Subtract 1 from face vertex index when sending to Speckle public Mesh MeshToSpeckle(PolyFaceMesh mesh, string units = null) { var u = units ?? ModelUnits; - var _vertices = new List(); - var faces = new List(); - var colors = new List(); + List _vertices = new(); + List faces = new(); + List colors = new(); using (Transaction tr = Doc.Database.TransactionManager.StartTransaction()) { foreach (ObjectId id in mesh) @@ -1485,8 +1433,7 @@ public Mesh MeshToSpeckle(PolyFaceMesh mesh, string units = null) vertices.AddRange(PointToSpeckle(vert).ToList()); } - var speckleMesh = new Mesh(vertices, faces, colors, null, u); - speckleMesh.bbox = BoxToSpeckle(mesh.GeometricExtents); + var speckleMesh = new Mesh(vertices, faces, colors, null, u) { bbox = BoxToSpeckle(mesh.GeometricExtents) }; return speckleMesh; } @@ -1528,8 +1475,10 @@ public Mesh MeshToSpeckle(SubDMesh mesh) .Select(o => Color.FromArgb(Convert.ToInt32(o.Red), Convert.ToInt32(o.Green), Convert.ToInt32(o.Blue)).ToArgb()) .ToList(); - var speckleMesh = new Mesh(vertices, faces, colors, null, ModelUnits); - speckleMesh.bbox = BoxToSpeckle(mesh.GeometricExtents); + var speckleMesh = new Mesh(vertices, faces, colors, null, ModelUnits) + { + bbox = BoxToSpeckle(mesh.GeometricExtents) + }; return speckleMesh; } @@ -1541,7 +1490,7 @@ public PolyFaceMesh MeshToNativeDB(Mesh mesh) // get vertex points var vertices = new Point3dCollection(); - var points = mesh.GetPoints().Select(o => PointToNative(o)).ToList(); + var points = mesh.GetPoints().Select(PointToNative).ToList(); foreach (var point in points) { vertices.Add(point); @@ -1563,14 +1512,19 @@ public PolyFaceMesh MeshToNativeDB(Mesh mesh) for (int i = 0; i < vertices.Count; i++) { var vertex = new PolyFaceMeshVertex(points[i]); - if (mesh.colors.Count > 0) + if (i < mesh.colors.Count) { try { - Color color = Color.FromArgb(mesh.colors[i]); - vertex.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(color.R, color.G, color.B); + if (Color.FromArgb(mesh.colors[i]) is Color color) + { + vertex.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(color.R, color.G, color.B); + } + } + catch (Exception e) when (!e.IsFatal()) + { + // Couldn't set vertex color, but this should not prevent conversion. } - catch { } } if (vertex.IsNewObject) { @@ -1641,8 +1595,10 @@ private Mesh GetMeshFromSolidOrSurface( area = solid.Area; volume = solid.MassProperties.Volume; } - catch (Exception e) { } - ; + catch (Exception e) when (!e.IsFatal()) + { + // Couldn't set area and /or volume props, but this should not prevent conversion. + } bbox = BoxToSpeckle(solid.GeometricExtents); } @@ -1707,15 +1663,18 @@ private Mesh GetMeshFromSolidOrSurface( // create speckle mesh var vertices = _vertices.SelectMany(o => PointToSpeckle(o).ToList()).ToList(); - mesh = new Mesh(vertices, faces); - mesh.units = ModelUnits; - mesh.bbox = bbox; - mesh.area = area; - mesh.volume = volume; + mesh = new Mesh(vertices, faces) + { + units = ModelUnits, + bbox = bbox, + area = area, + volume = volume + }; } } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + SpeckleLog.Logger.Warning(e, $"Could not retrieve mesh from brep"); notes.Add(e.Message); } } diff --git a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Other.cs b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Other.cs index 93969b9720..f97cea6124 100644 --- a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Other.cs +++ b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.Other.cs @@ -7,7 +7,6 @@ using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Windows.Data; using Autodesk.AutoCAD.Colors; -using AcadBRep = Autodesk.AutoCAD.BoundaryRepresentation; using AcadDB = Autodesk.AutoCAD.DatabaseServices; using Speckle.Core.Models; @@ -27,6 +26,7 @@ using Point = Objects.Geometry.Point; using Text = Objects.Other.Text; using Objects.BuiltElements.Revit; +using Speckle.Core.Logging; namespace Objects.Converter.AutocadCivil; @@ -38,8 +38,7 @@ public Collection LayerToSpeckle(LayerTableRecord layer) var collection = new Collection(layer.Name, "layer") { applicationId = layer.Id.ToString() }; // add dynamic autocad props - var style = new DisplayStyle() { units = Units.Millimeters }; - style.color = layer.Color.ColorValue.ToArgb(); + DisplayStyle style = new() { color = layer.Color.ColorValue.ToArgb(), units = Units.Millimeters }; var linetype = (LinetypeTableRecord)Trans.GetObject(layer.LinetypeObjectId, OpenMode.ForRead); style.linetype = linetype.Name; var lineWeight = @@ -56,87 +55,81 @@ public Collection LayerToSpeckle(LayerTableRecord layer) public ApplicationObject CollectionToNative(Collection collection) { - // get layer table - var layerTable = (LayerTable)Trans.GetObject(Doc.Database.LayerTableId, OpenMode.ForWrite); + var appObj = new ApplicationObject(collection.id, collection.speckle_type) + { + applicationId = collection.applicationId + }; + + ApplicationObject.State status = ApplicationObject.State.Unknown; + LayerTableRecord layer = null; - #region local functions - LayerTableRecord GetLayer(string path) + if (collection["path"] is string layerPath) { - if (layerTable.Has(path)) + // see if this layer already exists in the doc + LayerTableRecord existingLayer = GetLayer(layerPath); + + // update this layer if it exists & receive mode is on update + if (existingLayer != null) { - return (LayerTableRecord)Trans.GetObject(layerTable[path], OpenMode.ForWrite); + if (ReceiveMode == ReceiveMode.Update) + { + layer = existingLayer; + status = ApplicationObject.State.Updated; + } + else + { + layerPath += $" - {DateTime.Now.ToString()}"; + } } - return null; - } - LayerTableRecord MakeLayer(string name) - { - try + // otherwise, create this layer + if (layer == null) { - var _layer = new LayerTableRecord(); - - // Assign the layer properties - _layer.Name = name; - - // Append the new layer to the layer table and the transaction - layerTable.Add(_layer); - Trans.AddNewlyCreatedDBObject(_layer, true); - - return _layer; + if (MakeLayer(layerPath, out layer)) + { + status = ApplicationObject.State.Created; + } + else + { + appObj.Update(status: ApplicationObject.State.Failed, logItem: "Could not create layer"); + return appObj; + } } - catch (Exception e) + + // get attributes + Base styleBase = collection["displayStyle"] is DisplayStyle displayStyle + ? displayStyle + : collection["renderMaterial"] is RenderMaterial renderMaterial + ? renderMaterial + : null; + if (styleBase is not null) { - return null; - } - } - #endregion + DisplayStyleToNative( + styleBase, + out Color color, + out Transparency transparency, + out LineWeight lineWeight, + out ObjectId lineType + ); - var appObj = new ApplicationObject(collection.id, collection.speckle_type) - { - applicationId = collection.applicationId - }; - LayerTableRecord layer = null; - var status = ApplicationObject.State.Unknown; + if (!layer.IsWriteEnabled) + { + layer.UpgradeOpen(); + } - // see if this layer already exists in the doc - var layerPath = collection["path"] as string; - LayerTableRecord existingLayer = GetLayer(layerPath); + layer.Color = color; + layer.Transparency = transparency; + layer.LineWeight = lineWeight; + layer.LinetypeObjectId = lineType; + } - // update this layer if it exists & receive mode is on update - if (existingLayer != null && ReceiveMode == ReceiveMode.Update) - { - layer = existingLayer; - status = ApplicationObject.State.Updated; - } - else // create this layer - { - layer = MakeLayer(layerPath); - status = ApplicationObject.State.Created; + appObj.Update(status: status, convertedItem: layer, createdId: layer.Id.ToString()); } - - if (layer == null) + else { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "Could not create layer"); - return appObj; + appObj.Update(status: ApplicationObject.State.Failed, logItem: "Layer path did not exist on Collection."); } - // get attributes - var displayStyle = collection["displayStyle"] as DisplayStyle; - var renderMaterial = collection["renderMaterial"] as RenderMaterial; - Base styleBase = displayStyle != null ? displayStyle : renderMaterial; - DisplayStyleToNative( - styleBase, - out Color color, - out Transparency transparency, - out LineWeight lineWeight, - out ObjectId lineType - ); - layer.Color = color; - layer.Transparency = transparency; - layer.LineWeight = lineWeight; - layer.LinetypeObjectId = lineType; - - appObj.Update(status: status, convertedItem: layer, createdId: layer.Id.ToString()); return appObj; } @@ -213,6 +206,8 @@ public DisplayStyle DisplayStyleToSpeckle(Entity entity) case ColorMethod.ByColor: color = entity.Color.ColorValue.ToArgb(); break; + default: + break; } style.color = color; @@ -243,14 +238,10 @@ public DisplayStyle DisplayStyleToSpeckle(Entity entity) if (entity.LayerId.IsValid) { var layer = tr.GetObject(entity.LayerId, OpenMode.ForRead) as LayerTableRecord; - if (layer.LineWeight == LineWeight.ByLineWeightDefault || layer.LineWeight == LineWeight.ByBlock) - { - lineWeight = (int)LineWeight.LineWeight025; - } - else - { - lineWeight = (int)layer.LineWeight; - } + lineWeight = + layer.LineWeight == LineWeight.ByLineWeightDefault || layer.LineWeight == LineWeight.ByBlock + ? (int)LineWeight.LineWeight025 + : (int)layer.LineWeight; } tr.Commit(); } @@ -300,10 +291,12 @@ private HatchLoopTypes HatchLoopTypeToNative(HatchLoopType type) public Hatch HatchToSpeckle(AcadDB.Hatch hatch) { - var _hatch = new Hatch(); - _hatch.pattern = hatch.PatternName; - _hatch.scale = hatch.PatternScale; - _hatch.rotation = hatch.PatternAngle; + var _hatch = new Hatch + { + pattern = hatch.PatternName, + scale = hatch.PatternScale, + rotation = hatch.PatternAngle + }; // handle curves var curves = new List(); @@ -367,43 +360,42 @@ public ApplicationObject HatchToNativeDB(Hatch hatch) } } } + if (loops.Count == 0) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "No loops were successfully created"); - return appObj; + throw new ConversionException("No loops were successfully created"); } // add hatch to modelspace - var _hatch = new AcadDB.Hatch(); - modelSpaceRecord.Append(_hatch); + var newHatch = new AcadDB.Hatch(); + modelSpaceRecord.Append(newHatch); - _hatch.SetDatabaseDefaults(); + newHatch.SetDatabaseDefaults(); // try get hatch pattern var patternCategory = HatchPatterns.ValidPatternName(hatch.pattern); switch (patternCategory) { case PatPatternCategory.kCustomdef: - _hatch.SetHatchPattern(HatchPatternType.CustomDefined, hatch.pattern); + newHatch.SetHatchPattern(HatchPatternType.CustomDefined, hatch.pattern); break; case PatPatternCategory.kPredef: case PatPatternCategory.kISOdef: - _hatch.SetHatchPattern(HatchPatternType.PreDefined, hatch.pattern); + newHatch.SetHatchPattern(HatchPatternType.PreDefined, hatch.pattern); break; case PatPatternCategory.kUserdef: - _hatch.SetHatchPattern(HatchPatternType.UserDefined, hatch.pattern); + newHatch.SetHatchPattern(HatchPatternType.UserDefined, hatch.pattern); break; default: - _hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID"); + newHatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID"); break; } - _hatch.PatternAngle = hatch.rotation; - _hatch.PatternScale = hatch.scale; + newHatch.PatternAngle = hatch.rotation; + newHatch.PatternScale = hatch.scale; - var style = hatch["style"] as string; - if (style != null) + if (hatch["style"] is string style) { - _hatch.HatchStyle = Enum.TryParse(style, out HatchStyle hatchStyle) ? hatchStyle : HatchStyle.Normal; + newHatch.HatchStyle = Enum.TryParse(style, out HatchStyle hatchStyle) ? hatchStyle : HatchStyle.Normal; } // create loops @@ -412,23 +404,13 @@ public ApplicationObject HatchToNativeDB(Hatch hatch) var loopHandle = entry.Key.Handle.ToString(); try { - _hatch.AppendLoop(entry.Value, new ObjectIdCollection() { entry.Key.ObjectId }); - _hatch.EvaluateHatch(true); - try - { - entry.Key.Erase(); // delete created hatch loop curve - } - catch (Exception e) - { - appObj.Update( - createdId: loopHandle, - convertedItem: entry.Key, - logItem: $"Could not delete loop {loopHandle}: {e.Message}" - ); - } + newHatch.AppendLoop(entry.Value, new ObjectIdCollection() { entry.Key.ObjectId }); + newHatch.EvaluateHatch(true); + entry.Key.Erase(); // delete created hatch loop curve } - catch (Exception e) + catch (Exception e) when (!e.IsFatal()) { + // A hatch loop failed to create, but potentially can still create the rest of the hatch. appObj.Update( createdId: loopHandle, convertedItem: entry.Key, @@ -450,7 +432,7 @@ private AcadDB.Polyline GetPolylineFromBulgeVertexCollection(BulgeVertexCollecti polyline.AddVertexAt(i, bulgeVertex.Vertex, bulgeVertex.Bulge, 1.0, 1.0); totalBulge += bulgeVertex.Bulge; } - polyline.Closed = bulges[0].Vertex.IsEqualTo(bulges[bulges.Count - 1].Vertex) ? true : false; + polyline.Closed = bulges[0].Vertex.IsEqualTo(bulges[bulges.Count - 1].Vertex); return polyline; } @@ -458,7 +440,7 @@ private AcadDB.Polyline GetPolylineFromBulgeVertexCollection(BulgeVertexCollecti public BlockInstance BlockReferenceToSpeckle(BlockReference reference) { // get record - BlockDefinition definition = null; + BlockDefinition definition; var attributes = new Dictionary(); var btrObjId = reference.BlockTableRecord; @@ -480,7 +462,7 @@ public BlockInstance BlockReferenceToSpeckle(BlockReference reference) if (definition == null) { - return null; + throw new ConversionException("Could not convert definition."); } var instance = new BlockInstance() @@ -491,7 +473,7 @@ public BlockInstance BlockReferenceToSpeckle(BlockReference reference) }; // add attributes - if (attributes.Any()) + if (attributes.Count != 0) { instance["attributes"] = attributes; } @@ -503,46 +485,38 @@ public ApplicationObject InstanceToNativeDB(Instance instance, bool AppendToMode { var appObj = new ApplicationObject(instance.id, instance.speckle_type) { applicationId = instance.applicationId }; - // get the definition + // convert the definition var definition = instance.definition ?? instance["@definition"] as Base ?? instance["@blockDefinition"] as Base; // some applications need to dynamically attach defs (eg sketchup) if (definition == null) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "instance did not have a definition"); - return appObj; + throw new ConversionException("Instance did not have a definition"); } - // delete existing objs if any and this is an update - if (ReceiveMode == ReceiveMode.Update) - { - var existingObjs = GetExistingElementsByApplicationId(instance.applicationId); - try - { - foreach (var existingObjId in existingObjs) - { - var existingObj = Trans.GetObject(existingObjId, OpenMode.ForWrite); - existingObj.Erase(); - } - } - catch (Exception e) - { - if (!e.Message.Contains("eWasErased")) // this couldve been previously deleted & received? - { - appObj.Update(logItem: $"Could not remove one or more existing instances on update: {e.Message}"); - } - } - } - - // convert the definition ObjectId definitionId = DefinitionToNativeDB(definition, out List notes); if (notes.Count > 0) { appObj.Update(log: notes); + Report.UpdateReportObject(appObj); } if (definitionId == ObjectId.Null) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "Could not create block definition"); - return appObj; + throw new ConversionException("Could not convert instance definition."); + } + + // delete existing objs if any and this is an update + if (ReceiveMode == ReceiveMode.Update) + { + List existingObjs = GetExistingElementsByApplicationId(instance.applicationId); + + foreach (ObjectId existingObjId in existingObjs) + { + var existingObj = Trans.GetObject(existingObjId, OpenMode.ForWrite); + if (!existingObj.IsErased) + { + existingObj.Erase(); + } + } } // transform @@ -551,12 +525,10 @@ public ApplicationObject InstanceToNativeDB(Instance instance, bool AppendToMode // add block reference BlockTableRecord modelSpaceRecord = Doc.Database.GetModelSpace(); var insertionPoint = Point3d.Origin.TransformBy(convertedTransform); - BlockReference br = new(insertionPoint, definitionId); - br.BlockTransform = convertedTransform; + BlockReference br = new(insertionPoint, definitionId) { BlockTransform = convertedTransform }; // add attributes if there are any - var attributes = instance["attributes"] as Dictionary; - if (attributes != null) + if (instance["attributes"] is Dictionary attributes) { // TODO: figure out how to add attributes } @@ -568,8 +540,7 @@ public ApplicationObject InstanceToNativeDB(Instance instance, bool AppendToMode if ((!id.IsValid || id.IsNull) && AppendToModelSpace) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "Couldn't append instance to model space"); - return appObj; + throw new ConversionException("Couldn't append instance to model space"); } // update appobj @@ -591,7 +562,7 @@ public BlockDefinition BlockRecordToSpeckle(BlockTableRecord record) { DBObject obj = Trans.GetObject(id, OpenMode.ForRead); Entity objEntity = obj as Entity; - if (CanConvertToSpeckle(obj) && (objEntity != null && objEntity.Visible)) + if (CanConvertToSpeckle(obj) && objEntity != null && objEntity.Visible) { Base converted = ConvertToSpeckle(obj); if (converted != null) @@ -618,11 +589,11 @@ public ObjectId DefinitionToNativeDB(Base definition, out List notes) notes = new List(); // get the definition name - var commitInfo = RemoveInvalidAutocadChars(Doc.UserData["commit"] as string); + var commitInfo = RemoveInvalidChars(Doc.UserData["commit"] as string); string definitionName = definition is BlockDefinition blockDef - ? RemoveInvalidAutocadChars(blockDef.name) + ? RemoveInvalidChars(blockDef.name) : definition is RevitSymbolElementType revitDef - ? RemoveInvalidAutocadChars($"{revitDef.family} - {revitDef.type} - {definition.id}") + ? RemoveInvalidChars($"{revitDef.family} - {revitDef.type} - {definition.id}") : definition.id; if (ReceiveMode == ReceiveMode.Create) { @@ -668,7 +639,7 @@ public ObjectId DefinitionToNativeDB(Base definition, out List notes) } // convert definition geometry and attributes - var bakedGeometry = new ObjectIdCollection(); // this is to contain block def geometry that is already added to doc space during conversion + ObjectIdCollection bakedGeometry = new(); // this is to contain block def geometry that is already added to doc space during conversion var converted = new List(); foreach (var item in conversionDict) @@ -706,7 +677,7 @@ public ObjectId DefinitionToNativeDB(Base definition, out List notes) foreach (var convertedItem in convertedGeo) { - if (!convertedItem.IsNewObject && !(convertedItem is BlockReference)) + if (!convertedItem.IsNewObject && convertedItem is not BlockReference) { bakedGeometry.Add(convertedItem.Id); } @@ -850,7 +821,7 @@ private string GetBlockDefName(BlockTableRecord btr) if (descriptiveProps.Count > 0) { - fullName = $"{fullName}_{String.Join("_", descriptiveProps.ToArray())}"; + fullName = $"{fullName}_{string.Join("_", descriptiveProps.ToArray())}"; } } @@ -859,7 +830,7 @@ private string GetBlockDefName(BlockTableRecord btr) private bool IsSimpleType(object value, out string stringValue) { - stringValue = String.Empty; + stringValue = string.Empty; var type = value.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -916,7 +887,7 @@ void FlattenConvertedObject(object item) } FlattenConvertedObject(convertedGeo); - foreach (Entity entity in convertedList) + foreach (Entity entity in convertedList.Cast()) { if (entity != null) { @@ -942,10 +913,11 @@ out ObjectId lineType // Text public Text TextToSpeckle(DBText text) { - var _text = new Text(); - - // not realistically feasible to extract outline curves for displayvalue currently - _text.height = text.Height; + var _text = new Text + { + // not realistically feasible to extract outline curves for displayvalue currently + height = text.Height + }; var center = GetTextCenter(text); _text.plane = PlaneToSpeckle(new Plane(center, text.Normal)); _text.rotation = text.Rotation; @@ -963,10 +935,11 @@ public Text TextToSpeckle(DBText text) public Text TextToSpeckle(MText text) { - var _text = new Text(); - - // not realistically feasible to extract outline curves for displayvalue currently - _text.height = text.Height == 0 ? text.ActualHeight : text.Height; + var _text = new Text + { + // not realistically feasible to extract outline curves for displayvalue currently + height = text.Height == 0 ? text.ActualHeight : text.Height + }; var center = (text.Bounds != null) ? GetTextCenter(text.Bounds.Value) : text.Location; _text.plane = PlaneToSpeckle(new Plane(center, text.Normal)); _text.rotation = text.Rotation; @@ -985,9 +958,7 @@ public Text TextToSpeckle(MText text) public Entity AcadTextToNative(Text text) { - Entity _text = null; - Base sourceAppProps = text[AutocadPropName] as Base; - if (sourceAppProps == null) + if (text[AutocadPropName] is not Base sourceAppProps) { return TextToNative(text); } @@ -1000,6 +971,7 @@ public Entity AcadTextToNative(Text text) : Doc.Database.Textstyle; string className = sourceAppProps["class"] as string; + Entity _text; switch (className) { case "MText": @@ -1010,13 +982,15 @@ public Entity AcadTextToNative(Text text) _text = mText; break; case "DBText": - var dbText = new DBText(); - dbText.TextString = text.value; - dbText.Height = ScaleToNative(text.height, text.units); - dbText.Position = PointToNative(textPosition); - dbText.Rotation = text.rotation; - dbText.Normal = VectorToNative(text.plane.normal); - dbText.TextStyleId = textStyle; + var dbText = new DBText + { + TextString = text.value, + Height = ScaleToNative(text.height, text.units), + Position = PointToNative(textPosition), + Rotation = text.rotation, + Normal = VectorToNative(text.plane.normal), + TextStyleId = textStyle + }; Utilities.SetApplicationProps(dbText, typeof(DBText), sourceAppProps); _text = dbText; break; @@ -1095,24 +1069,24 @@ private Point3d GetTextCenter(DBText text) case AttachmentPoint.BottomMid: case AttachmentPoint.BottomCenter: x = alignment.X; - y = alignment.Y + (height / 2); + y = alignment.Y + height / 2; break; case AttachmentPoint.TopCenter: case AttachmentPoint.TopMid: x = alignment.X; - y = alignment.Y - (height / 2); + y = alignment.Y - height / 2; break; case AttachmentPoint.MiddleRight: - x = alignment.X - ((alignment.X - position.X) / 2); + x = alignment.X - (alignment.X - position.X) / 2; y = alignment.Y; break; case AttachmentPoint.BottomRight: - x = alignment.X - ((alignment.X - position.X) / 2); - y = alignment.Y + (height / 2); + x = alignment.X - (alignment.X - position.X) / 2; + y = alignment.Y + height / 2; break; case AttachmentPoint.TopRight: - x = alignment.X - ((alignment.X - position.X) / 2); - y = alignment.Y - (height / 2); + x = alignment.X - (alignment.X - position.X) / 2; + y = alignment.Y - height / 2; break; case AttachmentPoint.MiddleCenter: case AttachmentPoint.MiddleMid: @@ -1173,56 +1147,52 @@ public Dimension DimensionToSpeckle(AcadDB.Dimension dimension) _dimension = rotatedDimension; break; case OrdinateDimension o: - var ordinateDimension = new DistanceDimension() + var ordinateDimension = new DistanceDimension { units = ModelUnits, value = dimension.DimensionText, measurement = dimension.Measurement, - isOrdinate = true + isOrdinate = true, + direction = o.UsingXAxis ? VectorToSpeckle(Vector3d.XAxis) : VectorToSpeckle(Vector3d.YAxis), + position = PointToSpeckle(o.LeaderEndPoint), + measured = new List() { PointToSpeckle(o.Origin), PointToSpeckle(o.DefiningPoint) } }; - ordinateDimension.direction = o.UsingXAxis ? VectorToSpeckle(Vector3d.XAxis) : VectorToSpeckle(Vector3d.YAxis); - ordinateDimension.position = PointToSpeckle(o.LeaderEndPoint); - ordinateDimension.measured = new List() { PointToSpeckle(o.Origin), PointToSpeckle(o.DefiningPoint) }; props = Utilities.GetApplicationProps(o, typeof(OrdinateDimension), true, ignore); _dimension = ordinateDimension; break; case RadialDimension o: - var radialDimension = new LengthDimension() + var radialDimension = new LengthDimension { units = ModelUnits, value = dimension.DimensionText, - measurement = dimension.Measurement + measurement = dimension.Measurement, + measured = new Line(PointToSpeckle(o.Center), PointToSpeckle(o.ChordPoint), ModelUnits), + position = PointToSpeckle(o.ChordPoint) // TODO: the position could be improved by using the leader length x the direction of the dimension }; - radialDimension.measured = new Line(PointToSpeckle(o.Center), PointToSpeckle(o.ChordPoint), ModelUnits); - radialDimension.position = PointToSpeckle(o.ChordPoint); // TODO: the position could be improved by using the leader length x the direction of the dimension props = Utilities.GetApplicationProps(o, typeof(RadialDimension), true, ignore); _dimension = radialDimension; break; case DiametricDimension o: - var diametricDimension = new LengthDimension() + var diametricDimension = new LengthDimension { units = ModelUnits, value = dimension.DimensionText, - measurement = dimension.Measurement + measurement = dimension.Measurement, + measured = new Line(PointToSpeckle(o.FarChordPoint), PointToSpeckle(o.ChordPoint), ModelUnits), + position = PointToSpeckle(o.ChordPoint) // TODO: the position could be improved by using the leader length x the direction of the dimension }; - diametricDimension.measured = new Line( - PointToSpeckle(o.FarChordPoint), - PointToSpeckle(o.ChordPoint), - ModelUnits - ); - diametricDimension.position = PointToSpeckle(o.ChordPoint); // TODO: the position could be improved by using the leader length x the direction of the dimension props = Utilities.GetApplicationProps(o, typeof(DiametricDimension), true, ignore); _dimension = diametricDimension; break; case ArcDimension o: - var arcDimension = new LengthDimension() + var arcDimension = new LengthDimension { units = ModelUnits, value = dimension.DimensionText, - measurement = dimension.Measurement + measurement = dimension.Measurement, + measured = ArcToSpeckle(new CircularArc3d(o.XLine1Point, o.ArcPoint, o.XLine2Point)), + position = PointToSpeckle(o.ArcPoint) }; - arcDimension.measured = ArcToSpeckle(new CircularArc3d(o.XLine1Point, o.ArcPoint, o.XLine2Point)); - arcDimension.position = PointToSpeckle(o.ArcPoint); props = Utilities.GetApplicationProps(o, typeof(ArcDimension), true, ignore); _dimension = arcDimension; break; @@ -1266,8 +1236,7 @@ public Dimension DimensionToSpeckle(AcadDB.Dimension dimension) public AcadDB.Dimension AcadDimensionToNative(Dimension dimension) { AcadDB.Dimension _dimension = null; - Base sourceAppProps = dimension[AutocadPropName] as Base; - if (sourceAppProps == null) + if (dimension[AutocadPropName] is not Base sourceAppProps) { return DimensionToNative(dimension); } @@ -1286,110 +1255,94 @@ public AcadDB.Dimension AcadDimensionToNative(Dimension dimension) switch (className) { case "AlignedDimension": - var alignedSpeckle = dimension as DistanceDimension; - if (alignedSpeckle == null || alignedSpeckle.measured.Count < 2) - { - return null; - } - - try + if (dimension is not DistanceDimension alignedSpeckle || alignedSpeckle.measured.Count < 2) { - var alignedStart = PointToNative(alignedSpeckle.measured[0]); - var alignedEnd = PointToNative(alignedSpeckle.measured[1]); - var alignedDimension = new AlignedDimension( - alignedStart, - alignedEnd, - position, - dimension.value, - dimensionStyle + throw new ConversionException( + "Aligned dimension was not a DistanceDimension or measured count was less than 2" ); - Utilities.SetApplicationProps(alignedDimension, typeof(AlignedDimension), sourceAppProps); - _dimension = alignedDimension; } - catch { } - ; + + Point3d alignedStart = PointToNative(alignedSpeckle.measured[0]); + Point3d alignedEnd = PointToNative(alignedSpeckle.measured[1]); + var alignedDimension = new AlignedDimension( + alignedStart, + alignedEnd, + position, + dimension.value, + dimensionStyle + ); + Utilities.SetApplicationProps(alignedDimension, typeof(AlignedDimension), sourceAppProps); + _dimension = alignedDimension; break; case "RotatedDimension": - var rotatedSpeckle = dimension as DistanceDimension; - if (rotatedSpeckle == null || rotatedSpeckle.measured.Count < 2) + if (dimension is not DistanceDimension rotatedSpeckle || rotatedSpeckle.measured.Count < 2) { - return null; + throw new ConversionException( + "Rotated dimension was not a DistanceDimension or measured count was less than 2" + ); } double rotation = sourceAppProps["Rotation"] as double? ?? 0; - try - { - var rotatedStart = PointToNative(rotatedSpeckle.measured[0]); - var rotatedEnd = PointToNative(rotatedSpeckle.measured[1]); - var rotatedDimension = new RotatedDimension( - rotation, - rotatedStart, - rotatedEnd, - position, - dimension.value, - dimensionStyle - ); - Utilities.SetApplicationProps(rotatedDimension, typeof(RotatedDimension), sourceAppProps); - _dimension = rotatedDimension; - } - catch { } + Point3d rotatedStart = PointToNative(rotatedSpeckle.measured[0]); + Point3d rotatedEnd = PointToNative(rotatedSpeckle.measured[1]); + + var rotatedDimension = new RotatedDimension( + rotation, + rotatedStart, + rotatedEnd, + position, + dimension.value, + dimensionStyle + ); + Utilities.SetApplicationProps(rotatedDimension, typeof(RotatedDimension), sourceAppProps); + _dimension = rotatedDimension; + break; case "OrdinateDimension": - try + var ordinateDimension = DimensionToNative(dimension) as OrdinateDimension; + if (ordinateDimension != null) { - var ordinateDimension = DimensionToNative(dimension) as OrdinateDimension; - if (ordinateDimension != null) - { - Utilities.SetApplicationProps(ordinateDimension, typeof(OrdinateDimension), sourceAppProps); - } - - _dimension = ordinateDimension; + Utilities.SetApplicationProps(ordinateDimension, typeof(OrdinateDimension), sourceAppProps); } - catch { } + + _dimension = ordinateDimension; break; case "RadialDimension": - try + var radialDimension = DimensionToNative(dimension) as RadialDimension; + if (radialDimension != null) { - var radialDimension = DimensionToNative(dimension) as RadialDimension; - if (radialDimension != null) - { - Utilities.SetApplicationProps(radialDimension, typeof(RadialDimension), sourceAppProps); - } - - _dimension = radialDimension; + Utilities.SetApplicationProps(radialDimension, typeof(RadialDimension), sourceAppProps); } - catch { } + + _dimension = radialDimension; + break; case "DiametricDimension": - var diametricSpeckle = dimension as LengthDimension; - if (diametricSpeckle == null || diametricSpeckle.measured as Line == null) + if (dimension is not LengthDimension diametricSpeckle || diametricSpeckle.measured as Line == null) { - return null; + throw new ConversionException( + "Diametric dimension was not a LengthDimension or measured value was not a Line" + ); } - try - { - var line = diametricSpeckle.measured as Line; - var start = PointToNative(line.start); - var end = PointToNative(line.end); - double leaderLength = ScaleToNative(sourceAppProps["LeaderLength"] as double? ?? 0, ModelUnits); - var diametricDimension = new DiametricDimension(end, start, leaderLength, dimension.value, dimensionStyle); - sourceAppProps["LeaderLength"] = leaderLength; - Utilities.SetApplicationProps(diametricDimension, typeof(DiametricDimension), sourceAppProps); - _dimension = diametricDimension; - } - catch { } + var line = diametricSpeckle.measured as Line; + Point3d start = PointToNative(line.start); + Point3d end = PointToNative(line.end); + double leaderLength = ScaleToNative(sourceAppProps["LeaderLength"] as double? ?? 0, ModelUnits); + var diametricDimension = new DiametricDimension(end, start, leaderLength, dimension.value, dimensionStyle); + sourceAppProps["LeaderLength"] = leaderLength; + Utilities.SetApplicationProps(diametricDimension, typeof(DiametricDimension), sourceAppProps); + _dimension = diametricDimension; break; case "ArcDimension": - var arcSpeckle = dimension as LengthDimension; - if (arcSpeckle == null || arcSpeckle.measured as Arc == null) + if (dimension is not LengthDimension arcSpeckle || arcSpeckle.measured as Arc == null) { - return null; + throw new ConversionException("Arc dimension was not a LengthDimension or measured value was not an Arc"); } - try + CircularArc3d arc = ArcToNative(arcSpeckle.measured as Arc); + if (arc != null) { - var arc = ArcToNative(arcSpeckle.measured as Arc); var arcDimension = new ArcDimension( arc.Center, arc.StartPoint, @@ -1401,33 +1354,25 @@ public AcadDB.Dimension AcadDimensionToNative(Dimension dimension) Utilities.SetApplicationProps(arcDimension, typeof(ArcDimension), sourceAppProps); _dimension = arcDimension; } - catch { } + break; case "LineAngularDimension2": - try + var lineAngularDimension = DimensionToNative(dimension) as LineAngularDimension2; + if (lineAngularDimension != null) { - var lineAngularDimension = DimensionToNative(dimension) as LineAngularDimension2; - if (lineAngularDimension != null) - { - Utilities.SetApplicationProps(lineAngularDimension, typeof(LineAngularDimension2), sourceAppProps); - } - - _dimension = lineAngularDimension; + Utilities.SetApplicationProps(lineAngularDimension, typeof(LineAngularDimension2), sourceAppProps); } - catch { } + + _dimension = lineAngularDimension; break; case "Point3AngularDimension": - try + var pointAngularDimension = DimensionToNative(dimension) as Point3AngularDimension; + if (pointAngularDimension != null) { - var pointAngularDimension = DimensionToNative(dimension) as Point3AngularDimension; - if (pointAngularDimension != null) - { - Utilities.SetApplicationProps(pointAngularDimension, typeof(Point3AngularDimension), sourceAppProps); - } - - _dimension = pointAngularDimension; + Utilities.SetApplicationProps(pointAngularDimension, typeof(Point3AngularDimension), sourceAppProps); } - catch { } + + _dimension = pointAngularDimension; break; default: _dimension = DimensionToNative(dimension); @@ -1443,110 +1388,91 @@ public AcadDB.Dimension AcadDimensionToNative(Dimension dimension) public AcadDB.Dimension DimensionToNative(Dimension dimension) { - AcadDB.Dimension _dimension = null; + if (dimension.position == null) + { + throw new ConversionException("Position was null"); + } + + AcadDB.Dimension autocadDimension = null; var style = Doc.Database.Dimstyle; - var position = PointToNative(dimension.position); + Point3d position = PointToNative(dimension.position); + string value = dimension.value ?? ""; switch (dimension) { case LengthDimension o: switch (o.measured) { case Arc a: - var arcCenter = PointToNative(a.plane.origin); - var arcStart = PointToNative(a.startPoint); - var arcEnd = PointToNative(a.endPoint); - try + if (a.plane?.origin == null || a.startPoint == null || a.endPoint == null) { - var arcDimension = new ArcDimension(arcCenter, arcStart, arcEnd, position, dimension.value, style); - _dimension = arcDimension; + throw new ConversionException("Arc did not have a plane origin or start point or end point."); } - catch { } + + Point3d arcCenter = PointToNative(a.plane.origin); + Point3d arcStart = PointToNative(a.startPoint); + Point3d arcEnd = PointToNative(a.endPoint); + var arcDimension = new ArcDimension(arcCenter, arcStart, arcEnd, position, value, style); + autocadDimension = arcDimension; break; case Line l: - var radialStart = PointToNative(l.start); - var radialEnd = PointToNative(l.end); + Point3d radialStart = PointToNative(l.start); + Point3d radialEnd = PointToNative(l.end); double leaderLength = radialEnd.DistanceTo(position); - try - { - var radialDimension = new RadialDimension(radialStart, radialEnd, leaderLength, dimension.value, style); - _dimension = radialDimension; - } - catch { } + var radialDimension = new RadialDimension(radialStart, radialEnd, leaderLength, value, style); + autocadDimension = radialDimension; break; } break; case AngleDimension o: - try - { - if (o.measured.Count < 2) - { - break; - } - var line1Start = PointToNative(o.measured[0].start); - var line1End = PointToNative(o.measured[0].end); - var line2Start = PointToNative(o.measured[1].start); - var line2End = PointToNative(o.measured[1].end); - if (Math.Round(line1Start.DistanceTo(line2Start), 3) == 0) - { - _dimension = new Point3AngularDimension(line1Start, line1End, line2End, position, dimension.value, style); - } - else - { - _dimension = new LineAngularDimension2( - line1Start, - line1End, - line2Start, - line2End, - position, - dimension.value, - style - ); - } + if (o.measured.Count < 2) + { + throw new ConversionException("Angle dimension had a measured count of less than 2."); } - catch { } + + Point3d line1Start = PointToNative(o.measured[0].start); + Point3d line1End = PointToNative(o.measured[0].end); + Point3d line2Start = PointToNative(o.measured[1].start); + Point3d line2End = PointToNative(o.measured[1].end); + autocadDimension = + Math.Round(line1Start.DistanceTo(line2Start), 3) == 0 + ? new Point3AngularDimension(line1Start, line1End, line2End, position, value, style) + : new LineAngularDimension2(line1Start, line1End, line2Start, line2End, position, value, style); break; case DistanceDimension o: - if (o.measured.Count < 2) + if (o.measured.Count < 2 || o.direction is null) { - break; + throw new ConversionException("Distance dimension had no direction or a measured count of less than 2."); } - try - { - var start = PointToNative(o.measured[0]); - var end = PointToNative(o.measured[1]); - var normal = VectorToNative(o.direction); + Point3d start = PointToNative(o.measured[0]); + Point3d end = PointToNative(o.measured[1]); + Vector3d normal = VectorToNative(o.direction); - if (o.isOrdinate) - { - bool useXAxis = normal.IsParallelTo(Vector3d.XAxis) ? true : false; - var ordinateDimension = new OrdinateDimension(useXAxis, end, position, dimension.value, style); - ordinateDimension.Origin = start; - _dimension = ordinateDimension; - } - else + if (o.isOrdinate) + { + bool useXAxis = normal.IsParallelTo(Vector3d.XAxis); + var ordinateDimension = new OrdinateDimension(useXAxis, end, position, dimension.value, style) { - var dir = new Vector3d(end.X - start.X, end.Y - start.Y, end.Z - start.Z); // dimension direction - var angleBetween = Math.Round(dir.GetAngleTo(normal), 3); - if (dir.IsParallelTo(normal, Tolerance.Global)) - { - _dimension = new AlignedDimension(start, end, position, dimension.value, style); - } - else - { - _dimension = new RotatedDimension(angleBetween, start, end, position, dimension.value, style); - } - } + Origin = start + }; + autocadDimension = ordinateDimension; } - catch { } + else + { + var dir = new Vector3d(end.X - start.X, end.Y - start.Y, end.Z - start.Z); // dimension direction + var angleBetween = Math.Round(dir.GetAngleTo(normal), 3); + autocadDimension = dir.IsParallelTo(normal, Tolerance.Global) + ? new AlignedDimension(start, end, position, dimension.value, style) + : new RotatedDimension(angleBetween, start, end, position, dimension.value, style); + } + break; default: break; } - //if (_dimension != null) - // _dimension.TextPosition = PointToNative(dimension.textPosition); - return _dimension; + + return autocadDimension; } private ObjectId GetDimensionStyle(string styleName) diff --git a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.cs b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.cs index 525f114df4..1702695a7a 100644 --- a/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.cs +++ b/Objects/Converters/ConverterAutocadCivil/ConverterAutocadCivilShared/ConverterAutocadCivil.cs @@ -2,19 +2,16 @@ using Autodesk.AutoCAD.DatabaseServices; using Objects.BuiltElements; using Objects.Other; -using Objects.Structural.Properties.Profiles; using Speckle.Core.Kits; using Speckle.Core.Models; using System; using System.Collections.Generic; using System.Linq; -using System.Xml; using Acad = Autodesk.AutoCAD; using AcadDB = Autodesk.AutoCAD.DatabaseServices; using Alignment = Objects.BuiltElements.Alignment; using Arc = Objects.Geometry.Arc; using BlockDefinition = Objects.Other.BlockDefinition; -using BlockInstance = Objects.Other.BlockInstance; using Circle = Objects.Geometry.Circle; using Curve = Objects.Geometry.Curve; using Dimension = Objects.Other.Dimension; @@ -27,8 +24,9 @@ using Polycurve = Objects.Geometry.Polycurve; using Polyline = Objects.Geometry.Polyline; using Spiral = Objects.Geometry.Spiral; +using Speckle.Core.Logging; + #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 -using Civil = Autodesk.Civil; using CivilDB = Autodesk.Civil.DatabaseServices; #endif @@ -106,174 +104,189 @@ public Base ConvertToSpeckle(object @object) Base extensionDictionary = null; List notes = new(); - switch (@object) + try { - case DBObject obj: + switch (@object) + { + case DBObject obj: - var appId = obj.ObjectId.ToString(); // TODO: UPDATE THIS WITH STORED APP ID IF IT EXISTS + var appId = obj.ObjectId.ToString(); // TODO: UPDATE THIS WITH STORED APP ID IF IT EXISTS - //Use the Handle object to update progressReport object. - //In an AutoCAD session, you can get the Handle of a DBObject from its ObjectId using the ObjectId.Handle or Handle property. - reportObj = new ApplicationObject(obj.Handle.ToString(), obj.GetType().Name) { applicationId = appId }; - style = DisplayStyleToSpeckle(obj as Entity); // note layer display styles are converted in the layer method - extensionDictionary = obj.GetObjectExtensionDictionaryAsBase(); + //Use the Handle object to update progressReport object. + //In an AutoCAD session, you can get the Handle of a DBObject from its ObjectId using the ObjectId.Handle or Handle property. + reportObj = new ApplicationObject(obj.Handle.ToString(), obj.GetType().Name) { applicationId = appId }; + style = DisplayStyleToSpeckle(obj as Entity); // note layer display styles are converted in the layer method + extensionDictionary = obj.GetObjectExtensionDictionaryAsBase(); - switch (obj) - { - case DBPoint o: - @base = PointToSpeckle(o); - break; - case AcadDB.Line o: - @base = LineToSpeckle(o); - break; - case AcadDB.Arc o: - @base = ArcToSpeckle(o); - break; - case AcadDB.Circle o: - @base = CircleToSpeckle(o); - break; - case AcadDB.Ellipse o: - @base = EllipseToSpeckle(o); - break; - case AcadDB.Hatch o: - @base = HatchToSpeckle(o); - break; - case AcadDB.Spline o: - @base = SplineToSpeckle(o); - break; - case AcadDB.Polyline o: - if (o.IsOnlyLines) // db polylines can have arc segments, decide between polycurve or polyline conversion - { + switch (obj) + { + case DBPoint o: + @base = PointToSpeckle(o); + break; + case AcadDB.Line o: + @base = LineToSpeckle(o); + break; + case AcadDB.Arc o: + @base = ArcToSpeckle(o); + break; + case AcadDB.Circle o: + @base = CircleToSpeckle(o); + break; + case AcadDB.Ellipse o: + @base = EllipseToSpeckle(o); + break; + case AcadDB.Hatch o: + @base = HatchToSpeckle(o); + break; + case AcadDB.Spline o: + @base = SplineToSpeckle(o); + break; + case AcadDB.Polyline o: + @base = o.IsOnlyLines ? PolylineToSpeckle(o) : (Base)PolycurveToSpeckle(o); + + break; + case AcadDB.Polyline3d o: @base = PolylineToSpeckle(o); - } - else - { + break; + case Polyline2d o: @base = PolycurveToSpeckle(o); - } - - break; - case AcadDB.Polyline3d o: - @base = PolylineToSpeckle(o); - break; - case Polyline2d o: - @base = PolycurveToSpeckle(o); - break; - case Region o: - @base = RegionToSpeckle(o, out notes); - break; - case AcadDB.Surface o: - @base = SurfaceToSpeckle(o, out notes); - break; - case PolyFaceMesh o: - @base = MeshToSpeckle(o); - break; - case ProxyEntity o: - @base = ProxyEntityToSpeckle(o); - break; - case SubDMesh o: - @base = MeshToSpeckle(o); - break; - case Solid3d o: - if (o.IsNull) - { - notes.Add($"Solid was null"); - } - else - { - @base = SolidToSpeckle(o, out notes); - } - - break; - case AcadDB.Dimension o: - @base = DimensionToSpeckle(o); - break; - case BlockReference o: - @base = BlockReferenceToSpeckle(o); - break; - case BlockTableRecord o: - @base = BlockRecordToSpeckle(o); - break; - case DBText o: - @base = TextToSpeckle(o); - break; - case MText o: - @base = TextToSpeckle(o); - break; - case LayerTableRecord o: - @base = LayerToSpeckle(o); - break; + break; + case Region o: + @base = RegionToSpeckle(o, out notes); + break; + case AcadDB.Surface o: + @base = SurfaceToSpeckle(o, out notes); + break; + case PolyFaceMesh o: + @base = MeshToSpeckle(o); + break; + case ProxyEntity o: + @base = ProxyEntityToSpeckle(o); + break; + case SubDMesh o: + @base = MeshToSpeckle(o); + break; + case Solid3d o: + if (o.IsNull) + { + notes.Add($"Solid was null"); + } + else + { + @base = SolidToSpeckle(o, out notes); + } + + break; + case AcadDB.Dimension o: + @base = DimensionToSpeckle(o); + break; + case BlockReference o: + @base = BlockReferenceToSpeckle(o); + break; + case BlockTableRecord o: + @base = BlockRecordToSpeckle(o); + break; + case DBText o: + @base = TextToSpeckle(o); + break; + case MText o: + @base = TextToSpeckle(o); + break; + case LayerTableRecord o: + @base = LayerToSpeckle(o); + break; #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 - case CivilDB.Alignment o: - @base = AlignmentToSpeckle(o); - break; - case CivilDB.Corridor o: - @base = CorridorToSpeckle(o); - break; - case CivilDB.FeatureLine o: - @base = FeatureLineToSpeckle(o); - break; - case CivilDB.Structure o: - @base = StructureToSpeckle(o); - break; - case CivilDB.Pipe o: - @base = PipeToSpeckle(o); - break; - case CivilDB.PressurePipe o: - @base = PipeToSpeckle(o); - break; - case CivilDB.Profile o: - @base = ProfileToSpeckle(o); - break; - case CivilDB.TinSurface o: - @base = SurfaceToSpeckle(o); - break; - -#elif ADVANCESTEEL - - default: - try - { - @base = ConvertASToSpeckle(obj, reportObj, notes); - } - catch (Exception ex) - { - //Update report because AS object type - Report.UpdateReportObject(reportObj); - throw; - } - - break; + case CivilDB.Alignment o: + @base = AlignmentToSpeckle(o); + break; + case CivilDB.Corridor o: + @base = CorridorToSpeckle(o); + break; + case CivilDB.FeatureLine o: + @base = FeatureLineToSpeckle(o); + break; + case CivilDB.Structure o: + @base = StructureToSpeckle(o); + break; + case CivilDB.Pipe o: + @base = PipeToSpeckle(o); + break; + case CivilDB.PressurePipe o: + @base = PipeToSpeckle(o); + break; + case CivilDB.Profile o: + @base = ProfileToSpeckle(o); + break; + case CivilDB.TinSurface o: + @base = SurfaceToSpeckle(o); + break; #endif - } - break; - case Acad.Geometry.Point3d o: - @base = PointToSpeckle(o); - break; - case Acad.Geometry.Vector3d o: - @base = VectorToSpeckle(o); - break; - case Acad.Geometry.Line3d o: - @base = LineToSpeckle(o); - break; - case Acad.Geometry.LineSegment3d o: - @base = LineToSpeckle(o); - break; - case Acad.Geometry.CircularArc3d o: - @base = ArcToSpeckle(o); - break; - case Acad.Geometry.Plane o: - @base = PlaneToSpeckle(o); - break; - case Acad.Geometry.Curve3d o: - @base = CurveToSpeckle(o) as Base; - break; - default: - if (reportObj != null) - { - reportObj.Update(status: ApplicationObject.State.Skipped, logItem: $"{@object.GetType()} type not supported"); - Report.UpdateReportObject(reportObj); - } - return @base; + default: +#if ADVANCESTEEL + try + { + @base = ConvertASToSpeckle(obj, reportObj, notes); + } + catch (Exception e) when (!e.IsFatal()) + { + //Update report because AS object type + Report.UpdateReportObject(reportObj); + throw; + } + break; +#else + throw new ConversionNotSupportedException( + $"AutocadCivil3D object of type {@object.GetType()} is not supported for conversion." + ); +#endif + } + break; + case Acad.Geometry.Point3d o: + @base = PointToSpeckle(o); + break; + case Acad.Geometry.Vector3d o: + @base = VectorToSpeckle(o); + break; + case Acad.Geometry.Line3d o: + @base = LineToSpeckle(o); + break; + case Acad.Geometry.LineSegment3d o: + @base = LineToSpeckle(o); + break; + case Acad.Geometry.CircularArc3d o: + @base = ArcToSpeckle(o); + break; + case Acad.Geometry.Plane o: + @base = PlaneToSpeckle(o); + break; + case Acad.Geometry.Curve3d o: + @base = CurveToSpeckle(o) as Base; + break; + default: + throw new ConversionNotSupportedException( + $"AutocadCivil object of type {@object.GetType()} is not supported for conversion." + ); + } + } + catch (ConversionNotSupportedException e) + { + SpeckleLog.Logger.Information(e, "{exceptionMessage}"); + reportObj?.Update(status: ApplicationObject.State.Skipped, logItem: e.Message); + } + catch (SpeckleException e) + { + SpeckleLog.Logger.Warning(e, "{exceptionMessage}"); + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); + } + catch (Exception e) when (!e.IsFatal()) + { + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); } if (@base is null) @@ -306,151 +319,152 @@ private Base ObjectToSpeckleBuiltElement(DBObject o) public List ConvertToSpeckle(List objects) { - return objects.Select(x => ConvertToSpeckle(x)).ToList(); + return objects.Select(ConvertToSpeckle).ToList(); } public object ConvertToNative(Base @object) { // determine if this object has autocad props - bool isFromAutoCAD = @object[AutocadPropName] != null ? true : false; - bool isFromCivil = @object[CivilPropName] != null ? true : false; + bool isFromAutoCAD = @object[AutocadPropName] != null; + bool isFromCivil = @object[CivilPropName] != null; object acadObj = null; var reportObj = Report.ReportObjects.ContainsKey(@object.id) ? new ApplicationObject(@object.id, @object.speckle_type) : null; List notes = new(); - switch (@object) + try { - case Point o: - acadObj = PointToNativeDB(o); - break; + switch (@object) + { + case Point o: + acadObj = PointToNativeDB(o); + break; - case Line o: - acadObj = LineToNativeDB(o); - break; + case Line o: + acadObj = LineToNativeDB(o); + break; - case Arc o: - acadObj = ArcToNativeDB(o); - break; + case Arc o: + acadObj = ArcToNativeDB(o); + break; - case Circle o: - acadObj = CircleToNativeDB(o); - break; + case Circle o: + acadObj = CircleToNativeDB(o); + break; - case Ellipse o: - acadObj = EllipseToNativeDB(o); - break; + case Ellipse o: + acadObj = EllipseToNativeDB(o); + break; - case Spiral o: - acadObj = PolylineToNativeDB(o.displayValue); - break; + case Spiral o: + acadObj = PolylineToNativeDB(o.displayValue); + break; - case Hatch o: - acadObj = HatchToNativeDB(o); - break; + case Hatch o: + acadObj = HatchToNativeDB(o); + break; - case Polyline o: - acadObj = PolylineToNativeDB(o); - break; + case Polyline o: + acadObj = PolylineToNativeDB(o); + break; - case Polycurve o: - bool convertAsSpline = (o.segments.Where(s => !(s is Line) && !(s is Arc)).Count() > 0) ? true : false; - if (convertAsSpline || !IsPolycurvePlanar(o)) - { - acadObj = PolycurveSplineToNativeDB(o); - } - else - { - acadObj = PolycurveToNativeDB(o); - } - - break; - - case Curve o: - acadObj = CurveToNativeDB(o); - break; + case Polycurve o: + bool convertAsSpline = o.segments.Any(s => s is not Line and not Arc); + acadObj = convertAsSpline || !IsPolycurvePlanar(o) ? PolycurveSplineToNativeDB(o) : PolycurveToNativeDB(o); - /* - case Surface o: - return SurfaceToNative(o); + break; - */ + case Curve o: + acadObj = CurveToNativeDB(o); + break; - case Mesh o: + case Mesh o: #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 - acadObj = isFromCivil ? CivilSurfaceToNative(o) : MeshToNativeDB(o); + acadObj = isFromCivil ? CivilSurfaceToNative(o) : MeshToNativeDB(o); #else - acadObj = MeshToNativeDB(o); + acadObj = MeshToNativeDB(o); #endif - break; + break; - case Dimension o: - acadObj = isFromAutoCAD ? AcadDimensionToNative(o) : DimensionToNative(o); - break; + case Dimension o: + acadObj = isFromAutoCAD ? AcadDimensionToNative(o) : DimensionToNative(o); + break; - case Instance o: - acadObj = InstanceToNativeDB(o); - break; + case Instance o: + acadObj = InstanceToNativeDB(o); + break; - case BlockDefinition o: - acadObj = DefinitionToNativeDB(o, out notes); - break; + case BlockDefinition o: + acadObj = DefinitionToNativeDB(o, out notes); + break; - case Text o: - acadObj = isFromAutoCAD ? AcadTextToNative(o) : TextToNative(o); - break; + case Text o: + acadObj = isFromAutoCAD ? AcadTextToNative(o) : TextToNative(o); + break; - case Collection o: - acadObj = CollectionToNative(o); - break; + case Collection o: + acadObj = CollectionToNative(o); + break; #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 - case Alignment o: - acadObj = AlignmentToNative(o); - break; + case Alignment o: + acadObj = AlignmentToNative(o); + break; #endif - case ModelCurve o: - acadObj = CurveToNativeDB(o.baseCurve); - break; + case ModelCurve o: + acadObj = CurveToNativeDB(o.baseCurve); + break; - case GridLine o: - acadObj = CurveToNativeDB(o.baseLine); - break; + case GridLine o: + acadObj = CurveToNativeDB(o.baseLine); + break; - default: - if (reportObj != null) - { - reportObj.Update(status: ApplicationObject.State.Skipped, logItem: $"{@object.GetType()} type not supported"); - Report.UpdateReportObject(reportObj); - } - throw new NotSupportedException(); + default: + throw new ConversionNotSupportedException( + $"Speckle object of type {@object.GetType()} is not supported for conversion." + ); + } + } + catch (ConversionNotSupportedException e) + { + SpeckleLog.Logger.Information(e, "{exceptionMessage}"); + reportObj?.Update(status: ApplicationObject.State.Skipped, logItem: e.Message); + } + catch (SpeckleException e) + { + SpeckleLog.Logger.Warning(e, "{exceptionMessage}"); + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); + } + catch (Exception e) when (!e.IsFatal()) + { + SpeckleLog.Logger.Error(e, $"{@object.GetType()} unhandled conversion error"); + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); } switch (acadObj) { case ApplicationObject o: // some to native methods return an application object (if object is baked to doc during conv) - acadObj = o.Converted.Any() ? o.Converted : null; - if (reportObj != null) - { - reportObj.Update( - status: o.Status, - createdIds: o.CreatedIds, - converted: o.Converted, - container: o.Container, - log: o.Log - ); - } - + acadObj = o.Converted.Count != 0 ? o.Converted : null; + reportObj?.Update( + status: o.Status, + createdIds: o.CreatedIds, + converted: o.Converted, + container: o.Container, + log: o.Log + ); break; default: - if (reportObj != null) - { - reportObj.Update(log: notes); - } - + reportObj?.Update(log: notes); break; } + if (reportObj != null) { Report.UpdateReportObject(reportObj); @@ -466,7 +480,7 @@ public object ConvertToNativeDisplayable(Base @object) public List ConvertToNative(List objects) { - return objects.Select(x => ConvertToNative(x)).ToList(); + return objects.Select(ConvertToNative).ToList(); } public bool CanConvertToSpeckle(object @object) @@ -476,42 +490,42 @@ public bool CanConvertToSpeckle(object @object) case DBObject o: switch (o) { - case DBPoint _: - case AcadDB.Line _: - case AcadDB.Arc _: - case AcadDB.Circle _: - case AcadDB.Dimension _: - case AcadDB.Ellipse _: - case AcadDB.Hatch _: - case AcadDB.Spline _: - case AcadDB.Polyline _: - case AcadDB.Polyline2d _: - case AcadDB.Polyline3d _: - case AcadDB.Surface _: - case AcadDB.PolyFaceMesh _: - case AcadDB.ProxyEntity _: - case AcadDB.Region _: - case SubDMesh _: - case Solid3d _: + case DBPoint: + case AcadDB.Line: + case AcadDB.Arc: + case AcadDB.Circle: + case AcadDB.Dimension: + case AcadDB.Ellipse: + case AcadDB.Hatch: + case AcadDB.Spline: + case AcadDB.Polyline: + case Polyline2d: + case Polyline3d: + case AcadDB.Surface: + case PolyFaceMesh: + case ProxyEntity: + case AcadDB.Region: + case SubDMesh: + case Solid3d: return true; - case BlockReference _: - case BlockTableRecord _: - case AcadDB.DBText _: - case AcadDB.MText _: - case LayerTableRecord _: + case BlockReference: + case BlockTableRecord: + case DBText: + case MText: + case LayerTableRecord: return true; #if CIVIL2021 || CIVIL2022 || CIVIL2023 || CIVIL2024 // NOTE: C3D pressure pipes and pressure fittings API under development - case CivilDB.FeatureLine _: - case CivilDB.Corridor _: - case CivilDB.Structure _: - case CivilDB.Alignment _: - case CivilDB.Pipe _: - case CivilDB.PressurePipe _: - case CivilDB.Profile _: - case CivilDB.TinSurface _: + case CivilDB.FeatureLine: + case CivilDB.Corridor: + case CivilDB.Structure: + case CivilDB.Alignment: + case CivilDB.Pipe: + case CivilDB.PressurePipe: + case CivilDB.Profile: + case CivilDB.TinSurface: return true; #endif @@ -525,13 +539,13 @@ public bool CanConvertToSpeckle(object @object) } } - case Acad.Geometry.Point3d _: - case Acad.Geometry.Vector3d _: - case Acad.Geometry.Plane _: - case Acad.Geometry.Line3d _: - case Acad.Geometry.LineSegment3d _: - case Acad.Geometry.CircularArc3d _: - case Acad.Geometry.Curve3d _: + case Acad.Geometry.Point3d: + case Acad.Geometry.Vector3d: + case Acad.Geometry.Plane: + case Acad.Geometry.Line3d: + case Acad.Geometry.LineSegment3d: + case Acad.Geometry.CircularArc3d: + case Acad.Geometry.Curve3d: return true; default: @@ -543,27 +557,27 @@ public bool CanConvertToNative(Base @object) { switch (@object) { - case Point _: - case Line _: - case Arc _: - case Circle _: - case Ellipse _: - case Spiral _: - case Hatch _: - case Polyline _: - case Polycurve _: - case Curve _: - case Mesh _: - - case Dimension _: - case BlockDefinition _: - case Instance _: - case Text _: - case Collection _: - - case Alignment _: - case ModelCurve _: - case GridLine _: + case Point: + case Line: + case Arc: + case Circle: + case Ellipse: + case Spiral: + case Hatch: + case Polyline: + case Polycurve: + case Curve: + case Mesh: + + case Dimension: + case BlockDefinition: + case Instance: + case Text: + case Collection: + + case Alignment: + case ModelCurve: + case GridLine: return true; default: diff --git a/Objects/Converters/ConverterBentley/ConverterBentleyShared/ConverterBentley.Civil.cs b/Objects/Converters/ConverterBentley/ConverterBentleyShared/ConverterBentley.Civil.cs index ec10ccaf18..e7f345d44e 100644 --- a/Objects/Converters/ConverterBentley/ConverterBentleyShared/ConverterBentley.Civil.cs +++ b/Objects/Converters/ConverterBentley/ConverterBentleyShared/ConverterBentley.Civil.cs @@ -129,25 +129,21 @@ public CifGM.Alignment AlignmentToNative(Alignment alignment) { ICurve singleBaseCurve; - if (alignment.baseCurve is ICurve basecurve) + if (alignment.curves?.Count > 0) { - singleBaseCurve = basecurve; - } - else if (alignment?.curves?.Any() is null) - { - return null; + //Not 100% clear on how best to handle the conversion between multiple curves and single element + singleBaseCurve = alignment.curves.Count == 1 ? alignment.curves.Single() : new Polycurve() + { + segments = alignment.curves + }; } - else if (alignment.curves?.Count == 1) + else if (alignment.baseCurve is not null) // this could be an old alignment using a basecurve { - singleBaseCurve = alignment.curves.Single(); + singleBaseCurve = alignment.baseCurve; } else { - //Not 100% clear on how best to handle the conversion between multiple curves and single element - singleBaseCurve = new Polycurve() - { - segments = alignment.curves - }; + throw new ArgumentException("Alignment had no usable curves or basecurve"); } var nativeCurve = CurveToNative(singleBaseCurve); diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/AnalysisResultUtils.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/AnalysisResultUtils.cs index 56ee1d39f4..2539d5e76f 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/AnalysisResultUtils.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/AnalysisResultUtils.cs @@ -1,4 +1,3 @@ -using ConverterCSIShared.Extensions; using ConverterCSIShared.Models; using CSiAPIv1; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Constants.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Constants.cs index 33a9c2aa1e..cad8f982f1 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Constants.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Constants.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.AspNetCore.Http; - namespace ConverterCSIShared; internal static class Constants diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSI.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSI.cs index 7ba85f50e6..d6b06e1bd2 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSI.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSI.cs @@ -12,7 +12,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Objects.Other; using Objects.Structural.Materials; using OSG = Objects.Structural.Geometry; using Speckle.Core.Kits.ConverterInterfaces; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSIUtils.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSIUtils.cs index 6677f74f6e..e9a33a27dc 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSIUtils.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/ConverterCSIUtils.cs @@ -3,6 +3,7 @@ using CSiAPIv1; using Objects.Structural.CSI.Analysis; using System.Linq; +using System; namespace Objects.Converter.CSI; @@ -44,16 +45,10 @@ public double ScaleToNative(double value, string units) public static List GetAllFrameNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.FrameObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.FrameObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetColumnNames(cSapModel model) @@ -125,16 +120,10 @@ public static List GetBraceNames(cSapModel model) public static List GetAllAreaNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.AreaObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.AreaObj.GetNameList(ref num, ref names); + return names.ToList(); } public static List GetAllWallNames(cSapModel model) @@ -344,16 +333,10 @@ public Restraint RestraintToSpeckle(bool[] releases) public static List GetAllPointNames(cSapModel model) { int num = 0; - var names = new string[] { }; - try - { - model.PointObj.GetNameList(ref num, ref names); - return names.ToList(); - } - catch - { - return null; - } + var names = Array.Empty(); + + model.PointObj.GetNameList(ref num, ref names); + return names.ToList(); } public enum CSIConverterSupported diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ArcExtensions.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ArcExtensions.cs index 76a89b6b10..60f71ff561 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ArcExtensions.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ArcExtensions.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Net; using System.Numerics; -using System.Text; using Objects.Geometry; namespace ConverterCSIShared.Extensions; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/CurveExtensions.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/CurveExtensions.cs index 60d4d2db89..ffab8c6d01 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/CurveExtensions.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/CurveExtensions.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; using Objects.Geometry; namespace ConverterCSIShared.Extensions; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ICurveExtensions.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ICurveExtensions.cs index f1e555b36a..6356305db9 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ICurveExtensions.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/ICurveExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using Objects.Geometry; using Objects; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/LineExtensions.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/LineExtensions.cs index eaf1e12591..9bf842a058 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/LineExtensions.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Extensions/LineExtensions.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; using Objects.Geometry; namespace ConverterCSIShared.Extensions; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element1DAnalyticalResultConverter.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element1DAnalyticalResultConverter.cs index d718aa6524..5c120422cc 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element1DAnalyticalResultConverter.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element1DAnalyticalResultConverter.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using ConverterCSIShared.Extensions; using CSiAPIv1; using Objects.Structural.Geometry; using Objects.Structural.Loading; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element2DAnalyticalResultConverter.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element2DAnalyticalResultConverter.cs index d7865ab1d7..260230a3b6 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element2DAnalyticalResultConverter.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/Models/Element2DAnalyticalResultConverter.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using ConverterCSIShared.Extensions; using CSiAPIv1; using Objects.Structural.Loading; using Objects.Structural.Results; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModel.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModel.cs index 5179a1f7a6..9bbcc9109f 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModel.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModel.cs @@ -1,20 +1,7 @@ -using System; using System.Collections.Generic; using Objects.Structural.Analysis; -using Objects.Geometry; -using Objects.Structural.Properties; -using Objects.Structural.Geometry; -using Objects.Structural.Materials; -using Objects.Structural.CSI.Properties; -using Objects.Structural.GSA.Properties; -using Objects.Structural.GSA.Geometry; -using Objects.Structural.Loading; -using Objects.Structural.CSI.Loading; using Speckle.Core.Models; -using Objects.Structural.CSI.Geometry; -using Objects.Structural.CSI.Analysis; using System.Linq; -using CSiAPIv1; namespace Objects.Converter.CSI; @@ -45,7 +32,7 @@ public Model ModelToSpeckle() model.restraints = new List { }; model.loads = new List { }; int number = 0; - string[] properties1D = { }; + string[] properties1D = System.Array.Empty(); //var stories = StoriesToSpeckle(); ////Should stories belong here ? not sure @@ -54,69 +41,61 @@ public Model ModelToSpeckle() //Properties are sent by default whether you want them to be sent or not. Easier this way to manage information about the model Model.PropFrame.GetNameList(ref number, ref properties1D); - properties1D.ToList(); foreach (string property1D in properties1D) { var speckleProperty1D = Property1DToSpeckle(property1D); model.properties.Add(speckleProperty1D); } - string[] springPointProperties = { }; + string[] springPointProperties = System.Array.Empty(); Model.PropPointSpring.GetNameList(ref number, ref springPointProperties); - springPointProperties.ToList(); foreach (string propertySpring in springPointProperties) { var specklePropertyPointSpring = SpringPropertyToSpeckle(propertySpring); model.properties.Add(specklePropertyPointSpring); } - string[] springLineProperties = { }; + string[] springLineProperties = System.Array.Empty(); Model.PropLineSpring.GetNameList(ref number, ref springLineProperties); - springLineProperties.ToList(); foreach (string propertyLine in springLineProperties) { var specklePropertyLineSpring = LinearSpringToSpeckle(propertyLine); model.properties.Add(specklePropertyLineSpring); } - string[] springAreaProperties = { }; + string[] springAreaProperties = System.Array.Empty(); Model.PropAreaSpring.GetNameList(ref number, ref springAreaProperties); - springAreaProperties.ToList(); foreach (string propertyArea in springAreaProperties) { var specklePropertyAreaSpring = AreaSpringToSpeckle(propertyArea); model.properties.Add(specklePropertyAreaSpring); } - string[] LinkProperties = { }; + string[] LinkProperties = System.Array.Empty(); Model.PropLink.GetNameList(ref number, ref LinkProperties); - LinkProperties.ToList(); foreach (string propertyLink in LinkProperties) { var specklePropertyLink = LinkPropertyToSpeckle(propertyLink); model.properties.Add(specklePropertyLink); } - string[] TendonProperties = { }; + string[] TendonProperties = System.Array.Empty(); Model.PropTendon.GetNameList(ref number, ref TendonProperties); - TendonProperties.ToList(); foreach (string propertyTendon in TendonProperties) { var specklePropertyTendon = TendonPropToSpeckle(propertyTendon); model.properties.Add(specklePropertyTendon); } - string[] DiaphragmProperties = { }; + string[] DiaphragmProperties = System.Array.Empty(); Model.Diaphragm.GetNameList(ref number, ref DiaphragmProperties); - DiaphragmProperties.ToList(); foreach (string propertyDiaphragm in DiaphragmProperties) { var specklePropertyDiaphragm = diaphragmToSpeckle(propertyDiaphragm); model.properties.Add(specklePropertyDiaphragm); } - string[] properties2D = { }; + string[] properties2D = System.Array.Empty(); Model.PropArea.GetNameList(ref number, ref properties2D); - properties2D.ToList(); foreach (string property in properties2D) { var speckleProperty2D = FloorPropertyToSpeckle(property); @@ -130,7 +109,7 @@ public Model ModelToSpeckle() } } - string[] materials = { }; + string[] materials = System.Array.Empty(); Model.PropMaterial.GetNameList(ref number, ref materials); foreach (string material in materials) { diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelInfo.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelInfo.cs index 1065edd2b9..ae2ebd32b2 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelInfo.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelInfo.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using Objects.Geometry; -using Objects.Structural.Geometry; using Objects.Structural.Analysis; -using CSiAPIv1; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelSettings.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelSettings.cs index 1bbda6dd72..3a97e1d4bf 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelSettings.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelSettings.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; using Objects.Structural.Analysis; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelUnits.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelUnits.cs index b1ef3da5c1..550bff8e2e 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelUnits.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Analysis/ConvertModelUnits.cs @@ -1,8 +1,4 @@ using Objects.Structural.Analysis; -using System; -using System.Collections.Generic; -using System.Text; -using Objects.Structural.Analysis; using CSiAPIv1; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertArea.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertArea.cs index ffab03b0f5..c53f8b3721 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertArea.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertArea.cs @@ -228,12 +228,14 @@ public void AreaToNative(Element2D area, ApplicationObject appObj) foreach (var opening in area.openings) { string openingName; + List openingPoints = opening.ToPoints().ToList(); try { - openingName = CreateAreaFromPoints(opening.ToPoints(), propName); + openingName = CreateAreaFromPoints(openingPoints, propName); } - catch (Exception) + catch (ConversionException ex) { + SpeckleLog.Logger.Error(ex, "Failed to create opening with {numPoints} points", openingPoints.Count); openingName = string.Empty; } @@ -321,8 +323,9 @@ private string CreateAreaFromPoints(IEnumerable points, string propName) { return Property2DToNative(prop2D); } - catch (Exception) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "Unable to create property2d"); // something failed... replace the type } } diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertBraces.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertBraces.cs index 9e51c24ff7..71a6df379e 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertBraces.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertBraces.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using Objects.Geometry; using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using CSiAPIv1; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertColumn.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertColumn.cs index effbb18fc7..5d5536566d 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertColumn.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertColumn.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using Objects.Geometry; using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using CSiAPIv1; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFloor.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFloor.cs index 6fae1c4947..b4c59c9a1a 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFloor.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFloor.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using CSiAPIv1; using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Objects.Structural.CSI.Properties; -using System.Linq; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFrame.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFrame.cs index 8a423fe917..437e01d621 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFrame.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertFrame.cs @@ -305,7 +305,7 @@ public CSIElement1D FrameToSpeckle(string name) break; } } - double[] modifiers = new double[] { }; + double[] modifiers = Array.Empty(); int s = Model.FrameObj.GetModifiers(name, ref modifiers); if (s == 0) { diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertLine.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertLine.cs index 90ff0d7b5d..8a6b76d1de 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertLine.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertLine.cs @@ -1,11 +1,5 @@ -using System; -using System.Collections.Generic; using Objects.Geometry; using Speckle.Core.Kits; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using CSiAPIv1; -using Speckle.Core.Models; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertPier.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertPier.cs index 8210206720..95b03a926c 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertPier.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertPier.cs @@ -1,14 +1,4 @@ -using System; -using Objects.Structural.Geometry; -using Objects.Geometry; -using Objects.Structural.Analysis; -using System.Collections.Generic; using Objects.Structural.CSI.Geometry; -using Objects.Structural.CSI.Properties; -using Speckle.Core.Models; - -using CSiAPIv1; -using System.Linq; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertSpandrel.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertSpandrel.cs index 45bf5b8d20..0121f7b32d 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertSpandrel.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertSpandrel.cs @@ -1,14 +1,4 @@ -using System; -using Objects.Structural.Geometry; -using Objects.Geometry; -using Objects.Structural.Analysis; -using System.Collections.Generic; using Objects.Structural.CSI.Geometry; -using Objects.Structural.CSI.Properties; -using Speckle.Core.Models; - -using CSiAPIv1; -using System.Linq; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertTendon.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertTendon.cs index a9ef987736..8804a6bd0c 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertTendon.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Geometry/ConvertTendon.cs @@ -1,13 +1,6 @@ using System; -using System.Collections.Generic; -using System.Text; -using CSiAPIv1; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Objects.Structural.CSI.Properties; using Objects.Structural.CSI.Geometry; using Objects.Geometry; -using System.Linq; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Loading/ConvertLoadCombination.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Loading/ConvertLoadCombination.cs index b48e659980..ea2e93ec72 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Loading/ConvertLoadCombination.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Loading/ConvertLoadCombination.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using ConverterCSIShared.Models; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Materials/ConvertMaterials.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Materials/ConvertMaterials.cs index bdf7a82ff4..fd182e964e 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Materials/ConvertMaterials.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Materials/ConvertMaterials.cs @@ -10,7 +10,7 @@ public string MaterialToNative(StructuralMaterial? material) { material = material ?? new StructuralMaterial("undefined", Structural.MaterialType.Other, null, null, null); int numbMaterial = 0; - string[] materials = new string[] { }; + string[] materials = System.Array.Empty(); Model.PropMaterial.GetNameList(ref numbMaterial, ref materials); if (materials.Contains(material.name)) diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert1DProperty.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert1DProperty.cs index 9e9ebd1b1f..b61452a353 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert1DProperty.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert1DProperty.cs @@ -5,6 +5,7 @@ using Objects.Structural.Properties.Profiles; using System.Linq; using Speckle.Core.Kits; +using Speckle.Core.Logging; namespace Objects.Converter.CSI; @@ -40,8 +41,9 @@ public bool Property1DExists(string? name) parentLog?.Add(ex.Message); return property1D.name; } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.Error(ex, "Failed to convert property {propertyName}", property1D.name); parentLog?.Add($"Failed to convert property {property1D.name}: {ex.Message}"); return null; } diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DProperty.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DProperty.cs index b759b6419f..7a34d510f3 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DProperty.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DProperty.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; using CSiAPIv1; -using Objects.Structural.Properties; -using Objects.Structural.Materials; using Objects.Structural.CSI.Analysis; using Objects.Structural.CSI.Properties; -using Speckle.Core.Models; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DPropertyWall.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DPropertyWall.cs index fee5a3ca12..d471b05ab8 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DPropertyWall.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/Convert2DPropertyWall.cs @@ -1,8 +1,6 @@ -using System; using CSiAPIv1; using Objects.Structural.CSI.Properties; using Speckle.Core.Kits; -using Speckle.Core.Models; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertDiaphragm.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertDiaphragm.cs index d918abbe9e..c76c7cf260 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertDiaphragm.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertDiaphragm.cs @@ -1,17 +1,6 @@ using Objects.Structural.CSI.Properties; using Speckle.Core.Kits; -using System; -using System.Collections.Generic; -using System.Text; -using CSiAPIv1; -using Objects.Structural.Properties; -using Objects.Structural.Materials; -using Objects.Structural.CSI.Analysis; -using Objects.Structural.CSI.Properties; -using Speckle.Core.Models; -using Objects.Structural.Geometry; - namespace Objects.Converter.CSI; public partial class ConverterCSI diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertSectionProfile.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertSectionProfile.cs index 08a9e0d591..74642f6c6d 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertSectionProfile.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertSectionProfile.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections.Generic; using Objects.Structural.Properties.Profiles; using CSiAPIv1; using System.Linq; diff --git a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertTendonProperty.cs b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertTendonProperty.cs index e3d3b88c96..7f9699c51d 100644 --- a/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertTendonProperty.cs +++ b/Objects/Converters/ConverterCSI/ConverterCSIShared/PartialClasses/Properties/ConvertTendonProperty.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using Objects.Structural.Properties.Profiles; -using CSiAPIv1; -using System.Linq; using Objects.Structural.CSI.Properties; -using Objects.Structural.Properties; namespace Objects.Converter.CSI; diff --git a/Objects/Converters/ConverterDxf/ConverterDxf/SpeckleDxfConverter.Geometry.cs b/Objects/Converters/ConverterDxf/ConverterDxf/SpeckleDxfConverter.Geometry.cs index a775e57727..3f5216366b 100644 --- a/Objects/Converters/ConverterDxf/ConverterDxf/SpeckleDxfConverter.Geometry.cs +++ b/Objects/Converters/ConverterDxf/ConverterDxf/SpeckleDxfConverter.Geometry.cs @@ -3,9 +3,6 @@ using System.Linq; using Objects.Geometry; using Objects.Other; -using Speckle.Core.Kits; -using Speckle.Core.Logging; -using Speckle.netDxf.Units; using Dxf = Speckle.netDxf; using Dxfe = Speckle.netDxf.Entities; using Line = Objects.Geometry.Line; diff --git a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Geometry.cs b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Geometry.cs index e97c24482d..77d50ca988 100644 --- a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Geometry.cs +++ b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Geometry.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; using Autodesk.DesignScript.Geometry; using Objects.Geometry; using Speckle.Core.Models; @@ -16,7 +15,6 @@ using Ellipse = Objects.Geometry.Ellipse; using Curve = Objects.Geometry.Curve; using Mesh = Objects.Geometry.Mesh; -using Objects; using Objects.Other; using Objects.Utils; using Spiral = Objects.Geometry.Spiral; @@ -192,7 +190,7 @@ public DS.Plane PlaneToNative(Plane plane) public CoordinateSystem TransformToNative(Transform transform) { - return CoordinateSystem.ByMatrix(transform.value).Scale(Units.GetConversionFactor(transform.units, ModelUnits)); + return CoordinateSystem.ByMatrix(transform.ToArray()).Scale(Units.GetConversionFactor(transform.units, ModelUnits)); } #endregion @@ -215,7 +213,10 @@ public Line LineToSpeckle(DS.Line line, string units = null) { l.bbox = BoxToSpeckle(line.BoundingBox, u); } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + // TODO: Should a Line even have a bounding box? + } return l; } diff --git a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Units.cs b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Units.cs index 518e7c2b70..087e36a8b9 100644 --- a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Units.cs +++ b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/ConverterDynamo.Units.cs @@ -1,6 +1,5 @@ #if REVIT using Autodesk.Revit.DB; -using Objects.Converter.Revit; #endif namespace Objects.Converter.Dynamo; @@ -36,7 +35,7 @@ public string GetRevitDocUnits() return Speckle.Core.Kits.Units.Meters; } -#if (REVIT2020 || REVIT2021 ) +#if REVIT2020 || REVIT2021 private DisplayUnitType _revitUnitsTypeId = DisplayUnitType.DUT_UNDEFINED; public DisplayUnitType RevitLengthTypeId diff --git a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/Utils.cs b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/Utils.cs index d256330c07..c9784c14fd 100644 --- a/Objects/Converters/ConverterDynamo/ConverterDynamoShared/Utils.cs +++ b/Objects/Converters/ConverterDynamo/ConverterDynamoShared/Utils.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Speckle.Core.Logging; using DS = Autodesk.DesignScript.Geometry; namespace Objects.Converter.Dynamo; @@ -60,7 +61,7 @@ public static bool IsLinear(this DS.Curve curve) var extremesDistance = curve.StartPoint.DistanceTo(curve.EndPoint); return Threshold(curve.Length, extremesDistance); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return false; } @@ -104,7 +105,7 @@ public static bool IsCircle(this DS.Curve curve) return Threshold(radius, (curve.Length) / (2 * Math.PI)); } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return false; } @@ -152,7 +153,7 @@ public static bool IsEllipse(this DS.Curve curve) return Threshold(curve.Length, perimeter, 1e-5); //Ellipse perimeter is an approximation } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return false; } @@ -208,7 +209,7 @@ public static bool IsArc(this DS.Curve curve) return Threshold(arc.Length, curve.Length); } } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return false; } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Geometry.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Geometry.cs index 7b589c644f..9e645a61b6 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Geometry.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Geometry.cs @@ -12,8 +12,6 @@ using Plane = Objects.Geometry.Plane; using Vector = Objects.Geometry.Vector; -// - namespace Objects.Converter.Navisworks; public class PrimitiveProcessor : InwSimplePrimitivesCB @@ -28,10 +26,10 @@ public class PrimitiveProcessor : InwSimplePrimitivesCB private List _triangles = new(); - public PrimitiveProcessor(bool elevationMode) + public PrimitiveProcessor(bool isUpright) : this() { - ElevationMode = elevationMode; + IsUpright = isUpright; } private PrimitiveProcessor() @@ -55,7 +53,7 @@ private PrimitiveProcessor() public IEnumerable LocalToWorldTransformation { get; set; } - private bool ElevationMode { get; set; } + private bool IsUpright { get; set; } public void Line(InwSimpleVertex v1, InwSimpleVertex v2) { @@ -64,16 +62,8 @@ public void Line(InwSimpleVertex v1, InwSimpleVertex v2) return; } -#pragma warning disable CA2000 - var vD1 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), - ElevationMode - ); - var vD2 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v2), LocalToWorldTransformation), - ElevationMode - ); -#pragma warning restore CA2000 + var vD1 = TargetUpVector(ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), IsUpright); + var vD2 = TargetUpVector(ApplyTransformation(VectorFromVertex(v2), LocalToWorldTransformation), IsUpright); try { @@ -97,10 +87,7 @@ public void Point(InwSimpleVertex v1) return; } - var vD1 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), - ElevationMode - ); + var vD1 = TargetUpVector(ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), IsUpright); AddPoint(new PointD(vD1)); } @@ -117,18 +104,9 @@ public void Triangle(InwSimpleVertex v1, InwSimpleVertex v2, InwSimpleVertex v3) return; } - var vD1 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), - ElevationMode - ); - var vD2 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v2), LocalToWorldTransformation), - ElevationMode - ); - var vD3 = SetElevationModeVector( - ApplyTransformation(VectorFromVertex(v3), LocalToWorldTransformation), - ElevationMode - ); + var vD1 = TargetUpVector(ApplyTransformation(VectorFromVertex(v1), LocalToWorldTransformation), IsUpright); + var vD2 = TargetUpVector(ApplyTransformation(VectorFromVertex(v2), LocalToWorldTransformation), IsUpright); + var vD3 = TargetUpVector(ApplyTransformation(VectorFromVertex(v3), LocalToWorldTransformation), IsUpright); var indexPointer = Faces.Count; AddFace(3); @@ -143,60 +121,28 @@ private void SetCoords(IEnumerable coords) _coords.AddRange(coords); } - private void AddCoords(IEnumerable coords) - { - _coords.AddRange(coords); - } + private void AddCoords(IEnumerable coords) => _coords.AddRange(coords); - private void SetFaces(List faces) - { - _faces = faces ?? throw new ArgumentNullException(nameof(faces)); - } + private void SetFaces(List faces) => _faces = faces ?? throw new ArgumentNullException(nameof(faces)); - private void AddFace(int face) - { - _faces.Add(face); - } + private void AddFace(int face) => _faces.Add(face); - private void AddFaces(IEnumerable faces) - { - _faces.AddRange(faces); - } + private void AddFaces(IEnumerable faces) => _faces.AddRange(faces); - private void SetTriangles(List triangles) - { + private void SetTriangles(List triangles) => _triangles = triangles ?? throw new ArgumentNullException(nameof(triangles)); - } - private void AddTriangle(TriangleD triangle) - { - _triangles.Add(triangle); - } + private void AddTriangle(TriangleD triangle) => _triangles.Add(triangle); - private void SetLines(List lines) - { - _lines = lines ?? throw new ArgumentNullException(nameof(lines)); - } + private void SetLines(List lines) => _lines = lines ?? throw new ArgumentNullException(nameof(lines)); - private void AddLine(LineD line) - { - _lines.Add(line); - } + private void AddLine(LineD line) => _lines.Add(line); - private void SetPoints(List points) - { - _points = points ?? throw new ArgumentNullException(nameof(points)); - } + private void SetPoints(List points) => _points = points ?? throw new ArgumentNullException(nameof(points)); - private void AddPoint(PointD point) - { - _points.Add(point); - } + private void AddPoint(PointD point) => _points.Add(point); - private static Vector3D SetElevationModeVector(Vector3D v, bool elevationMode) - { - return elevationMode ? v : new Vector3D(v.X, -v.Z, v.Y); - } + private static Vector3D TargetUpVector(Vector3D v, bool isUpright) => isUpright ? v : new Vector3D(v.X, -v.Z, v.Y); private static Vector3D ApplyTransformation(Vector3 vector3, IEnumerable matrixStore) { @@ -236,7 +182,7 @@ public NavisworksGeometry(ModelItem modelItem) private IEnumerable ModelFragments => ModelFragmentStack; - public bool ElevationMode { get; set; } + public bool IsUpright { get; set; } public IEnumerable GetUniqueGeometryFragments() { @@ -244,7 +190,7 @@ public IEnumerable GetUniqueGeometryFragments() foreach (InwOaPath path in Selection.Paths()) { - var processor = new PrimitiveProcessor(ElevationMode); + var processor = new PrimitiveProcessor(IsUpright); foreach (var fragment in ModelFragments) { @@ -268,10 +214,8 @@ public IEnumerable GetUniqueGeometryFragments() return processors; } - private static bool IsSameFragmentPath(Array a1, Array a2) - { - return a1.Length == a2.Length && a1.Cast().SequenceEqual(a2.Cast()); - } + private static bool IsSameFragmentPath(Array a1, Array a2) => + a1.Length == a2.Length && a1.Cast().SequenceEqual(a2.Cast()); private static double[] ConvertArrayToDouble(Array arr) { @@ -353,20 +297,22 @@ public partial class ConverterNavisworks public Vector TransformVector { get; set; } + private static readonly Vector3D s_canonicalUp = new(0, 0, 1); + private BoundingBox3D ModelBoundingBox { get; set; } /// - /// ElevationMode is the indicator that the model is being handled as an XY ground plane + /// IsUpright is the indicator that the model is being handled as an XY ground plane /// with Z as elevation height. /// This is distinct from the typical "handedness" of 3D models. /// - private static bool ElevationMode { get; set; } + private static bool IsUpright { get; set; } public static Box BoxToSpeckle(BoundingBox3D boundingBox3D) { var source = Application.ActiveDocument.Units; - var target = Units.Meters; - var scale = UnitConversion.ScaleFactor(source, target); + const Units TARGET_UNITS = Units.Meters; + var scale = UnitConversion.ScaleFactor(source, TARGET_UNITS); var min = boundingBox3D.Min; var max = boundingBox3D.Max; @@ -392,17 +338,7 @@ public static Box BoxToSpeckle(BoundingBox3D boundingBox3D) return boundingBox; } - private static void SetModelOrientationMode() - { - using var elevationModeUpVector = new Vector3D(0, 0, 1); - using var elevationModeRightVector = new Vector3D(1, 0, 0); - - var upMatch = VectorMatch(Doc.UpVector, elevationModeUpVector); - var rightMatch = VectorMatch(Doc.RightVector, elevationModeRightVector); - - // TODO: do both need to match or would UP be enough? - ElevationMode = upMatch && rightMatch; - } + private static void SetModelOrientationMode() => IsUpright = VectorMatch(Doc.UpVector, s_canonicalUp); /// /// Compares two vectors as identical with an optional tolerance. @@ -411,12 +347,10 @@ private static void SetModelOrientationMode() /// The second comparison vector /// Default value of 1e-9 /// Boolean value indicating match success - private static bool VectorMatch(Vector3D vectorA, Vector3D vectorB, double tolerance = 1e-9) - { - return Math.Abs(vectorA.X - vectorB.X) < tolerance - && Math.Abs(vectorA.Y - vectorB.Y) < tolerance - && Math.Abs(vectorA.Z - vectorB.Z) < tolerance; - } + private static bool VectorMatch(Vector3D vectorA, Vector3D vectorB, double tolerance = 1e-9) => + Math.Abs(vectorA.X - vectorB.X) < tolerance + && Math.Abs(vectorA.Y - vectorB.Y) < tolerance + && Math.Abs(vectorA.Z - vectorB.Z) < tolerance; private static void PopulateModelFragments(NavisworksGeometry geometry) { @@ -427,11 +361,10 @@ private static void PopulateModelFragments(NavisworksGeometry geometry) var fragments = path.Fragments(); foreach (InwOaFragment3 fragment in fragments) { - var a1 = ((Array)fragment.path.ArrayData).ToArray(); - var a2 = ((Array)path.ArrayData).ToArray(); - var isSame = !(a1.Length != a2.Length || !a1.SequenceEqual(a2)); + var pathArray1 = ((Array)fragment.path.ArrayData).ToArray(); + var pathArray2 = ((Array)path.ArrayData).ToArray(); - if (isSame) + if (!(pathArray1.Length != pathArray2.Length || !pathArray1.SequenceEqual(pathArray2))) { geometry.ModelFragmentStack.Push(fragment); } @@ -443,7 +376,7 @@ private static void PopulateModelFragments(NavisworksGeometry geometry) } } - private static IReadOnlyList TranslateFragmentGeometry(NavisworksGeometry navisworksGeometry) + private static List TranslateFragmentGeometry(NavisworksGeometry navisworksGeometry) { var callbackListeners = navisworksGeometry.GetUniqueGeometryFragments(); @@ -513,10 +446,7 @@ from lineD in lines return baseGeometries; } - private void SetModelBoundingBox() - { - ModelBoundingBox = Doc.GetBoundingBox(false); - } + private void SetModelBoundingBox() => ModelBoundingBox = Doc.GetBoundingBox(false); private void SetTransformVector3D() { @@ -545,13 +475,6 @@ private void SetTransformVector3D() TransformVector3D = transform; } - private static IEnumerable MoveAndScaleVertices(Vector3D vertex1, Vector3D move, double scale) - { - return new List - { - (vertex1.X + move.X) * scale, - (vertex1.Y + move.Y) * scale, - (vertex1.Z + move.Z) * scale - }; - } + private static List MoveAndScaleVertices(Vector3D vertex1, Vector3D move, double scale) => + new() { (vertex1.X + move.X) * scale, (vertex1.Y + move.Y) * scale, (vertex1.Z + move.Z) * scale }; } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Other.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Other.cs index fc48bb7c69..a89e0d55af 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Other.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Other.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using Autodesk.Navisworks.Api; using Objects.Other; using Color = System.Drawing.Color; @@ -8,38 +9,25 @@ namespace Objects.Converter.Navisworks; // ReSharper disable once UnusedType.Global public partial class ConverterNavisworks { - private static Color NavisworksColorToColor(Autodesk.Navisworks.Api.Color color) - { - return Color.FromArgb( - Convert.ToInt32(color.R * 255), - Convert.ToInt32(color.G * 255), - Convert.ToInt32(color.B * 255) - ); - } + private static Color NavisworksColorToColor(Autodesk.Navisworks.Api.Color color) => + Color.FromArgb(Convert.ToInt32(color.R * 255), Convert.ToInt32(color.G * 255), Convert.ToInt32(color.B * 255)); + [SuppressMessage( + "design", + "CA1508:Avoid dead conditional code", + Justification = "Already there anticipating other options becoming possible" + )] private static RenderMaterial TranslateMaterial(ModelItem geom) { // Already there anticipating other options becoming possible var materialSettings = new { Mode = "original" }; - - Color renderColor; - - switch (materialSettings.Mode) + var renderColor = materialSettings.Mode switch { - case "original": - renderColor = NavisworksColorToColor(geom.Geometry.OriginalColor); - break; - case "active": - renderColor = NavisworksColorToColor(geom.Geometry.ActiveColor); - break; - case "permanent": - renderColor = NavisworksColorToColor(geom.Geometry.PermanentColor); - break; - default: - renderColor = new Color(); - break; - } - + "active" => NavisworksColorToColor(geom.Geometry.ActiveColor), + "permanent" => NavisworksColorToColor(geom.Geometry.PermanentColor), + "original" => NavisworksColorToColor(geom.Geometry.OriginalColor), + _ => new Color(), + }; var materialName = $"NavisworksMaterial_{Math.Abs(renderColor.ToArgb())}"; var black = Color.FromArgb(Convert.ToInt32(0), Convert.ToInt32(0), Convert.ToInt32(0)); @@ -74,13 +62,8 @@ private static RenderMaterial TranslateMaterial(ModelItem geom) return r; } - private static void ConsoleLog(string message, ConsoleColor color = ConsoleColor.Blue) - { + private static void ConsoleLog(string message, ConsoleColor color = ConsoleColor.Blue) => Console.WriteLine(message, color); - } - private static void ErrorLog(string errorMessage) - { - ConsoleLog(errorMessage, ConsoleColor.DarkRed); - } + private static void ErrorLog(string errorMessage) => ConsoleLog(errorMessage, ConsoleColor.DarkRed); } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Properties.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Properties.cs index 955507572f..34164afc93 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Properties.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Properties.cs @@ -38,7 +38,7 @@ private static void ProcessPropertyCategory(DynamicBase propertiesBase, Property properties.ToList().ForEach(property => BuildPropertyCategory(propertyCategory, property, propertyCategoryBase)); - if (!propertyCategoryBase.GetMembers().Any() || propertyCategory.DisplayName == null) + if (propertyCategoryBase.GetMembers().Count == 0 || propertyCategory.DisplayName == null) { return; } @@ -49,19 +49,15 @@ private static void ProcessPropertyCategory(DynamicBase propertiesBase, Property propertiesBase[UseInternalPropertyNames ? internalName : propertyCategoryDisplayName] = propertyCategoryBase; } - private static bool IsCategoryToBeSkipped(PropertyCategory propertyCategory) - { - return propertyCategory.DisplayName == "Geometry"; - } + private static bool IsCategoryToBeSkipped(PropertyCategory propertyCategory) => + propertyCategory.DisplayName == "Geometry"; - private static string SanitizePropertyName(string name) - { + private static string SanitizePropertyName(string name) => // Regex pattern from speckle-sharp/Core/Core/Models/DynamicBase.cs IsPropNameValid - return name == "Item" + name == "Item" // Item is a reserved term for Indexed Properties: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/using-indexers ? "Item_" : Regex.Replace(name, @"[\.\/]", "_"); - } private static void BuildPropertyCategory( PropertyCategory propertyCategory, @@ -218,10 +214,8 @@ private static void AddItemProperties(ModelItem element, Base @base) AddInternalProperties(element, (Base)@base["properties"]); } - private static bool ShouldIncludeProperties() - { - return !bool.TryParse(Settings.FirstOrDefault(x => x.Key == "include-properties").Value, out bool result) || result; - } + private static bool ShouldIncludeProperties() => + !bool.TryParse(Settings.FirstOrDefault(x => x.Key == "include-properties").Value, out bool result) || result; private static void AddInternalProperties(ModelItem element, Base propertiesBase) { diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Settings.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Settings.cs index bfc711393d..780381fe2f 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Settings.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Settings.cs @@ -16,9 +16,9 @@ public enum Transforms } // CAUTION: these strings need to have the same values as in the converter - private const string InternalOrigin = "Model Origin (default)"; - private const string ProxyOrigin = "Project Base Origin"; - private const string BBoxOrigin = "Boundingbox Origin"; + private const string INTERNAL_ORIGIN = "Model Origin (default)"; + private const string PROXY_ORIGIN = "Project Base Origin"; + private const string BBOX_ORIGIN = "Boundingbox Origin"; private static Dictionary Settings { get; } = new(); @@ -26,14 +26,11 @@ private static Vector2D ProjectBasePoint { get { - if (!Settings.ContainsKey("x-coordinate") || !Settings.ContainsKey("y-coordinate")) + if (!Settings.TryGetValue("x-coordinate", out string x) || !Settings.TryGetValue("y-coordinate", out string y)) { return new Vector2D(0, 0); } - var x = Settings["x-coordinate"]; - var y = Settings["y-coordinate"]; - return new Vector2D( Convert.ToDouble(x, CultureInfo.InvariantCulture), Convert.ToDouble(y, CultureInfo.InvariantCulture) @@ -45,18 +42,16 @@ private static Transforms ModelTransform { get { - if (!Settings.ContainsKey("reference-point")) + if (!Settings.TryGetValue("reference-point", out string referencePoint)) { return Transforms.Default; } - var value = Settings["reference-point"]; - - return value switch + return referencePoint switch { - ProxyOrigin => Transforms.ProjectBasePoint, - BBoxOrigin => Transforms.BoundingBox, - InternalOrigin => Transforms.Default, + PROXY_ORIGIN => Transforms.ProjectBasePoint, + BBOX_ORIGIN => Transforms.BoundingBox, + INTERNAL_ORIGIN => Transforms.Default, _ => Transforms.Default }; } @@ -66,14 +61,12 @@ private static Units CoordinateUnits { get { - if (!Settings.ContainsKey("units")) + if (!Settings.TryGetValue("units", out string units)) { return Units.Meters; } - var value = Settings["units"]; - - return (Units)Enum.Parse(typeof(Units), value, true); + return (Units)Enum.Parse(typeof(Units), units, true); } } @@ -81,14 +74,12 @@ private static bool UseInternalPropertyNames { get { - if (!Settings.ContainsKey("internal-property-names")) + if (!Settings.TryGetValue("internal-property-names", out string useInternalPropertyNames)) { return false; } - var value = Settings["internal-property-names"]; - - return value == "True"; + return useInternalPropertyNames == "True"; } } } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToNative.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToNative.cs index b939b552bc..4238d3855f 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToNative.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToNative.cs @@ -11,30 +11,15 @@ public partial class ConverterNavisworks /// No actual receiving exists /// /// - public object ConvertToNative(Base @object) - { - throw new NotImplementedException(); - } + public object ConvertToNative(Base @object) => throw new NotImplementedException(); - public object ConvertToNativeDisplayable(Base @object) - { - throw new NotImplementedException(); - } + public object ConvertToNativeDisplayable(Base @object) => throw new NotImplementedException(); /// - public List ConvertToNative(List objects) - { - throw new NotImplementedException(); - } + public List ConvertToNative(List objects) => throw new NotImplementedException(); /// - public bool CanConvertToNative(Base @object) - { - throw new NotImplementedException(); - } + public bool CanConvertToNative(Base @object) => throw new NotImplementedException(); - public bool CanConvertToNativeDisplayable(Base @object) - { - throw new NotImplementedException(); - } + public bool CanConvertToNativeDisplayable(Base @object) => throw new NotImplementedException(); } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToSpeckle.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToSpeckle.cs index 43fa3e2a1a..882148aa7c 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToSpeckle.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.ToSpeckle.cs @@ -18,7 +18,7 @@ public partial class ConverterNavisworks { public Base ConvertToSpeckle(object @object) { - var unused = Settings.TryGetValue("_Mode", out var mode); + var _ = Settings.TryGetValue("_Mode", out var mode); Base @base; @@ -33,7 +33,7 @@ public Base ConvertToSpeckle(object @object) { case string pseudoId: element = - pseudoId == RootNodePseudoId + pseudoId == ROOT_NODE_PSEUDO_ID ? Application.ActiveDocument.Models.RootItems.First : PointerToModelItem(pseudoId); break; @@ -72,10 +72,9 @@ public Base ConvertToSpeckle(object @object) } } - public List ConvertToSpeckle(List objects) - { - throw new NotImplementedException(); - } + private static readonly int[] s_lowerBounds = new int[1] { 1 }; + + public List ConvertToSpeckle(List objects) => throw new NotImplementedException(); public bool CanConvertToSpeckle(object @object) { @@ -105,17 +104,11 @@ private static SavedViewpoint ReferenceOrGuidToSavedViewpoint(string referenceOr return savedViewpoint; } - private static Point ToPoint(InwLPos3f v) - { - return new Point(v.data1, v.data2, v.data3); - } + private static Point ToPoint(InwLPos3f v) => new(v.data1, v.data2, v.data3); - private static Vector ToVector(InwLVec3f v) - { - return new Vector(v.data1, v.data2, v.data3); - } + private static Vector ToVector(InwLVec3f v) => new(v.data1, v.data2, v.data3); - private static Base ViewpointToBase(Viewpoint viewpoint, string name = "Commit View") + private static View3D ViewpointToBase(Viewpoint viewpoint, string name = "Commit View") { var scaleFactor = UnitConversion.ScaleFactor(Application.ActiveDocument.Units, Units.Meters); @@ -211,21 +204,17 @@ private static Base ViewpointToBase(Viewpoint viewpoint, string name = "Commit V return view; } - private static Point ScalePoint(Point cameraPosition, double scaleFactor) - { - return new Point(cameraPosition.x * scaleFactor, cameraPosition.y * scaleFactor, cameraPosition.z * scaleFactor); - } + private static Point ScalePoint(Point cameraPosition, double scaleFactor) => + new(cameraPosition.x * scaleFactor, cameraPosition.y * scaleFactor, cameraPosition.z * scaleFactor); - private static Point GetViewTarget(Point cameraPosition, Vector viewDirection, double focalDistance) - { - return new Point( + private static Point GetViewTarget(Point cameraPosition, Vector viewDirection, double focalDistance) => + new( cameraPosition.x + viewDirection.x * focalDistance, cameraPosition.y + viewDirection.y * focalDistance, cameraPosition.z + viewDirection.z * focalDistance ); - } - private static Base ViewpointToBase(SavedViewpoint savedViewpoint) + private static View3D ViewpointToBase(SavedViewpoint savedViewpoint) { var view = ViewpointToBase(savedViewpoint.Viewpoint, savedViewpoint.DisplayName); @@ -251,9 +240,7 @@ private static Base ModelItemToSpeckle(ModelItem element) : element.DisplayName; @base["name"] = string.IsNullOrEmpty(resolvedName) - ? ( - element.PropertyCategories.FindPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemIcon) - ).ToString() + ? element.PropertyCategories.FindPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemIcon).ToString() : GetSanitizedPropertyName(resolvedName); // Geometry items have no children @@ -316,20 +303,16 @@ private static Base ConvertModelItemToSpeckle(ModelItem element) /// /// The ModelItem element. /// The found category property. - private static DataProperty FindCategoryProperty(ModelItem element) - { - return element.PropertyCategories.FindPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemIcon); - } + private static DataProperty FindCategoryProperty(ModelItem element) => + element.PropertyCategories.FindPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemIcon); /// /// Gets the display name of a category property. /// /// The category property. /// The display name of the category. - private static string GetCategoryDisplayName(DataProperty categoryProperty) - { - return categoryProperty.Value.ToNamedConstant().DisplayName; - } + private static string GetCategoryDisplayName(DataProperty categoryProperty) => + categoryProperty.Value.ToNamedConstant().DisplayName; /// /// Creates a Speckle object based on the ModelItem element and its category type. @@ -337,19 +320,17 @@ private static string GetCategoryDisplayName(DataProperty categoryProperty) /// The ModelItem element. /// The type of the category. /// A Speckle object. - private static Base CreateSpeckleObject(ModelItem element, string categoryType) - { - return element.HasGeometry ? new GeometryNode() : new Collection { collectionType = categoryType }; - } + private static Base CreateSpeckleObject(ModelItem element, string categoryType) => + element.HasGeometry ? new GeometryNode() : new Collection { collectionType = categoryType }; private static void GeometryToSpeckle(ModelItem element, Base @base) { - var geometry = new NavisworksGeometry(element) { ElevationMode = ElevationMode }; + var geometry = new NavisworksGeometry(element) { IsUpright = IsUpright }; PopulateModelFragments(geometry); var fragmentGeometry = TranslateFragmentGeometry(geometry); - if (fragmentGeometry != null && fragmentGeometry.Any()) + if (fragmentGeometry != null && fragmentGeometry.Count != 0) { @base["@displayValue"] = fragmentGeometry; } @@ -363,11 +344,11 @@ private static bool CanConvertToSpeckle(ModelItem item) return true; } - const PrimitiveTypes allowedTypes = + const PrimitiveTypes ALLOWED_TYPES = PrimitiveTypes.Lines | PrimitiveTypes.Triangles | PrimitiveTypes.SnapPoints | PrimitiveTypes.Text; var primitives = item.Geometry.PrimitiveTypes; - var primitiveTypeSupported = (primitives & allowedTypes) == primitives; + var primitiveTypeSupported = (primitives & ALLOWED_TYPES) == primitives; return primitiveTypeSupported; } @@ -396,7 +377,7 @@ private static ModelItem PointerToModelItem(object @string) typeof(int), new int[1] { pathArray.Length }, // ReSharper disable once RedundantExplicitArraySize - new int[1] { 1 } + s_lowerBounds ); Array.Copy(pathArray, 0, oneBasedArray, 1, pathArray.Length); diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Utilities.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Utilities.cs index d8e34133d9..2b46b43a66 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Utilities.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.Utilities.cs @@ -20,17 +20,15 @@ public static T[] ToArray(this Array arr) // ReSharper disable once UnusedType.Global public partial class ConverterNavisworks { - private const string RootNodePseudoId = "___"; + private const string ROOT_NODE_PSEUDO_ID = "___"; /// /// Checks is the Element is hidden or if any of its ancestors is hidden /// /// /// - private static bool IsElementHidden(ModelItem element) - { + private static bool IsElementHidden(ModelItem element) => // Hidden status is stored at the earliest node in the hierarchy // Any of the the tree path nodes Hidden then the element is hidden - return element.AncestorsAndSelf.Any(x => x.IsHidden); - } + element.AncestorsAndSelf.Any(x => x.IsHidden); } diff --git a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.cs b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.cs index cf90205a41..d2e3b4ac2c 100644 --- a/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.cs +++ b/Objects/Converters/ConverterNavisworks/ConverterNavisworks/ConverterNavisworks.cs @@ -10,15 +10,15 @@ namespace Objects.Converter.Navisworks; public partial class ConverterNavisworks : ISpeckleConverter { #if NAVMAN21 - private readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2024); + private static readonly string s_versionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2024); #elif NAVMAN20 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2023); + private static readonly string s_versionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2023); #elif NAVMAN19 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2022); + private static readonly string s_versionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2022); #elif NAVMAN18 - public readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2021); + private static readonly string s_versionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2021); #elif NAVMAN17 - private readonly static string VersionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2020); + private static readonly string s_versionedAppName = HostApplications.Navisworks.GetVersion(HostAppVersion.v2020); #endif public string Description => "Default Speckle Kit for Navisworks"; @@ -39,10 +39,7 @@ public partial class ConverterNavisworks : ISpeckleConverter private static Document Doc { get; set; } - public IEnumerable GetServicedApplications() - { - return new[] { VersionedAppName }; - } + public IEnumerable GetServicedApplications() => new[] { s_versionedAppName }; public void SetContextDocument(object doc) { @@ -61,7 +58,7 @@ public void SetContextDocument(object doc) Doc = Application.ActiveDocument; } - // This sets or resets the correct ElevationMode flag for model orientation. + // This sets or resets the correct IsUpright flag for model orientation. // Needs to be called every time a Send is initiated to reflect the options SetModelOrientationMode(); SetModelBoundingBox(); @@ -73,16 +70,11 @@ public void SetContextDocument(object doc) public IReadOnlyList ContextObjects => _contextObjects; /// - public void SetContextObjects(List objects) - { + public void SetContextObjects(List objects) => _contextObjects = objects ?? throw new ArgumentNullException(nameof(objects)); - } /// - public void SetPreviousContextObjects(List objects) - { - throw new NotImplementedException(); - } + public void SetPreviousContextObjects(List objects) => throw new NotImplementedException(); /// public void SetConverterSettings(object settings) diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/Categories.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/Categories.cs index 711dd27dc1..abc0cd7964 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/Categories.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/Categories.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; -using SCH = RevitSharedResources.Helpers.Categories; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs index 6249ae63a9..49f4e09c6b 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs @@ -9,13 +9,13 @@ using Objects.Converter.Revit.Models; using Objects.Geometry; using Objects.Other; +using RevitSharedResources.Extensions.SpeckleExtensions; using RevitSharedResources.Interfaces; using Speckle.Core.Helpers; using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; -using Speckle.Core.Models.GraphTraversal; using DB = Autodesk.Revit.DB; using Level = Objects.BuiltElements.Level; using Line = Objects.Geometry.Line; @@ -152,9 +152,9 @@ out List notes reportObj.Update(status: ApplicationObject.State.Failed, logItem: $"Conversion returned null"); } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { - SpeckleLog.Logger.Error(ex, ex.Message); + SpeckleLog.Logger.LogDefaultError(ex); reportObj.Update(status: ApplicationObject.State.Failed, logItem: $"Conversion threw exception: {ex}"); } } @@ -165,7 +165,7 @@ out List notes Report.Log(reportObj); } - if (convertedHostedElements.Any()) + if (convertedHostedElements.Count > 0) { notes.Add($"Converted and attached {convertedHostedElements.Count} hosted elements"); @@ -242,10 +242,14 @@ public void GetAllRevitParamsAndIds(Base speckleElement, DB.Element revitElement { paramBase[kv.Key] = kv.Value; } - catch + catch (InvalidPropNameException) { //ignore } + catch (SpeckleException ex) + { + SpeckleLog.Logger.Warning(ex, "Error thrown when trying to set property named {propName}", kv.Key); + } } if (paramBase.GetDynamicMembers().Any()) @@ -586,7 +590,7 @@ private void TrySetParam(DB.Parameter rp, object value, string units = "", strin break; } } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { // do nothing for now... } @@ -1030,12 +1034,13 @@ public T TryInSubtransaction(Func func, Action catchFunc) returnValue = func(); subtransaction.Commit(); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { subtransaction.RollBack(); Doc.Regenerate(); catchFunc(ex); } + return returnValue; } #endregion @@ -1083,7 +1088,7 @@ public WallLocationLine GetWallLocationLine(LocationLine location) } #region materials - public RenderMaterial GetElementRenderMaterial(DB.Element element) + public RenderMaterial? GetElementRenderMaterial(DB.Element? element) { var matId = element?.GetMaterialIds(false)?.FirstOrDefault(); @@ -1097,7 +1102,7 @@ public RenderMaterial GetElementRenderMaterial(DB.Element element) return RenderMaterialToSpeckle(revitMaterial); } - public static RenderMaterial RenderMaterialToSpeckle(DB.Material revitMaterial) + public static RenderMaterial? RenderMaterialToSpeckle(DB.Material? revitMaterial) { if (revitMaterial == null) { @@ -1242,9 +1247,10 @@ public bool TryAppendLineSafely(CurveArray curveArray, Line line, ApplicationObj curveArray.Append(LineToNative(line)); return true; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - appObj.Log.Add(e.Message); + SpeckleLog.Logger.LogDefaultError(ex); + appObj.Log.Add(ex.Message); return false; } } @@ -1411,4 +1417,17 @@ public static double GetSlopeArrowHeadOffset(ModelLine slopeArrow, Document doc, return headOffset; } + + public static string GetCleanBasePropName(string propName) + { + var charsToRemove = new string[] { ".", "/" }; + foreach (var c in charsToRemove) + { + if (propName.Contains(c)) + { + propName = propName.Replace(c, string.Empty); + } + } + return propName; + } } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.DxfImport.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.DxfImport.cs index 6f87247752..cb0b8d1428 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.DxfImport.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.DxfImport.cs @@ -6,13 +6,11 @@ using ConverterRevitShared.Revit; using Objects.Converters.DxfConverter; using Objects.Geometry; -using Speckle.Core.Api; using Speckle.Core.Helpers; using Speckle.Core.Kits; using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.netDxf.Entities; -using FamilyInstance = Objects.BuiltElements.Revit.FamilyInstance; using Mesh = Objects.Geometry.Mesh; using DirectShape = Objects.BuiltElements.Revit.DirectShape; @@ -241,11 +239,10 @@ public DB.FamilyInstance CreateDxfImportFamily( var symbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as DB.FamilySymbol; symbol.Activate(); - try + if (File.Exists(tempFamilyPath)) { File.Delete(tempFamilyPath); } - catch { } return Doc.Create.NewFamilyInstance(DB.XYZ.Zero, symbol, DB.Structure.StructuralType.NonStructural); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.MeshBuildHelper.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.MeshBuildHelper.cs index c4bcd96060..b700228aaa 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.MeshBuildHelper.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.MeshBuildHelper.cs @@ -1,7 +1,5 @@ -using System; using System.Collections.Generic; using System.Linq; -using Autodesk.Revit.DB; using Objects.Other; using DB = Autodesk.Revit.DB; using Mesh = Objects.Geometry.Mesh; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.Previews.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.Previews.cs index 0c872c7d44..6f545fa737 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.Previews.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.Previews.cs @@ -1,12 +1,7 @@ -using ConverterRevitShared; -using Objects.Geometry; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Text; using Mesh = Objects.Geometry.Mesh; namespace Objects.Converter.Revit; @@ -28,15 +23,9 @@ private ApplicationObject PreviewGeometry(Base @object) ); return appObj; } - try - { - server = new DirectContext3DServer(meshes, Doc); - appObj.Update(status: ApplicationObject.State.Created); - } - catch (Exception ex) - { - appObj.Update(status: ApplicationObject.State.Failed, logItem: ex.Message); - } + + server = new DirectContext3DServer(meshes, Doc); + appObj.Update(status: ApplicationObject.State.Created); appObj.Converted = new List { server }; return appObj; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs index e53d7872b5..96f2d237bd 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; @@ -9,19 +8,16 @@ using Objects.Organization; using Objects.Other; using Objects.Structural.Properties.Profiles; -using RevitSharedResources.Helpers; using RevitSharedResources.Helpers.Extensions; using RevitSharedResources.Interfaces; using RevitSharedResources.Models; using Speckle.Core.Kits; -using Speckle.Core.Logging; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; using BE = Objects.BuiltElements; using BER = Objects.BuiltElements.Revit; using BERC = Objects.BuiltElements.Revit.Curve; using DB = Autodesk.Revit.DB; -using GE = Objects.Geometry; using STR = Objects.Structural; namespace Objects.Converter.Revit; @@ -406,15 +402,10 @@ public Base ConvertToSpeckle(object @object) && !(returnObject is Collection) ) { - try + if (GetElementRenderMaterial(@object as DB.Element) is RenderMaterial material) { - var material = GetElementRenderMaterial(@object as DB.Element); returnObject["renderMaterial"] = material; } - catch (Exception e) - { - // passing for stuff without a material (eg converting the current document to get the `Model` and `Info` objects) - } } // log @@ -565,7 +556,7 @@ public object ConvertToNativeObject(Base @object) } // non revit built elems case BE.Alignment o: - if (o.curves is null) // TODO: remove after a few releases, this is for backwards compatibility + if (o.curves is null && o.baseCurve is not null) // This is for backwards compatibility for the deprecated basecurve property { return ModelCurveToNative(o.baseCurve); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/DirectContext3DServer.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/DirectContext3DServer.cs index f488a548b6..b38e50ca5c 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/DirectContext3DServer.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/DirectContext3DServer.cs @@ -1,14 +1,11 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Text; using Autodesk.Revit.DB; using Autodesk.Revit.DB.DirectContext3D; using Autodesk.Revit.DB.ExternalService; -using Autodesk.Revit.UI; -using Objects.Converter.Revit; -using Speckle.Core.Models; +using RevitSharedResources.Extensions.SpeckleExtensions; +using Speckle.Core.Logging; using OG = Objects.Geometry; namespace Objects.Converter.Revit; @@ -139,9 +136,9 @@ public void RenderScene(View dBView, DisplayStyle displayStyle) ); } } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { - System.Diagnostics.Debug.WriteLine(e.ToString()); + SpeckleLog.Logger.LogDefaultError(e); } } @@ -476,14 +473,7 @@ public SpeckleMeshInfo(OG.Mesh mesh, ColorWithTransparency color, ref OG.Point m var vectorC = Vertices.ElementAt(indices[2]); var result = (vectorB - vectorA).CrossProduct(vectorC - vectorA).Normalize(); - try - { - Normals.Add(result); - } - catch (Exception ex) - { - Normals.Add(new XYZ(0, 0, 1)); - } + Normals.Add(result); for (var j = 0; j < indices.Length; j++) { diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/ConnectorExtensions.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/ConnectorExtensions.cs index c94b559099..600a8c9a86 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/ConnectorExtensions.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/ConnectorExtensions.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; using Autodesk.Revit.DB; namespace ConverterRevitShared.Extensions; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/DefinitionExtensions.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/DefinitionExtensions.cs index c0f4794410..014e74a977 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/DefinitionExtensions.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/Extensions/DefinitionExtensions.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; using Autodesk.Revit.DB; -using Objects.Primitive; namespace ConverterRevitShared.Extensions; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAdaptiveComponent.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAdaptiveComponent.cs index 3bc9090bf5..3e83d8a99c 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAdaptiveComponent.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAdaptiveComponent.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; @@ -67,9 +66,10 @@ public ApplicationObject AdaptiveComponentToNative(AdaptiveComponent speckleAc) isUpdate = true; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { //something went wrong, re-create it + appObj.Update(logItem: "Unable to update element. Creating a new element instead"); } } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalNode.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalNode.cs index a5e8f9cd1e..75e3831dba 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalNode.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalNode.cs @@ -1,15 +1,11 @@ -using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; -using Objects.BuiltElements; -using Objects.BuiltElements.Revit; using Objects.Structural.Geometry; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; using Plane = Objects.Geometry.Plane; -using Vector = Objects.Geometry.Vector; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalStick.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalStick.cs index 1e96026fd4..3129e5b8fe 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalStick.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalStick.cs @@ -1,11 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Reflection; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.DB.Structure.StructuralSections; -using ConverterRevitShared.Extensions; using Objects.BuiltElements; using Objects.BuiltElements.Revit; using Objects.Structural.Geometry; @@ -14,6 +11,9 @@ using Objects.Structural.Properties.Profiles; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; +#if !REVIT2020 && !REVIT2021 && !REVIT2022 +using ConverterRevitShared.Extensions; +#endif namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalSurface.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalSurface.cs index 415b0dcaf8..52a8c5f97a 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalSurface.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertAnalyticalSurface.cs @@ -2,14 +2,16 @@ using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; -using ConverterRevitShared.Models; using Objects.BuiltElements.Revit; using Objects.Geometry; using Objects.Structural.Geometry; using Objects.Structural.Properties; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; +#if REVIT2020 || REVIT2021 || REVIT2022 +using ConverterRevitShared.Models; using Point = Objects.Geometry.Point; +#endif namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBeam.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBeam.cs index 5fd6f2e476..03172bba44 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBeam.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBeam.cs @@ -4,7 +4,6 @@ using Objects.BuiltElements.Revit; using Speckle.Core.Models; using System.Collections.Generic; -using System.Linq; using System.Text.RegularExpressions; using DB = Autodesk.Revit.DB; @@ -57,7 +56,7 @@ public ApplicationObject BeamToNative(Beam speckleBeam, StructuralType structura { if (level != null) { - level = GetLevelByName(speckleRevitBeam.level.name); + level = GetLevelByName(speckleRevitBeam.level?.name); } } @@ -95,8 +94,9 @@ public ApplicationObject BeamToNative(Beam speckleBeam, StructuralType structura } isUpdate = true; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { + appObj.Update(logItem: "Unable to update element. Creating a new element instead"); //something went wrong, re-create it } } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBlock.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBlock.cs index 0543ae3a7a..39dc76d525 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBlock.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertBlock.cs @@ -4,17 +4,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.DoubleNumerics; using ConverterRevitShared.Revit; using Objects.BuiltElements.Revit; -using Objects.Geometry; using Speckle.Core.Models; using Speckle.Core.Models.Extensions; using Objects.Other; -using Serilog.Core; using Speckle.Core.Kits; using Speckle.Core.Logging; -using Speckle.netDxf.Blocks; using DB = Autodesk.Revit.DB; namespace Objects.Converter.Revit; @@ -63,7 +59,7 @@ public ApplicationObject BlockInstanceToNative(BlockInstance instance) isUpdate = true; Doc.Delete(docObj.Id); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { SpeckleLog.Logger.Warning( e, @@ -83,7 +79,7 @@ public ApplicationObject BlockInstanceToNative(BlockInstance instance) logItem: $"Assigned name: {familyInstance.Symbol.Name}" ); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { var errMsg = "An unexpected error occured when converting a BlockInstance to Native"; SpeckleLog.Logger.Error(e, errMsg); @@ -212,7 +208,7 @@ private static void AssignCategoryToFamilyDoc(DB.Document famDoc, string? catego famDoc.OwnerFamily.FamilyCategory = familyCategory; t.Commit(); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ArgumentException e) { SpeckleLog.Logger.Error(e, "Document category could not be modified"); t.RollBack(); @@ -419,7 +415,7 @@ private void ApplyMirroringToElement( Doc.Regenerate(); DB.ElementTransformUtils.MirrorElements(Doc, new List { elementId }, item.mirrorPlane, false); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { SpeckleLog.Logger.Warning(e, "Failed to mirror element on {name} plane", item.name); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCableTray.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCableTray.cs index cab6afeb13..2296362a9e 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCableTray.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCableTray.cs @@ -3,7 +3,6 @@ using ConverterRevitShared.Extensions; using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using System; using System.Collections.Generic; using DB = Autodesk.Revit.DB; using Line = Objects.Geometry.Line; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCeiling.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCeiling.cs index 49b3148eec..ac6143fa12 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCeiling.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCeiling.cs @@ -1,12 +1,15 @@ using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; -using Speckle.Core.Models; -using System; using System.Collections.Generic; using System.Linq; -using Ceiling = Objects.BuiltElements.Ceiling; using DB = Autodesk.Revit.DB; +#if !REVIT2020 && !REVIT2021 +using Ceiling = Objects.BuiltElements.Ceiling; +using Speckle.Core.Logging; +using Speckle.Core.Models; +#endif + namespace Objects.Converter.Revit; public partial class ConverterRevit @@ -124,8 +127,9 @@ public ApplicationObject CeilingToNative(Ceiling speckleCeiling) { CreateVoids(revitCeiling, speckleCeiling); } - catch (Exception ex) + catch (Autodesk.Revit.Exceptions.ApplicationException ex) { + SpeckleLog.Logger.Error(ex, "Could not create openings in ceiling"); appObj.Update(logItem: $"Could not create openings: {ex.Message}"); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertColumn.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertColumn.cs index 3c23c6ebec..0f813d6165 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertColumn.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertColumn.cs @@ -4,7 +4,6 @@ using Speckle.Core.Models; using System; using System.Collections.Generic; -using System.Linq; using Column = Objects.BuiltElements.Column; using DB = Autodesk.Revit.DB; using Line = Objects.Geometry.Line; @@ -112,7 +111,11 @@ public ApplicationObject ColumnToNative(Column speckleColumn) } isUpdate = true; } - catch { } + catch (Autodesk.Revit.Exceptions.ApplicationException) + { + //something went wrong, re-create it + appObj.Update(logItem: "Unable to update element. Creating a new element instead"); + } } if (revitColumn == null && isLineBased) diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCombinableElement.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCombinableElement.cs index a31d8f53ba..bd4ed5509f 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCombinableElement.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCombinableElement.cs @@ -1,7 +1,6 @@ using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using System; using System.Collections.Generic; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConduit.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConduit.cs index bce79de458..f557963789 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConduit.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConduit.cs @@ -1,6 +1,5 @@ using Autodesk.Revit.DB; using Autodesk.Revit.DB.Electrical; -using Autodesk.Revit.DB.Mechanical; using ConverterRevitShared.Extensions; using Objects.BuiltElements.Revit; using Speckle.Core.Models; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConnector.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConnector.cs index 4104c7404e..1610d2bac2 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConnector.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertConnector.cs @@ -17,23 +17,21 @@ public RevitMEPConnector ConnectorToSpeckle(Connector connector) systemName = connector.MEPSystem?.Name ?? connector.Owner.Category?.Name, }; - // some genius at Autodesk thought it would be a good idea for property getters to throw... - try + if (connector.Domain is Domain.DomainHvac or Domain.DomainPiping or Domain.DomainCableTrayConduit) { speckleMEPConnector.angle = connector.Angle; } - catch { } - try + + if (connector.Shape is ConnectorProfileType.Rectangular) { speckleMEPConnector.height = ScaleToSpeckle(connector.Height); speckleMEPConnector.width = ScaleToSpeckle(connector.Width); } - catch { } - try + else if (connector.Shape is ConnectorProfileType.Round) { speckleMEPConnector.radius = ScaleToSpeckle(connector.Radius); } - catch { } + foreach (var reference in connector.AllRefs.Cast()) { if (connector.IsConnectedTo(reference)) diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCurves.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCurves.cs index 805715c83d..d24317b8e6 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCurves.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertCurves.cs @@ -1,9 +1,10 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements.Revit.Curve; +using RevitSharedResources.Extensions.SpeckleExtensions; +using Speckle.Core.Logging; using Speckle.Core.Models; using Alignment = Objects.BuiltElements.Alignment; using DB = Autodesk.Revit.DB; @@ -75,7 +76,7 @@ public ApplicationObject DetailCurveToNative(DetailCurve speckleCurve) { revitCurve = Doc.Create.NewDetailCurve(Doc.ActiveView, baseCurve); } - catch (Exception) + catch (Autodesk.Revit.Exceptions.ArgumentException) { appObj.Update(logItem: $"Detail curve creation failed\nView is not valid for detail curve creation."); continue; @@ -145,8 +146,9 @@ public ApplicationObject ModelCurveToNative(ICurve speckleLine) { return ModelCurvesFromEnumerator(CurveToNative(speckleLine).GetEnumerator(), speckleLine, appObj); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); // use display value if curve fails (prob a closed, periodic curve or a non-planar nurbs) if (speckleLine is IDisplayValue d) { @@ -157,7 +159,7 @@ public ApplicationObject ModelCurveToNative(ICurve speckleLine) } else { - appObj.Update(status: ApplicationObject.State.Failed, logItem: e.Message); + appObj.Update(status: ApplicationObject.State.Failed, logItem: ex.Message); return appObj; } } @@ -188,8 +190,9 @@ public ApplicationObject RoomBoundaryLineToNative(RoomBoundaryLine speckleCurve) appObj.Update(status: ApplicationObject.State.Created, createdId: revitCurve.UniqueId, convertedItem: revitCurve); } - catch (Exception) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update( status: ApplicationObject.State.Failed, logItem: "View is not valid for room boundary line creation." @@ -237,7 +240,7 @@ public ApplicationObject SpaceSeparationLineToNative(SpaceSeparationLine speckle .get_Item(0); appObj.Update(status: ApplicationObject.State.Created, createdId: res.UniqueId, convertedItem: res); } - catch (Exception) + catch (Autodesk.Revit.Exceptions.ApplicationException) { appObj.Update( status: ApplicationObject.State.Failed, diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectShape.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectShape.cs index f8174ee5f5..e71083bb48 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectShape.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectShape.cs @@ -5,7 +5,7 @@ using Objects.BuiltElements.Revit; using Objects.Geometry; using Objects.Other; -using Speckle.Core.Kits; +using RevitSharedResources.Extensions.SpeckleExtensions; using Speckle.Core.Logging; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; @@ -223,17 +223,19 @@ public ApplicationObject DirectShapeToNative(DirectShape speckleDs, ToNativeMesh { Doc.Delete(existingObj.Id); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ArgumentException e) { appObj.Log.Add($"Could not delete existing object: {e.Message}"); } } appObj.Update(status: ApplicationObject.State.Created, createdId: revitDs.UniqueId, convertedItem: revitDs); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update(status: ApplicationObject.State.Failed, logItem: $"{ex.Message}"); } + return appObj; } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectTeklaMeshElements.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectTeklaMeshElements.cs index f60246dce6..cf3cbafbc8 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectTeklaMeshElements.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDirectTeklaMeshElements.cs @@ -1,9 +1,5 @@ using Autodesk.Revit.DB; -using Objects.Other; -using System; using System.Collections.Generic; -using System.Linq; -using DB = Autodesk.Revit.DB; using Mesh = Objects.Geometry.Mesh; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDisplayableObject.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDisplayableObject.cs index 23f4d00266..70b0cc6652 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDisplayableObject.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDisplayableObject.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; @@ -86,6 +85,8 @@ public string GetSpeckleObjectBuiltInCategory(Base @object) return BuiltInCategory.OST_Columns.ToString(); case BE.Pipe _: return BuiltInCategory.OST_PipeSegments.ToString(); + case BE.RebarGroup _: + return BuiltInCategory.OST_Rebar.ToString(); case BE.Rebar _: return BuiltInCategory.OST_Rebar.ToString(); case BE.Topography _: diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDuct.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDuct.cs index a69c4253cf..ecba04e50c 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDuct.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertDuct.cs @@ -43,7 +43,7 @@ public ApplicationObject DuctToNative(BuiltElements.Duct speckleDuct) } Element duct = null; - if (speckleDuct.baseCurve == null || speckleDuct.baseCurve is Line) + if (speckleDuct.baseCurve is Line || speckleDuct.baseLine is not null) // this is for old ducts with deprecated baseline field { DuctType ductType = GetElementType(speckleDuct, appObj, out bool _); if (ductType == null) @@ -52,10 +52,10 @@ public ApplicationObject DuctToNative(BuiltElements.Duct speckleDuct) return appObj; } - DB.Line baseLine = - (speckleDuct.baseCurve != null) - ? LineToNative(speckleDuct.baseCurve as Line) - : LineToNative(speckleDuct.baseLine); + DB.Line baseLine = speckleDuct.baseCurve is Line baseCurve + ? LineToNative(baseCurve) + : LineToNative(speckleDuct.baseLine); + XYZ startPoint = baseLine.GetEndPoint(0); XYZ endPoint = baseLine.GetEndPoint(1); DB.Level lineLevel = ConvertLevelToRevit( diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFaceWall.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFaceWall.cs index eca96e0e34..70987eb976 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFaceWall.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFaceWall.cs @@ -8,6 +8,8 @@ using System.Linq; using Speckle.Core.Models.Extensions; using DB = Autodesk.Revit.DB; +using Speckle.Core.Logging; +using RevitSharedResources.Extensions.SpeckleExtensions; namespace Objects.Converter.Revit; @@ -31,9 +33,9 @@ public ApplicationObject FaceWallToNative(RevitFaceWall speckleWall) return appObj; } - if (speckleWall.surface == null) + if (speckleWall?.brep?.Surfaces?.FirstOrDefault() == null) { - appObj.Update(status: ApplicationObject.State.Failed, logItem: "Facewall surface was null"); + appObj.Update(status: ApplicationObject.State.Failed, logItem: "FaceWall surface was null"); return appObj; } @@ -52,17 +54,20 @@ public ApplicationObject FaceWallToNative(RevitFaceWall speckleWall) return appObj; } - var tempMassFamilyPath = CreateMassFamily(templatePath, speckleWall.surface, speckleWall.applicationId); - Family fam; - Doc.LoadFamily(tempMassFamilyPath, new FamilyLoadOption(), out fam); + var tempMassFamilyPath = CreateMassFamily( + templatePath, + speckleWall.brep.Surfaces.First(), + speckleWall.applicationId + ); + + Doc.LoadFamily(tempMassFamilyPath, new FamilyLoadOption(), out Family fam); var symbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as FamilySymbol; symbol.Activate(); - try + if (File.Exists(tempMassFamilyPath)) { File.Delete(tempMassFamilyPath); } - catch { } var mass = Doc.Create.NewFamilyInstance(XYZ.Zero, symbol, DB.Structure.StructuralType.NonStructural); // NOTE: must set a schedule level! @@ -104,7 +109,7 @@ public ApplicationObject FaceWallToNative(RevitFaceWall speckleWall) { revitWall = DB.FaceWall.Create(Doc, wallType.Id, GetWallLocationLine(speckleWall.locationLine), faceRef); } - catch (Exception e) { } + catch (Autodesk.Revit.Exceptions.ApplicationException) { } if (revitWall == null) { @@ -126,6 +131,7 @@ public ApplicationObject FaceWallToNativeV2(RevitFaceWall speckleWall) { applicationId = speckleWall.applicationId }; + try { var existing = GetExistingElementByApplicationId(speckleWall.applicationId) as FaceWall; @@ -175,17 +181,18 @@ public ApplicationObject FaceWallToNativeV2(RevitFaceWall speckleWall) SetInstanceParameters(revitWall, speckleWall); appObj.Update(status: ApplicationObject.State.Created, createdId: revitWall.UniqueId, convertedItem: revitWall); //appObj = SetHostedElements(speckleWall, revitWall, appObj); - return appObj; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update( status: ApplicationObject.State.Failed, - logItem: $"Revit wall creation failed: {e.Message}", - log: new List { e.ToFormattedString() } + logItem: $"Revit wall creation failed: {ex.Message}", + log: new List { ex.ToFormattedString() } ); - return appObj; } + + return appObj; } private Reference GetFaceRef(Element e) @@ -244,7 +251,10 @@ private string CreateMassFamily(string famPath, Geometry.Surface surface, string var loft = famDoc.FamilyCreate.NewLoftForm(true, curveArray); } - catch (Exception e) { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } t.Commit(); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFamilyInstance.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFamilyInstance.cs index eb091e7f7a..b5d22d8320 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFamilyInstance.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFamilyInstance.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; -using System.DoubleNumerics; using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using ConverterRevitShared.Extensions; -using Objects.BuiltElements.Revit; -using Objects.Organization; -using RevitSharedResources.Helpers; +using RevitSharedResources.Extensions.SpeckleExtensions; using RevitSharedResources.Helpers.Extensions; using Speckle.Core.Logging; using Speckle.Core.Models; @@ -217,7 +214,7 @@ public ApplicationObject FamilyInstanceToNative(BuiltElements.Revit.FamilyInstan } isUpdate = true; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { //something went wrong, re-create it } @@ -253,19 +250,14 @@ public ApplicationObject FamilyInstanceToNative(BuiltElements.Revit.FamilyInstan } // NOTE: do not check for the CanRotate prop as it doesn't work (at least on some families I tried)! - // some point based families don't have a rotation, so keep this in a try catch - try + if (speckleFi.rotation != (familyInstance.Location as LocationPoint)?.Rotation) { - if (speckleFi.rotation != (familyInstance.Location as LocationPoint).Rotation) - { - var axis = DB.Line.CreateBound(new XYZ(basePoint.X, basePoint.Y, 0), new XYZ(basePoint.X, basePoint.Y, 1000)); - (familyInstance.Location as LocationPoint).Rotate( - axis, - speckleFi.rotation - (familyInstance.Location as LocationPoint).Rotation - ); - } + var axis = DB.Line.CreateBound(new XYZ(basePoint.X, basePoint.Y, 0), new XYZ(basePoint.X, basePoint.Y, 1000)); + (familyInstance.Location as LocationPoint).Rotate( + axis, + speckleFi.rotation - (familyInstance.Location as LocationPoint).Rotation + ); } - catch { } if ( familySymbol.Family.FamilyPlacementType == FamilyPlacementType.TwoLevelsBased @@ -352,14 +344,10 @@ private DB.FamilyInstance CreateHostedFamilyInstance( InstanceVoidCutUtils.AddInstanceVoidCut(Doc, el, familyInstance); } - try + if (lvlParams.ElementAtOrDefault(0) != null && level.Id is ElementId levelId) { - if (lvlParams.ElementAtOrDefault(0) != null) - { - lvlParams[0].Set(level.Id); // this can be null - } + lvlParams[0].Set(levelId); } - catch { } } else if (CurrentHostElement is DB.Floor floor) { @@ -417,7 +405,7 @@ private DB.FamilyInstance CreateHostedFamilyInstance( StructuralType.NonStructural ); } - catch { } + catch (Autodesk.Revit.Exceptions.ApplicationException) { } } return familyInstance; @@ -620,7 +608,7 @@ out FamilyPlacementType placementType } isUpdate = true; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { //something went wrong, re-create it } @@ -665,7 +653,7 @@ out FamilyPlacementType placementType { familyInstance = Doc.Create.NewFamilyInstance(faceRef, insertionPoint, norm, familySymbol); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { appObj.Update( status: ApplicationObject.State.Failed, @@ -753,7 +741,7 @@ out FamilyPlacementType placementType false ); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { appObj.Update(logItem: $"Instance could not be mirrored: {e.Message}"); } @@ -791,7 +779,7 @@ out FamilyPlacementType placementType using var axis = DB.Line.CreateUnbound(location.Point, currentTransform.BasisZ); location.Rotate(axis, -rotation); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { appObj.Update(logItem: $"Could not rotate created instance: {e.Message}"); } @@ -880,9 +868,10 @@ Transform parentTransform var meshes = GetElementDisplayValue(instance, isConvertedAsInstance: true, transform: parentTransform); symbol.displayValue = meshes; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - notes.Add($"Could not retrieve display meshes: {e.Message}"); + SpeckleLog.Logger.LogDefaultError(ex); + notes.Add($"Could not retrieve display meshes: {ex.Message}"); } #region sub elements capture diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFloor.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFloor.cs index 8adcedcd38..6bfb1007bd 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFloor.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFloor.cs @@ -9,6 +9,9 @@ using DB = Autodesk.Revit.DB; using OG = Objects.Geometry; using OO = Objects.Other; +#if REVIT2020 || REVIT2021 +using RevitSharedResources.Extensions.SpeckleExtensions; +#endif namespace Objects.Converter.Revit; @@ -151,8 +154,9 @@ out baseOffset { CreateVoids(revitFloor, speckleFloor); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update(logItem: $"Could not create openings: {ex.Message}"); } #endif diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFreeformElement.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFreeformElement.cs index 34c4db6a21..d23d76e7ce 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFreeformElement.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertFreeformElement.cs @@ -6,6 +6,7 @@ using ConverterRevitShared.Revit; using Objects.Geometry; using Objects.Other; +using RevitSharedResources.Extensions.SpeckleExtensions; using Speckle.Core.Logging; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; @@ -39,10 +40,11 @@ public ApplicationObject FreeformElementToNative(Objects.BuiltElements.Revit.Fre solids.Add(solid); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update( - logItem: $"Could not convert brep to native, falling back to mesh representation: {e.Message}" + logItem: $"Could not convert brep to native, falling back to mesh representation: {ex.Message}" ); var brepMeshSolids = GetSolidMeshes(brep.displayValue); solids.AddRange(brepMeshSolids); @@ -72,11 +74,11 @@ public ApplicationObject FreeformElementToNative(Objects.BuiltElements.Revit.Fre Doc.LoadFamily(tempPath, new FamilyLoadOption(), out var fam); var symbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as DB.FamilySymbol; symbol.Activate(); - try + + if (File.Exists(tempPath)) { File.Delete(tempPath); } - catch { } FamilyInstance freeform; if (Doc.IsFamilyDocument) @@ -107,8 +109,9 @@ public ApplicationObject FreeformElementToNativeFamily(Brep brep, Category cat = solids.Add(solid); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); var meshes = GetSolidMeshes(brep.displayValue); solids.AddRange(meshes); } @@ -160,6 +163,7 @@ private ApplicationObject FreeformElementToNative(Brep brep) { var appObj = new ApplicationObject(brep.id, brep.speckle_type) { applicationId = brep.applicationId }; var solids = new List(); + try { var solid = BrepToNative(brep, out List brepNotes); @@ -170,8 +174,9 @@ private ApplicationObject FreeformElementToNative(Brep brep) solids.Add(solid); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); solids.AddRange(GetSolidMeshes(brep.displayValue)); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGeometry.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGeometry.cs index 16d8fc6a65..2448111106 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGeometry.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGeometry.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Linq; using System.DoubleNumerics; using Autodesk.Revit.DB; using Autodesk.Revit.DB.PointClouds; -using Objects.Converters.DxfConverter; using Objects.Geometry; using Objects.Other; using Objects.Primitive; @@ -23,7 +20,6 @@ using Pointcloud = Objects.Geometry.Pointcloud; using Spiral = Objects.Geometry.Spiral; using Surface = Objects.Geometry.Surface; -using Transform = Objects.Other.Transform; using Units = Speckle.Core.Kits.Units; using Vector = Objects.Geometry.Vector; @@ -706,7 +702,7 @@ public IList MeshToNative( { tsb.Build(); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { Report.LogConversionError(e); return null; @@ -1263,7 +1259,12 @@ public Brep BrepToSpeckle(Solid solid, Document d, string units = null) // Update trim indices with new item. // TODO: Make this better. var trimIndices = sEdge.TrimIndices.ToList(); - trimIndices.Append(sTrimIndex); //TODO Append is a pure function and the return is unused + + // suppressing the warning even though it is completely valid. + // reason we are just suppressing is because this entire class is broken anyways +#pragma warning disable CA1806 // Do not ignore method results + trimIndices.Append(sTrimIndex); +#pragma warning restore CA1806 // Do not ignore method results sEdge.TrimIndices = trimIndices.ToArray(); } } @@ -1426,7 +1427,7 @@ public DirectShape BrepToDirectShape( } revitDs.SetShape(new List { solid }); } - catch (Exception e) + catch (SpeckleException) { notes.Add($"Failed to convert brep, using display value meshes instead."); var meshes = brep.displayValue.SelectMany(m => MeshToNative(m)); diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGridLine.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGridLine.cs index a5d8709ccb..a6a880914a 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGridLine.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGridLine.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements; @@ -76,9 +75,9 @@ public ApplicationObject GridLineToNative(GridLine speckleGridline) Line.CreateBound(new XYZ(newEnd.X, newEnd.Y, datumLineZ), new XYZ(newStart.X, newStart.Y, datumLineZ)) ); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException ex) { - appObj.Update(logItem: $"Error setting grid endpoints: {e.Message}"); + appObj.Update(logItem: $"Error setting grid endpoints: {ex.Message}"); } isUpdate = true; } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGroup.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGroup.cs index 563aac28df..8f53c4ed71 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGroup.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertGroup.cs @@ -1,11 +1,7 @@ -using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; -using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using DB = Autodesk.Revit.DB; -using Mesh = Objects.Geometry.Mesh; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLevel.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLevel.cs index 7363371ea7..a421a7e7d7 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLevel.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLevel.cs @@ -187,7 +187,7 @@ public ViewPlan CreateViewPlan(string name, ElementId levelId) { view.Name = name; } - catch { } + catch (Autodesk.Revit.Exceptions.ApplicationException) { } Report.Log($"Created ViewPlan {view.Id}"); diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLocation.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLocation.cs index c0c879afd9..91813afc38 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLocation.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertLocation.cs @@ -1,7 +1,6 @@ using System; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; -using RevitSharedResources.Helpers; using RevitSharedResources.Helpers.Extensions; using Speckle.Core.Logging; using Speckle.Core.Models; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMEPFamilyInstance.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMEPFamilyInstance.cs index b0cc368fd4..8a0a4dabf5 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMEPFamilyInstance.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMEPFamilyInstance.cs @@ -2,13 +2,13 @@ using Objects.BuiltElements.Revit; using Autodesk.Revit.DB; using System.Linq; -using Objects.Organization; using System; using System.Collections.Generic; using Speckle.Core.Models; using Speckle.Core.Kits; using RevitSharedResources.Models; using Speckle.Core.Logging; +using RevitSharedResources.Extensions.SpeckleExtensions; namespace Objects.Converter.Revit; @@ -107,8 +107,9 @@ public ApplicationObject FittingOrMEPInstanceToNative(RevitMEPFamilyInstance spe return appObj; } } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update( logItem: $"Could not create fitting as part of the system. Reason: {ex.Message}. Converting as independent instance instead" ); diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterial.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterial.cs index 09c143ba07..b7c9692369 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterial.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterial.cs @@ -1,9 +1,3 @@ -using Autodesk.Revit.DB.Structure; -using Speckle.Core.Kits; -using Speckle.Core.Models; -using System; -using System.Collections.Generic; -using System.Linq; using DB = Autodesk.Revit.DB; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterialQuantities.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterialQuantities.cs index 8c8a232732..cbfe4df0df 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterialQuantities.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertMaterialQuantities.cs @@ -1,6 +1,5 @@ #nullable enable using Autodesk.Revit.DB; -using ConverterRevitShared.Extensions; using Objects.Other; using System.Collections.Generic; using System.Linq; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertNetwork.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertNetwork.cs index 8eddc6f844..ee10fd51f1 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertNetwork.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertNetwork.cs @@ -6,10 +6,7 @@ using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using ConverterRevitShared.Revit; -using Objects.BuiltElements.Revit; -using Speckle.Core.Credentials; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json.Linq; using DB = Autodesk.Revit.DB; using Network = Objects.BuiltElements.Network; using NetworkElement = Objects.BuiltElements.NetworkElement; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertOpening.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertOpening.cs index 7d8abe3fcc..fe01f1e092 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertOpening.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertOpening.cs @@ -4,6 +4,7 @@ using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; using Objects.Geometry; +using RevitSharedResources.Extensions.SpeckleExtensions; using Speckle.Core.Logging; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; @@ -52,15 +53,17 @@ public ApplicationObject OpeningToNative(BuiltElements.Opening speckleOpening) return appObj; } Element existingElement; + try { existingElement = GetExistingElementByApplicationId(rwo.host.applicationId); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update( status: ApplicationObject.State.Failed, - logItem: $"Could not find the host wall: {e.Message}" + logItem: $"Could not find the host wall: {ex.Message}" ); return appObj; } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPanel.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPanel.cs index b6450f9433..ba219b4cab 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPanel.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPanel.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; using Objects.BuiltElements.Revit; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPipe.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPipe.cs index 9775e79b29..ac2d2ce760 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPipe.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertPipe.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProfileWall.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProfileWall.cs index e39786b68e..fbb8ff4021 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProfileWall.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProfileWall.cs @@ -1,7 +1,6 @@ using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using System; using System.Collections.Generic; using DB = Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProjectInfo.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProjectInfo.cs index e18c049f7a..8be332814f 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProjectInfo.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertProjectInfo.cs @@ -1,10 +1,6 @@ -using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; -using Objects.Geometry; using Speckle.Core.Models; -using System; using System.Collections.Generic; -using System.Linq; using DB = Autodesk.Revit.DB; using ProjectInfo = Objects.BuiltElements.Revit.ProjectInfo; @@ -28,6 +24,43 @@ private ProjectInfo ProjectInfoToSpeckle(DB.ProjectInfo revitInfo) status = revitInfo.Status }; Report.Log($"Converted ProjectInfo"); + + Base parameterParent = new(); + GetAllRevitParamsAndIds( + parameterParent, + revitInfo, + new List + { + // parameters included in the strongly typed properties + "PROJECT_ADDRESS", + "PROJECT_AUTHOR", + "PROJECT_BUILDING_NAME", + "CLIENT_NAME", + "PROJECT_ISSUE_DATE", + "PROJECT_NUMBER", + "PROJECT_ORGANIZATION_DESCRIPTION", + "PROJECT_ORGANIZATION_NAME", + "PROJECT_NUMBER", + "PROJECT_STATUS", + // parameters to be excluded entirely + "ELEM_CATEGORY_PARAM_MT", + "ELEM_CATEGORY_PARAM", + "DESIGN_OPTION_ID", + } + ); + + if (parameterParent["parameters"] is Base parameters) + { + Dictionary parameterDict = parameters.GetMembers(DynamicBaseMemberType.Dynamic); + foreach (KeyValuePair kvp in parameterDict) + { + if (kvp.Value is Parameter param && param.value is not null) + { + speckleInfo[GetCleanBasePropName(param.name)] = param.value; + } + } + } + return speckleInfo; } } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRailing.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRailing.cs index 4033454997..62b11502a5 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRailing.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRailing.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRebar.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRebar.cs index 976420e928..5f7df69a28 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRebar.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRebar.cs @@ -3,11 +3,9 @@ using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; -using Autodesk.Revit.Exceptions; using Objects.BuiltElements; using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json.Linq; using DB = Autodesk.Revit.DB; using Vector = Objects.Geometry.Vector; @@ -63,27 +61,31 @@ public ApplicationObject RebarToNative(RevitRebarGroup speckleRebar) speckleRebar.shape.rebarType == RebarType.Standard ? RebarStyle.Standard : RebarStyle.StirrupTie; // get start and end hooks and orientations - var speckleStartHook = speckleRebar.startHook as RevitRebarHook; RebarHookType startHook = null; RebarHookOrientation startHookOrientation = RebarHookOrientation.Right; - if (speckleStartHook != null) + if (speckleRebar.startHook is RevitRebarHook speckleStartHook) { startHook = RebarHookToNative(speckleStartHook); - Enum.TryParse(speckleStartHook.orientation, out startHookOrientation); + if (Enum.TryParse(speckleStartHook.orientation, out RebarHookOrientation localStartHookOrientation)) + { + startHookOrientation = localStartHookOrientation; + } } - var speckleEndHook = speckleRebar.endHook as RevitRebarHook; RebarHookType endHook = null; RebarHookOrientation endHookOrientation = RebarHookOrientation.Right; - if (speckleEndHook != null) + if (speckleRebar.endHook is RevitRebarHook speckleEndHook) { endHook = RebarHookToNative(speckleEndHook); - Enum.TryParse(speckleEndHook.orientation, out endHookOrientation); + if (Enum.TryParse(speckleEndHook.orientation, out RebarHookOrientation localEndHookOrientation)) + { + endHookOrientation = localEndHookOrientation; + } } // get the shape curves List curves = barShape.curves.SelectMany(o => CurveToNative(o).Cast()).ToList(); - if (curves is null || !curves.Any()) + if (curves is null || curves.Count == 0) { appObj.Update(status: ApplicationObject.State.Failed, logItem: "Could not convert any shape curves"); return appObj; @@ -115,7 +117,7 @@ public ApplicationObject RebarToNative(RevitRebarGroup speckleRebar) true ); } - catch (Exception e) + catch (Autodesk.Revit.Exceptions.ApplicationException e) { appObj.Update(status: ApplicationObject.State.Failed, logItem: e.Message); return appObj; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRevitElement.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRevitElement.cs index dcb3ae86a1..24f2fba64a 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRevitElement.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRevitElement.cs @@ -2,8 +2,6 @@ using Autodesk.Revit.DB; -using Speckle.Core.Models; - using Objects.BuiltElements.Revit; using RevitElementType = Objects.BuiltElements.Revit.RevitElementType; using System.Linq; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoof.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoof.cs index 0ccfd8b411..42c616b6fd 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoof.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoof.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; using System.Linq; using Autodesk.Revit.DB; -using Autodesk.Revit.DB.Architecture; using Objects.BuiltElements; using Objects.BuiltElements.Revit.RevitRoof; using Objects.Geometry; +using RevitSharedResources.Extensions.SpeckleExtensions; +using Speckle.Core.Logging; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; using FamilyInstance = Objects.BuiltElements.Revit.FamilyInstance; @@ -201,8 +202,9 @@ out bool _ { CreateVoids(revitRoof, speckleRoof); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { + SpeckleLog.Logger.LogDefaultError(ex); appObj.Update(logItem: $"Could not create openings: {ex.Message}"); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoom.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoom.cs index a8976a02aa..79c2186c2a 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoom.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertRoom.cs @@ -1,7 +1,6 @@ using Autodesk.Revit.DB; using Objects.BuiltElements; using Speckle.Core.Models; -using System.Collections.Generic; using System.Linq; using DB = Autodesk.Revit.DB.Architecture; using Point = Objects.Geometry.Point; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralConnectionHandlers.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralConnectionHandlers.cs index 15190b2e81..d8543f682e 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralConnectionHandlers.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralConnectionHandlers.cs @@ -1,6 +1,5 @@ using Objects.BuiltElements.Revit; using Speckle.Core.Models; -using System.Collections.Generic; using DB = Autodesk.Revit.DB; using Structure = Autodesk.Revit.DB.Structure; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralModel.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralModel.cs index 48863a6d89..a791e725af 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralModel.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertStructuralModel.cs @@ -1,17 +1,10 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.Structure; -using Objects.BuiltElements; -using Objects.BuiltElements.Revit; using Objects.Structural.Geometry; -using Vector = Objects.Geometry.Vector; -using Plane = Objects.Geometry.Plane; using Speckle.Core.Models; -using DB = Autodesk.Revit.DB; using Objects.Structural.Analysis; using Objects.Structural.CSI.Geometry; +using RevitSharedResources.Extensions.SpeckleExtensions; +using Speckle.Core.Logging; +using System; namespace Objects.Converter.Revit; @@ -34,6 +27,7 @@ public ApplicationObject StructuralModelToNative(Model speckleStructModel) if (element is Element1D element1D) { element1D.units = lengthUnits; + try { if (element is CSIElement1D csiElement1D) @@ -47,7 +41,10 @@ public ApplicationObject StructuralModelToNative(Model speckleStructModel) appObj.Update(createdIds: _stick.CreatedIds, converted: _stick.Converted); } } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } } else { @@ -64,7 +61,10 @@ public ApplicationObject StructuralModelToNative(Model speckleStructModel) appObj.Update(createdIds: _stick.CreatedIds, converted: _stick.Converted); } } - catch { } + catch (Exception ex) when (!ex.IsFatal()) + { + SpeckleLog.Logger.LogDefaultError(ex); + } } } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTeklaObjects.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTeklaObjects.cs index 5bf29c6c4a..42b4725f4c 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTeklaObjects.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTeklaObjects.cs @@ -1,16 +1,6 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; -using Objects.BuiltElements; using Objects.BuiltElements.Revit; -using Objects.Structural.Geometry; -using Objects.Structural.Properties; -using Objects.Structural.Properties.Profiles; -using Objects.Structural.Materials; using Speckle.Core.Models; -using DB = Autodesk.Revit.DB; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTopRail.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTopRail.cs index f21c6528c4..f4f3295f2b 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTopRail.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertTopRail.cs @@ -1,4 +1,3 @@ -using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; using Objects.BuiltElements.Revit; using System.Collections.Generic; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertToposolid.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertToposolid.cs index ab7ff33d79..c10e7a72d6 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertToposolid.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertToposolid.cs @@ -1,17 +1,12 @@ -#if (REVIT2024) +#if REVIT2024 -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; -using OG = Objects.Geometry; -using OO = Objects.Other; - namespace Objects.Converter.Revit; public partial class ConverterRevit diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertView.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertView.cs index 045bfc262f..ee17084eab 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertView.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertView.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Text.RegularExpressions; using Autodesk.Revit.DB; -using Speckle.Core.Logging; using Speckle.Core.Kits; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs index 6046ac0b7a..11bbd0ceaf 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs @@ -1,15 +1,17 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; -using RevitSharedResources.Models; using Speckle.Core.Models; using DB = Autodesk.Revit.DB; using Mesh = Objects.Geometry.Mesh; +#if !REVIT2020 && !REVIT2021 using OG = Objects.Geometry; +using RevitSharedResources.Models; +using System.Collections; +#endif namespace Objects.Converter.Revit; @@ -355,7 +357,7 @@ private void SetWallVoids(Wall wall, Base speckleElement) { sketchEditScope.Commit(new ErrorEater()); } - catch (Exception ex) + catch (Autodesk.Revit.Exceptions.InvalidOperationException) { if (sketchEditScope.IsActive) { diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWire.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWire.cs index 97938000d9..4527af4e8b 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWire.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWire.cs @@ -4,7 +4,6 @@ using ConverterRevitShared.Extensions; using Objects.BuiltElements.Revit; using Objects.Geometry; -using Speckle.Core.Logging; using Speckle.Core.Models; using Curve = Objects.Geometry.Curve; using DB = Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertZone.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertZone.cs index 252a5cf45c..a0a1e699ca 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertZone.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertZone.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using Autodesk.Revit.DB; using Objects.BuiltElements; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/Units.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/Units.cs index 645d2f5e62..1572b80614 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/Units.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/Units.cs @@ -1,7 +1,8 @@ using Autodesk.Revit.DB; -using ConverterRevitShared.Extensions; -using RevitSharedResources.Interfaces; using Speckle.Core.Logging; +#if REVIT2020 +using RevitSharedResources.Interfaces; +#endif namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/UpdateParameter.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/UpdateParameter.cs index 2dd2440020..46c6b2e1d2 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/UpdateParameter.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/UpdateParameter.cs @@ -1,9 +1,5 @@ using Autodesk.Revit.DB; using Objects.BuiltElements.Revit; -using Objects.Geometry; -using System.Collections.Generic; -using System.Linq; -using Speckle.Core.Helpers; using Speckle.Core.Models; namespace Objects.Converter.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/Revit/FamilyLoadOptions.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/Revit/FamilyLoadOptions.cs index f69a0035f2..225c7976c1 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/Revit/FamilyLoadOptions.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/Revit/FamilyLoadOptions.cs @@ -1,7 +1,4 @@ using Autodesk.Revit.DB; -using System; -using System.Collections.Generic; -using System.Text; namespace ConverterRevitShared.Revit; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitCommitObjectBuilder.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitCommitObjectBuilder.cs index 179134568b..ab0aeca082 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitCommitObjectBuilder.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitCommitObjectBuilder.cs @@ -5,11 +5,8 @@ using Speckle.Core.Models; using Autodesk.Revit.DB; using System.Text.RegularExpressions; -using Autodesk.Revit.DB.Plumbing; using Objects.Converter.Revit; -using Autodesk.Revit.DB.Mechanical; using RevitSharedResources.Interfaces; -using Autodesk.Revit.DB.Electrical; namespace ConverterRevitShared; @@ -209,7 +206,7 @@ private static string GetCategoryId(Base conversionResult, Element revitElement) Autodesk.Revit.DB.FamilyInstance i => i.Host, Autodesk.Revit.DB.Opening i => i.Host, Autodesk.Revit.DB.DividedSurface i => i.Host, - Autodesk.Revit.DB.FabricationPart i => i.Document.GetElement(i.GetHostedInfo()?.HostId), + Autodesk.Revit.DB.FabricationPart i => HandleFabricationPart(i), Autodesk.Revit.DB.DisplacementElement i => i.Document.GetElement(i.ParentId), Autodesk.Revit.DB.Architecture.ContinuousRail i => i.Document.GetElement(i.HostRailingId), Autodesk.Revit.DB.Architecture.BuildingPad i => i.Document.GetElement(i.HostId), @@ -226,6 +223,19 @@ private static string GetCategoryId(Base conversionResult, Element revitElement) }; } + /// + /// Processes a FabricationPart to retrieve its associated host element. FabricationPart class has no HasHost method. + /// + /// The FabricationPart to process. + /// + /// The host element of the given FabricationPart, or null if no host is associated. + /// + private static Element? HandleFabricationPart(FabricationPart fabricationPart) + { + var hostedInfo = fabricationPart.GetHostedInfo(); + return hostedInfo == null ? null : fabricationPart.Document.GetElement(hostedInfo.HostId); + } + /// /// We want to display a user-friendly category names when grouping objects /// For this we are simplifying the BuiltIn one as otherwise, by using the display value, we'd be getting localized category names diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitVersionHelper.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitVersionHelper.cs index f7c7f1b9dd..35e2f9cbfd 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitVersionHelper.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitVersionHelper.cs @@ -31,7 +31,7 @@ public static string Version public static double ConvertToInternalUnits(object value, string applicationUnit) { #if REVIT2020 - Enum.TryParse(applicationUnit, out DisplayUnitType sourceUnit); + _ = Enum.TryParse(applicationUnit, out DisplayUnitType sourceUnit); return UnitUtils.ConvertToInternalUnits(Convert.ToDouble(value), sourceUnit); #else // if a commit is sent in <=2021 and received in 2022+, the application unit will be a different format @@ -97,7 +97,7 @@ public static bool IsCurveClosed(NurbSpline curve) { return curve.IsClosed; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { return true; } @@ -123,7 +123,7 @@ public static bool IsCurveClosed(Curve curve) { return curve.IsClosed; } - catch + catch (Autodesk.Revit.Exceptions.ApplicationException) { return true; } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/Globals.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/Globals.cs index 335c7ad837..d6d27f23ac 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/Globals.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/Globals.cs @@ -1,6 +1,5 @@ using System.IO; using System.Linq; -using Autodesk.Revit.DB; namespace ConverterRevitTests; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionFixture.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionFixture.cs index d08d467c7a..fac2fda6a0 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionFixture.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Threading.Tasks; using Autodesk.Revit.DB; -using Speckle.Newtonsoft.Json; using Xunit; using xUnitRevitUtils; using DB = Autodesk.Revit.DB; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionTest.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionTest.cs index f537be6472..a085dd7ee8 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionTest.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleConversionTest.cs @@ -4,6 +4,7 @@ using Objects.Converter.Revit; using RevitSharedResources.Models; using Speckle.ConnectorRevit.UI; +using Speckle.Core.Logging; using Speckle.Core.Models; using System; using System.Collections.Generic; @@ -190,9 +191,9 @@ await SpeckleUtils.RunInTransaction( { res = converter.ConvertToNative(el); } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - converter.Report.LogConversionError(new Exception(e.Message, e)); + converter.Report.LogConversionError(ex); } if (res is List apls) diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleUtils.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleUtils.cs index 22ee0360ba..bf56735030 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleUtils.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/ConverterRevitTestsShared/SpeckleUtils.cs @@ -17,7 +17,7 @@ internal static class SpeckleUtils { public static SemaphoreSlim Throttler = new(1, 1); - internal async static Task RunInTransaction( + internal static async Task RunInTransaction( Action action, DB.Document doc, ConverterRevit converter = null, @@ -37,6 +37,7 @@ await APIContext.Run(() => converter.SetContextDocument(transactionManager); } +#pragma warning disable CA1031 // Do not catch general exception types try { action.Invoke(); @@ -46,6 +47,7 @@ await APIContext.Run(() => { tcs.TrySetException(exception); } +#pragma warning restore CA1031 // Do not catch general exception types tcs.TrySetResult(""); }); @@ -101,7 +103,7 @@ internal static void DeleteElement(object obj) .Wait(); } // element already deleted, don't worry about it - catch { } + catch (Autodesk.Revit.Exceptions.ArgumentException) { } break; default: throw new Exception("It's not an element!?!?!"); @@ -148,7 +150,7 @@ internal static void CustomAssertions(DB.Element element, Base @base) { stringAssertionMethod(param.AsValueString(), baseString); } - catch (Exception ex) + catch (Autodesk.Revit.Exceptions.ApplicationException) { stringAssertionMethod(param.AsString(), baseString); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Categories.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Categories.cs index 24c346ed7b..377d6e8921 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Categories.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Categories.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; namespace TestGenerator; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Generator.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Generator.cs index 97788bcc16..d3d9c37029 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Generator.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Generator.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Text; using Microsoft.CodeAnalysis; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Globals.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Globals.cs index e1ef0c3e57..5ec4759c20 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Globals.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/Globals.cs @@ -1,4 +1,3 @@ -using System.IO; using System.Linq; namespace TestGenerator; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/TestTemplate.cs b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/TestTemplate.cs index 1e57e3471b..a2e592cb24 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/TestTemplate.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitTests/TestGenerator/TestTemplate.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace TestGenerator; internal static class TestTemplate diff --git a/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper6/ConverterGrasshopper6.csproj b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper6/ConverterGrasshopper6.csproj index 25c9f10097..ac176eb015 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper6/ConverterGrasshopper6.csproj +++ b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper6/ConverterGrasshopper6.csproj @@ -12,11 +12,11 @@ - TRACE;RHINO6;GRASSHOPPER + TRACE;RHINO6;GRASSHOPPER;RHINO6_OR_GREATER - TRACE;RHINO6;GRASSHOPPER + TRACE;RHINO6;GRASSHOPPER;RHINO6_OR_GREATER diff --git a/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper7/ConverterGrasshopper7.csproj b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper7/ConverterGrasshopper7.csproj index 092faf6b03..09f1753274 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper7/ConverterGrasshopper7.csproj +++ b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper7/ConverterGrasshopper7.csproj @@ -8,7 +8,7 @@ Objects.Converter.Rhino none true - $(DefineConstants);RHINO7;GRASSHOPPER + $(DefineConstants);RHINO7;GRASSHOPPER;RHINO6_OR_GREATER;RHINO7_OR_GREATER diff --git a/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper8/ConverterGrasshopper8.csproj b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper8/ConverterGrasshopper8.csproj new file mode 100644 index 0000000000..2f1f2f6af9 --- /dev/null +++ b/Objects/Converters/ConverterRhinoGh/ConverterGrasshopper8/ConverterGrasshopper8.csproj @@ -0,0 +1,28 @@ + + + net48 + Objects.Converter.Grasshopper7 + Speckle.Objects.Converter.Grasshopper8 + $(PackageTags) objects converter rhino grasshopper gh + Objects.Converter.Grasshopper8 + Objects.Converter.Rhino + none + true + $(DefineConstants);RHINO8;GRASSHOPPER;RHINO6_OR_GREATER;RHINO7_OR_GREATER;RHINO8_OR_GREATER + + + + + + + + + + + + + + + + + diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhino6/ConverterRhino6.csproj b/Objects/Converters/ConverterRhinoGh/ConverterRhino6/ConverterRhino6.csproj index 572f11e796..a46fa8cbad 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhino6/ConverterRhino6.csproj +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhino6/ConverterRhino6.csproj @@ -12,11 +12,11 @@ - TRACE;RHINO6 + TRACE;RHINO6;RHINO6_OR_GREATER - TRACE;RHINO6 + TRACE;RHINO6;RHINO6_OR_GREATER diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhino7/ConverterRhino7.csproj b/Objects/Converters/ConverterRhinoGh/ConverterRhino7/ConverterRhino7.csproj index 2376611602..3c83a7c0d9 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhino7/ConverterRhino7.csproj +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhino7/ConverterRhino7.csproj @@ -30,12 +30,12 @@ - TRACE;RHINO7 + TRACE;RHINO7;RHINO6_OR_GREATER;RHINO7_OR_GREATER x64 - TRACE;RHINO7 + TRACE;RHINO7;RHINO6_OR_GREATER;RHINO7_OR_GREATER x64 diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhino8/ConverterRhino8.csproj b/Objects/Converters/ConverterRhinoGh/ConverterRhino8/ConverterRhino8.csproj new file mode 100644 index 0000000000..10b9b41863 --- /dev/null +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhino8/ConverterRhino8.csproj @@ -0,0 +1,48 @@ + + + + net7.0-windows + Objects.Converter.Rhino8 + Converter for Rhino and Grasshopper + .dll + Speckle.Objects.Converter.Rhino8 + $(PackageTags) objects converter rhino + Objects.Converter.Rhino8 + Objects.Converter.Rhino + none + true + true + + + + + + + + + + + + + + + + + + + + + + + + TRACE;RHINO8;RHINO6_OR_GREATER;RHINO7_OR_GREATER;RHINO8_OR_GREATER + x64 + + + + TRACE;RHINO8;RHINO6_OR_GREATER;RHINO7_OR_GREATER;RHINO8_OR_GREATER + x64 + + + + diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/BrepEncoder.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/BrepEncoder.cs index b70e40b98e..adb2606fdc 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/BrepEncoder.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/BrepEncoder.cs @@ -133,7 +133,7 @@ double modelRelativeTolerance } kinkyEdges += edges.Count - edgeCount; -#if RHINO7 +#if RHINO7_OR_GREATER microEdges += edges.RemoveNakedMicroEdges(modelRelativeTolerance, true); #endif mergedEdges += edges.MergeAllEdges(modelAngleToleranceRadians) - edgeCount; diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Geometry.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Geometry.cs index 514362c7ce..1f5c20d0fc 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Geometry.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Geometry.cs @@ -3,6 +3,7 @@ #endif using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using Objects.Geometry; @@ -437,7 +438,7 @@ public RH.PolyCurve PolycurveToNative(Polycurve p) //let the converter pick the best type of curve myPolyc.Append((RH.Curve)ConvertToNative((Base)segment)); } - catch + catch (Exception ex) when (!ex.IsFatal()) { notes.Add($"Could not append curve {segment.GetType()} to PolyCurve"); } @@ -683,7 +684,7 @@ public Mesh MeshToSpeckle(RH.Mesh mesh, string units = null) return speckleMesh; } -#if RHINO7 +#if RHINO7_OR_GREATER public Mesh MeshToSpeckle(RH.SubD mesh, string units = null) { var u = units ?? ModelUnits; @@ -769,7 +770,7 @@ public RH.Mesh MeshToNative(Mesh mesh) } m.Faces.CullDegenerateFaces(); -#if RHINO7 +#if RHINO7_OR_GREATER // get receive mesh setting var meshSetting = Settings.ContainsKey("receive-mesh") ? Settings["receive-mesh"] @@ -986,7 +987,7 @@ private RH.Mesh GetBrepDisplayMesh(RH.Brep brep) joinedMesh.Append(RH.Mesh.CreateFromBrep(brep, mySettings)); return joinedMesh; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { return null; } @@ -1076,14 +1077,16 @@ public RH.Brep BrepToNative(Brep brep, out List notes) return newBrep; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - notes.Add(e.ToFormattedString()); + notes.Add(ex.ToFormattedString()); return null; } } // TODO: We're no longer creating new extrusions - they are converted as brep. This is here just for backwards compatibility. + [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Obsolete")] + [Obsolete("Unused")] public RH.Extrusion ExtrusionToNative(Extrusion extrusion) { RH.Curve outerProfile = CurveToNative((Curve)extrusion.profile); diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Mappings.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Mappings.cs index c04c0451b7..139bd1b056 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Mappings.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Mappings.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.DoubleNumerics; using Rhino.DocObjects; using RH = Rhino.Geometry; using Speckle.Core.Api; @@ -12,7 +11,7 @@ using Objects.BuiltElements.Revit; using Objects.Geometry; using Objects.Other; -using Plane = Objects.Geometry.Plane; +using Speckle.Core.Logging; namespace Objects.Converter.RhinoGh; @@ -189,7 +188,7 @@ private Base MappingToSpeckle(string mapping, RhinoObject @object, List notes.Add($"Attached {schemaObject.speckle_type} schema"); } - catch (Exception ex) + catch (Exception ex) when (!ex.IsFatal()) { notes.Add($"Could not attach {schemaObject.speckle_type} schema: {ex.Message}"); } diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Organization.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Organization.cs index 2e188dfa70..df1aa8fee5 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Organization.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Organization.cs @@ -1,6 +1,4 @@ -using System; using System.Drawing; -using Objects.Organization; using Objects.Other; using Rhino; using Rhino.DocObjects; @@ -35,26 +33,19 @@ Layer GetLayer(string path) } Layer MakeLayer(string name, Layer parentLayer = null) { - try + Layer newLayer = new() { Name = name }; + if (parentLayer != null) { - Layer newLayer = new() { Name = name }; - if (parentLayer != null) - { - newLayer.ParentLayerId = parentLayer.Id; - } - - int newIndex = Doc.Layers.Add(newLayer); - if (newIndex < 0) - { - return null; - } - - return Doc.Layers.FindIndex(newIndex); + newLayer.ParentLayerId = parentLayer.Id; } - catch (Exception e) + + int newIndex = Doc.Layers.Add(newLayer); + if (newIndex < 0) { return null; } + + return Doc.Layers.FindIndex(newIndex); } #endregion @@ -62,14 +53,14 @@ Layer MakeLayer(string name, Layer parentLayer = null) { applicationId = collection.applicationId }; - Layer layer = null; - var status = ApplicationObject.State.Unknown; // see if this layer already exists in the doc - var layerPath = RemoveInvalidRhinoChars(collection["path"] as string); + var layerPath = MakeValidPath(collection["path"] as string); Layer existingLayer = GetLayer(layerPath); // update this layer if it exists & receive mode is on update + Layer layer; + ApplicationObject.State status; if (existingLayer != null && ReceiveMode == ReceiveMode.Update) { layer = existingLayer; diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Other.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Other.cs index fff4047788..934809c384 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Other.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Other.cs @@ -7,7 +7,6 @@ using Objects.Other; using Rhino.Display; using Rhino.Geometry; -using Rhino.Render; using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; @@ -20,6 +19,10 @@ using Transform = Rhino.Geometry.Transform; using Utilities = Speckle.Core.Models.Utilities; +#if RHINO7_OR_GREATER +using Rhino.Render; +#endif + namespace Objects.Converter.RhinoGh; public partial class ConverterRhinoGh @@ -34,7 +37,7 @@ public RH.ObjectAttributes DisplayStyleToNative(DisplayStyle display) var colorSource = RH.ObjectColorSource.ColorFromObject; if (display["colorSource"] != null) { - Enum.TryParse(display["colorSource"] as string, out colorSource); + _ = Enum.TryParse(display["colorSource"] as string, out colorSource); } attributes.ColorSource = colorSource; @@ -45,7 +48,7 @@ public RH.ObjectAttributes DisplayStyleToNative(DisplayStyle display) var lineSource = RH.ObjectLinetypeSource.LinetypeFromObject; if (display["lineSource"] != null) { - Enum.TryParse(display["lineSource"] as string, out lineSource); + _ = Enum.TryParse(display["lineSource"] as string, out lineSource); } attributes.LinetypeSource = lineSource; @@ -57,7 +60,7 @@ public RH.ObjectAttributes DisplayStyleToNative(DisplayStyle display) var weightSource = RH.ObjectPlotWeightSource.PlotWeightFromObject; if (display["weightSource"] != null) { - Enum.TryParse(display["weightSource"] as string, out weightSource); + _ = Enum.TryParse(display["weightSource"] as string, out weightSource); } attributes.PlotWeightSource = weightSource; @@ -272,10 +275,20 @@ public Other.RenderMaterial RenderMaterialToSpeckle(Rhino.Render.RenderMaterial public Hatch[] HatchToNative(Other.Hatch hatch) { var curves = new List(); - curves = - hatch.loops != null - ? hatch.loops.Select(o => CurveToNative(o.Curve)).ToList() - : hatch.curves.Select(o => CurveToNative(o)).ToList(); + if (hatch.loops != null) + { + curves = hatch.loops.Select(o => CurveToNative(o.Curve)).ToList(); + } + else if (hatch.curves is not null) // this could've been an old hatch, using the deprecated loops property + { + curves = hatch.curves.Select(o => CurveToNative(o))?.ToList(); + } + + if (curves.Count == 0) + { + throw new ArgumentException("Hatch did not contain any loops or curves."); + } + var pattern = Doc.HatchPatterns.FindName(hatch.pattern); int index; if (pattern == null) @@ -629,21 +642,9 @@ public ApplicationObject InstanceToNative(Instance instance, bool AppendToModelS // get the transform var transform = TransformToNative(instance.transform); - // get any parameters - var parameters = instance["parameters"] as Base; + // set attributes var attributes = new RH.ObjectAttributes(); - if (parameters != null) - { - foreach (var member in parameters.GetMembers(DynamicBaseMemberType.Dynamic)) - { - if (member.Value is Parameter parameter) - { - var convertedParameter = ParameterToNative(parameter); - var name = $"{convertedParameter.Item1}({member.Key})"; - attributes.SetUserString(name, convertedParameter.Item2); - } - } - } + SetUserInfo(instance, attributes); // create the instance Guid instanceId = Doc.Objects.AddInstanceObject(instanceDef.Index, transform, attributes); diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Structural.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Structural.cs index f5d7a80ca6..8779b4c7f9 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Structural.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Structural.cs @@ -1,8 +1,5 @@ -#if GRASSHOPPER -#endif using Objects.Structural.Geometry; using RH = Rhino.Geometry; -using RV = Objects.BuiltElements.Revit; namespace Objects.Converter.RhinoGh; diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs index cc17605e84..47d0c30d3d 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs @@ -16,18 +16,43 @@ namespace Objects.Converter.RhinoGh; public partial class ConverterRhinoGh { - public static string invalidRhinoChars = @"{}()"; + public static string invalidRhinoChars = @"{}()[]"; /// - /// Removes invalid characters for Rhino layer and block names + /// Creates a valid name for Rhino layers, blocks, and named views. + /// + /// Layer, block, or named view name + /// The original name if valid, or "@name" if not. + /// From trial and error, names cannot begin with invalidRhinoChars. This has been encountered in grasshopper branch syntax. + public static string MakeValidName(string str) + { + return string.IsNullOrEmpty(str) + ? str + : invalidRhinoChars.Contains(str[0]) + ? $"@{str}" + : str; + } + + /// + /// Creates a valid path for Rhino layers. /// /// /// - public static string RemoveInvalidRhinoChars(string str) + public static string MakeValidPath(string str) { - // using this to handle grasshopper branch syntax - string cleanStr = str.Replace("{", "").Replace("}", ""); - return cleanStr; + if (string.IsNullOrEmpty(str)) + { + return str; + } + + string validPath = ""; + string[] layerNames = str.Split(new string[] { Layer.PathSeparator }, StringSplitOptions.None); + foreach (var item in layerNames) + { + validPath += string.IsNullOrEmpty(validPath) ? MakeValidName(item) : Layer.PathSeparator + MakeValidName(item); + } + + return validPath; } /// @@ -67,6 +92,45 @@ private string GetCommitInfo() private static string UserStrings = "userStrings"; private static string UserDictionary = "userDictionary"; + private void SetUserInfo(Base obj, ObjectAttributes attributes) + { + // set user strings + if (obj[UserStrings] is Base userStrings) + { + foreach (var member in userStrings.GetMembers(DynamicBaseMemberType.Dynamic)) + { + attributes.SetUserString(member.Key, member.Value as string); + } + } + + // set application id + if (!string.IsNullOrWhiteSpace(obj.applicationId)) + { + attributes.SetUserString(ApplicationIdKey, obj.applicationId); + } + + // set name or label + var name = obj["name"] as string ?? obj["label"] as string; // gridlines have a "label" prop instead of name? + if (name != null) + { + attributes.Name = name; + } + + // set revit parameters as user strings + if (obj["parameters"] is Base parameters) + { + foreach (var member in parameters.GetMembers(DynamicBaseMemberType.Dynamic)) + { + if (member.Value is Objects.BuiltElements.Revit.Parameter parameter) + { + var convertedParameter = ParameterToNative(parameter); + var paramName = $"{convertedParameter.Item1}({member.Key})"; + attributes.SetUserString(paramName, convertedParameter.Item2); + } + } + } + } + /// /// Attaches the provided user strings, user dictionaries, and and name to Base /// @@ -92,9 +156,9 @@ public void GetUserInfo( { userStringsBase[key] = userStrings[key]; } - catch (Exception e) + catch (Exception ex) when (!ex.IsFatal()) { - notes.Add($"Could not attach user string: {e.Message}"); + notes.Add($"Could not attach user string: {ex.Message}"); } } @@ -237,7 +301,6 @@ private string UnitToSpeckle(UnitSystem us) #endregion #region Layers - public static Layer GetLayer(RhinoDoc doc, string path, out int index, bool MakeIfNull = false) { index = doc.Layers.FindByFullPath(path, RhinoMath.UnsetIntIndex); @@ -255,7 +318,7 @@ public static Layer GetLayer(RhinoDoc doc, string path, out int index, bool Make currentLayer = GetLayer(doc, currentLayerPath, out index); if (currentLayer == null) { - currentLayer = MakeLayer(doc, layerNames[i], out index, parent); + currentLayer = MakeLayer(doc, layerNames[i], parent); } if (currentLayer == null) @@ -270,23 +333,42 @@ public static Layer GetLayer(RhinoDoc doc, string path, out int index, bool Make return layer; } - private static Layer MakeLayer(RhinoDoc doc, string name, out int index, Layer parentLayer = null) + /// + /// Creates a layer from its name and parent + /// + /// + /// + /// + /// The new layer + /// Layer name is invalid. + /// Layer parent could not be set, or a layer with the same name already exists. + public static Layer MakeLayer(RhinoDoc doc, string name, Layer parentLayer = null) { - index = -1; - Layer newLayer = new() { Color = Color.White, Name = name }; + if (!Layer.IsValidName(name)) + { + throw new ArgumentException("Layer name is invalid."); + } + + Layer newLayer = new() { Color = Color.AliceBlue, Name = name }; if (parentLayer != null) { - newLayer.ParentLayerId = parentLayer.Id; + try + { + newLayer.ParentLayerId = parentLayer.Id; + } + catch (Exception e) + { + throw new InvalidOperationException("Could not set layer parent id.", e); + } } int newIndex = doc.Layers.Add(newLayer); - if (newIndex < 0) + if (newIndex is -1) { - return null; + throw new InvalidOperationException("A layer with the same name already exists."); } - index = newIndex; - return doc.Layers.FindIndex(newIndex); + return newLayer; } #endregion diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs index 41c8ec39c3..b467aad06a 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs @@ -1,31 +1,31 @@ -#if GRASSHOPPER -using Grasshopper.Kernel.Types; -#endif using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; -using System.DoubleNumerics; using System.Reflection; using Objects.BuiltElements; using Objects.BuiltElements.Revit; using Objects.BuiltElements.Revit.Curve; using Objects.Geometry; -using Objects.Organization; using Objects.Other; using Objects.Primitive; using Objects.Structural.Geometry; using Rhino; using Rhino.Collections; -using Rhino.Display; + using Rhino.DocObjects; -using Speckle.Core.Api; using Speckle.Core.Kits; +using Speckle.Core.Logging; using Speckle.Core.Models; using Plane = Objects.Geometry.Plane; using RH = Rhino.Geometry; using Vector = Objects.Geometry.Vector; +#if GRASSHOPPER +using Grasshopper.Kernel.Types; +using Rhino.Display; +#endif + namespace Objects.Converter.RhinoGh; public partial class ConverterRhinoGh : ISpeckleConverter @@ -34,10 +34,14 @@ public partial class ConverterRhinoGh : ISpeckleConverter public static string RhinoAppName = HostApplications.Grasshopper.GetVersion(HostAppVersion.v6); #elif RHINO7 && GRASSHOPPER public static string RhinoAppName = HostApplications.Grasshopper.GetVersion(HostAppVersion.v7); +#elif RHINO8 && GRASSHOPPER + public static string RhinoAppName = HostApplications.Grasshopper.GetVersion(HostAppVersion.v8); #elif RHINO6 public static string RhinoAppName = HostApplications.Rhino.GetVersion(HostAppVersion.v6); #elif RHINO7 public static string RhinoAppName = HostApplications.Rhino.GetVersion(HostAppVersion.v7); +#elif RHINO8 + public static string RhinoAppName = HostApplications.Rhino.GetVersion(HostAppVersion.v8); #endif [Obsolete] @@ -104,7 +108,7 @@ public void SetConverterSettings(object settings) if (Settings.TryGetValue("preprocessGeometry", out string setting)) { - bool.TryParse(setting, out PreprocessGeometry); + _ = bool.TryParse(setting, out PreprocessGeometry); } } @@ -293,7 +297,7 @@ public Base ConvertToSpeckle(object @object) break; #endif -#if RHINO7 +#if RHINO7_OR_GREATER case RH.SubD o: if (o.HasBrepForm) { @@ -334,16 +338,9 @@ public Base ConvertToSpeckle(object @object) @base = LayerToSpeckle(o); break; default: - if (reportObj != null) - { - reportObj.Update( - status: ApplicationObject.State.Skipped, - logItem: $"{@object.GetType()} type not supported" - ); - Report.UpdateReportObject(reportObj); - } - - return @base; + throw new ConversionNotSupportedException( + $"Rhino object of type {@object.GetType()} is not supported for conversion." + ); } if (@base is null) @@ -371,7 +368,20 @@ public Base ConvertToSpeckle(object @object) @base["@SpeckleSchema"] = schema; } } - catch (Exception ex) + catch (ConversionNotSupportedException e) + { + SpeckleLog.Logger.Information(e, "{exceptionMessage}"); + reportObj?.Update(status: ApplicationObject.State.Skipped, logItem: e.Message); + } + catch (SpeckleException e) + { + SpeckleLog.Logger.Warning(e, "{exceptionMessage}"); + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); + } + catch (Exception ex) when (!ex.IsFatal()) { reportObj?.Update( status: ApplicationObject.State.Failed, @@ -560,48 +570,48 @@ public object ConvertToNative(Base @object) break; default: - if (reportObj != null) - { - reportObj.Update( - status: ApplicationObject.State.Skipped, - logItem: $"{@object.GetType()} type not supported" - ); - Report.UpdateReportObject(reportObj); - } - - break; + throw new ConversionNotSupportedException( + $"Speckle object of type {@object.GetType()} is not supported for conversion." + ); } } - catch (Exception ex) + catch (ConversionNotSupportedException e) + { + SpeckleLog.Logger.Information(e, "{exceptionMessage}"); + reportObj?.Update(status: ApplicationObject.State.Skipped, logItem: e.Message); + } + catch (SpeckleException e) { - reportObj.Update( + SpeckleLog.Logger.Warning(e, "{exceptionMessage}"); + reportObj?.Update( status: ApplicationObject.State.Failed, - logItem: $"{@object.GetType()} unhandled converion error: {ex.Message}\n{ex.StackTrace}" + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" + ); + } + catch (Exception e) when (!e.IsFatal()) + { + reportObj?.Update( + status: ApplicationObject.State.Failed, + logItem: $"{@object.GetType()} unhandled conversion error: {e.Message}\n{e.StackTrace}" ); } switch (rhinoObj) { case ApplicationObject o: // some to native methods return an application object (if object is baked to doc during conv) - rhinoObj = o.Converted.Any() ? o.Converted : null; - if (reportObj != null) - { - reportObj.Update( - status: o.Status, - createdIds: o.CreatedIds, - converted: o.Converted, - container: o.Container, - log: o.Log - ); - } + rhinoObj = o.Converted.Count == 0 ? null : o.Converted; + reportObj?.Update( + status: o.Status, + createdIds: o.CreatedIds, + converted: o.Converted, + container: o.Container, + log: o.Log + ); break; default: - if (reportObj != null) - { - reportObj.Update(log: notes); - } + reportObj?.Update(log: notes); break; } @@ -653,7 +663,7 @@ public bool CanConvertToSpeckle(object @object) case RH.NurbsCurve _: case RH.Box _: case RH.Mesh _: -#if RHINO7 +#if RHINO7_OR_GREATER case RH.SubD _: #endif case RH.Extrusion _: diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/ConverterTeklaStructureUtils.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/ConverterTeklaStructureUtils.cs index cb1ee0bd8e..7efd4c3f93 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/ConverterTeklaStructureUtils.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/ConverterTeklaStructureUtils.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; -using Objects.Structural.Geometry; using Tekla.Structures.Model; using System.Linq; using Objects.Geometry; @@ -14,6 +12,7 @@ using Objects.Structural.Properties.Profiles; using Tekla.Structures.Datatype; using Objects.BuiltElements.TeklaStructures; +using Speckle.Core.Logging; namespace Objects.Converter.TeklaStructures; @@ -159,9 +158,17 @@ public void GetAllUserProperties(Base speckleElement, ModelObject teklaObject, L { paramBase[kv.Key] = kv.Value; } - catch + // The exceptions here are thrown by the DynamicBase class for properties that cannot be set. + // The errors themselves are not fatal and should simply be logged. + catch (Exception ex) when (ex is InvalidPropNameException or SpeckleException) { - //ignore + string exceptionDetail = ex is InvalidPropNameException ? "due to an invalid name" : ""; + + SpeckleLog.Logger.Warning( + $"Element {teklaObject.Identifier.GUID} has a " + + $"property named {kv.Key} that cannot be set " + + $"{exceptionDetail}. Skipping." + ); } } @@ -169,7 +176,6 @@ public void GetAllUserProperties(Base speckleElement, ModelObject teklaObject, L { speckleElement["parameters"] = paramBase; } - //speckleElement["elementId"] = revitElement.Id.ToString(); speckleElement.applicationId = teklaObject.Identifier.GUID.ToString(); speckleElement["units"] = GetUnitsFromModel(); } diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBeam.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBeam.cs index 4af262e24b..8ad1e75f55 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBeam.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBeam.cs @@ -1,17 +1,10 @@ using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; using Objects.BuiltElements.TeklaStructures; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; using TSG = Tekla.Structures.Geometry3d; -using System.Collections; -using StructuralUtilities.PolygonMesher; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBentPlate.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBentPlate.cs index 0f63ae8c20..b879949548 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBentPlate.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBentPlate.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace ConverterTeklaStructuresShared.Partial_Classes; class ConvertBentPlate { } diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBolts.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBolts.cs index 19bc7d6106..12ed0c49c2 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBolts.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBolts.cs @@ -1,15 +1,8 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; using TSG = Tekla.Structures.Geometry3d; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBooleanPart.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBooleanPart.cs index 0f90085ff5..dffb6ef6a9 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBooleanPart.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertBooleanPart.cs @@ -1,16 +1,8 @@ -using System; -using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; using Objects.BuiltElements.TeklaStructures; using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertContourPlate.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertContourPlate.cs index 854e5c3272..deaed09493 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertContourPlate.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertContourPlate.cs @@ -1,16 +1,9 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; using Objects.BuiltElements.TeklaStructures; using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertDirectShapeMesh.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertDirectShapeMesh.cs index 728edb183c..6b310c4363 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertDirectShapeMesh.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertDirectShapeMesh.cs @@ -1,17 +1,10 @@ using System; using System.Collections.Generic; using GE = Objects.Geometry; -using GES = Objects.Structural.Geometry; -using Objects.Structural.Analysis; using Speckle.Core.Models; -using BE = Objects.BuiltElements; -using Objects.BuiltElements.TeklaStructures; using System.Linq; +using Speckle.Core.Kits; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; -using Tekla.Structures.Model.UI; using Tekla.Structures.Geometry3d; using Tekla.Structures.Catalogs; @@ -19,9 +12,23 @@ namespace Objects.Converter.TeklaStructures; public partial class ConverterTeklaStructures { + /// + /// Converts a list of Mesh objects to their native representations. + /// + /// The base object being converted. + /// A list of GE.Mesh objects to be converted. + /// + /// Exception handling is specifically tailored to the process: An ArgumentException indicating + /// that "The BRep geometry already exists" is intentionally swallowed, reflecting a scenario + /// where a duplicate shape is encountered and can be safely ignored. All other exceptions, + /// previously swallowed, are now propagated as ConversionExceptions, signaling a failure in + /// conversion or insertion. + /// + /// Thrown for any errors during conversion or insertion, + /// except when encountering duplicate BRep geometry. public void MeshToNative(Base @object, List displayValues) { - int incr = 0; + int shapeCounter = 0; foreach (var mesh in displayValues) { FacetedBrep facetedBrep = CreateFacetedBrep(mesh); @@ -29,7 +36,7 @@ public void MeshToNative(Base @object, List displayValues) // Add shape to catalog // Each shape in catalog needs to have a unique name string objectName = GetShapeName(@object); - string shapeName = "Speckle_" + objectName + (incr > 0 ? "_" + incr.ToString() : ""); + string shapeName = "Speckle_" + objectName + (shapeCounter > 0 ? "_" + shapeCounter.ToString() : ""); var shapeItem = new ShapeItem { Name = shapeName, @@ -39,13 +46,24 @@ public void MeshToNative(Base @object, List displayValues) // remove possibly pre-existing shape with same name and then insert a Speckle object shape // with that name into the catalog shapeItem.Delete(); + bool result = false; try { result = shapeItem.Insert(); - // Fails if two shapes exist with different names but same geometry fingerprint } - catch (Exception ex) { } + catch (InvalidOperationException ex) + { + throw new ConversionException("The converted Mesh could not be inserted.", ex); + } + catch (ArgumentException ex) + { + // if the exception message contains "BRep already exists", swallow the error, else rethrow + if (!ex.Message.Contains("The BRep geometry already exists")) + { + throw new ConversionException($"Failed to convert Mesh to Native: {ex.Message} ", ex); + } + } if (!result) { @@ -56,23 +74,34 @@ public void MeshToNative(Base @object, List displayValues) shapeName = matchingShape.Name; result = true; } + else + { + throw new ConversionException( + "The Mesh could either not be converted or not be inserted but no internal error occurred." + ); + } } // Insert object in model if (result) { - var brep = new Brep(); - brep.StartPoint = new Tekla.Structures.Geometry3d.Point(0, 0, 0); - brep.EndPoint = new Tekla.Structures.Geometry3d.Point(1000, 0, 0); - brep.Profile.ProfileString = shapeName; - brep.Material.MaterialString = "TS_Undefined"; - brep.Position.Depth = Position.DepthEnum.MIDDLE; - brep.Position.Plane = Position.PlaneEnum.MIDDLE; - brep.Position.Rotation = Position.RotationEnum.TOP; + var brep = new Brep + { + StartPoint = new Tekla.Structures.Geometry3d.Point(0, 0, 0), + EndPoint = new Tekla.Structures.Geometry3d.Point(1000, 0, 0), + Profile = { ProfileString = shapeName }, + Material = { MaterialString = "TS_Undefined" }, + Position = + { + Depth = Position.DepthEnum.MIDDLE, + Plane = Position.PlaneEnum.MIDDLE, + Rotation = Position.RotationEnum.TOP + } + }; brep.Insert(); } - incr++; + shapeCounter++; } //var vertex = new[] diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertFitting.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertFitting.cs index da27c841f1..fed2abb0e1 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertFitting.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertFitting.cs @@ -1,15 +1,6 @@ -using System; -using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; using TSG = Tekla.Structures.Geometry3d; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertLoftedPlates.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertLoftedPlates.cs index 534f2abc60..877e5764a1 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertLoftedPlates.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertLoftedPlates.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace ConverterTeklaStructuresShared.Partial_Classes; class ConvertLoftedPlates { } diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertModel.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertModel.cs index 29cf557b77..df8d013cec 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertModel.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertModel.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace ConverterTeklaStructuresShared.Partial_Classes; class ConvertModel { } diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolyBeam.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolyBeam.cs index d77705e715..5cb0cd3607 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolyBeam.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolyBeam.cs @@ -1,15 +1,6 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; -using BE = Objects.BuiltElements; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; using Objects.BuiltElements.TeklaStructures; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolygonWelds.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolygonWelds.cs index 5bad15bf44..0b7ea7c419 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolygonWelds.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertPolygonWelds.cs @@ -1,16 +1,7 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; -using TSG = Tekla.Structures.Geometry3d; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertRebar.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertRebar.cs index 276bfc118e..bd14bf52b4 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertRebar.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertRebar.cs @@ -1,18 +1,7 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; -using BE = Objects.BuiltElements; using Objects.BuiltElements.TeklaStructures; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using TSG = Tekla.Structures.Geometry3d; -using System.Collections; -using StructuralUtilities.PolygonMesher; -using Objects.Structural.Materials; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertSpiralBeam.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertSpiralBeam.cs index 10cc8a4933..5ca2e961cc 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertSpiralBeam.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertSpiralBeam.cs @@ -1,16 +1,5 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; -using BE = Objects.BuiltElements; -using System.Linq; -using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; -using Tekla.Structures.Geometry3d; using Objects.BuiltElements.TeklaStructures; using SpiralBeam = Objects.BuiltElements.TeklaStructures.SpiralBeam; using Point = Objects.Geometry.Point; diff --git a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertWelds.cs b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertWelds.cs index adbe3de4d9..3345e36502 100644 --- a/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertWelds.cs +++ b/Objects/Converters/ConverterTeklaStructures/ConverterTeklaStructuresShared/PartialClasses/ConvertWelds.cs @@ -1,16 +1,7 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Geometry; -using Objects.Structural.Analysis; -using Speckle.Core.Models; using BE = Objects.BuiltElements; -using System.Linq; using Tekla.Structures.Model; -using Tekla.Structures.Solid; -using System.Collections; -using StructuralUtilities.PolygonMesher; -using TSG = Tekla.Structures.Geometry3d; namespace Objects.Converter.TeklaStructures; diff --git a/Objects/Converters/StructuralUtilities/PolygonMesher/Extensions.cs b/Objects/Converters/StructuralUtilities/PolygonMesher/Extensions.cs index 93f9b78246..cc0a595c14 100644 --- a/Objects/Converters/StructuralUtilities/PolygonMesher/Extensions.cs +++ b/Objects/Converters/StructuralUtilities/PolygonMesher/Extensions.cs @@ -1,7 +1,5 @@ -using System; using System.Collections.Generic; using System.Linq; -using MathNet.Numerics; using MathNet.Spatial.Euclidean; namespace StructuralUtilities.PolygonMesher; diff --git a/Objects/Converters/StructuralUtilities/PolygonMesher/PolygonMesher.cs b/Objects/Converters/StructuralUtilities/PolygonMesher/PolygonMesher.cs index b97bd5d190..57378f8eb8 100644 --- a/Objects/Converters/StructuralUtilities/PolygonMesher/PolygonMesher.cs +++ b/Objects/Converters/StructuralUtilities/PolygonMesher/PolygonMesher.cs @@ -1,9 +1,5 @@ -using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using MathNet.Numerics.Interpolation; using MathNet.Spatial.Euclidean; namespace StructuralUtilities.PolygonMesher; diff --git a/Objects/Objects.sln b/Objects/Objects.sln index 2236905fcf..9945108d66 100644 --- a/Objects/Objects.sln +++ b/Objects/Objects.sln @@ -11,8 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Converters", "Converters", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Local Dependencies", "Local Dependencies", "{986B7226-6A4C-4881-8481-ADAFD0EC70B0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverterRevitTests", "Converters\ConverterRevit\ConverterRevitTests\ConverterRevitTests.csproj", "{D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConverterRevit", "ConverterRevit", "{1987848E-D753-4791-B89E-F74EDF136CB3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRevit2020", "Converters\ConverterRevit\ConverterRevit2020\ConverterRevit2020.csproj", "{E4006179-462F-4133-9481-219279138B93}" @@ -53,8 +51,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StructuralUtilities", "Stru EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolygonMesher", "Converters\StructuralUtilities\PolygonMesher\PolygonMesher.csproj", "{6185B1A1-0A12-44B1-8AC5-0ED48147FB21}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{528C7672-12C1-47DE-A7C0-775DDA8E7D92}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRevit2022", "Converters\ConverterRevit\ConverterRevit2022\ConverterRevit2022.csproj", "{90362309-466A-482B-814A-ADB1CE227607}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConverterBentley", "ConverterBentley", "{B539797D-13E9-4932-A2CF-05C5485F3AA4}" @@ -127,6 +123,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterCivil2024", "Conve EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterNavisworks2024", "Converters\ConverterNavisworks\ConverterNavisworks2024\ConverterNavisworks2024.csproj", "{BFBD40D4-BF2A-47B2-8F35-4371149DD1B6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterRhino8", "Converters\ConverterRhinoGh\ConverterRhino8\ConverterRhino8.csproj", "{DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverterGrasshopper8", "Converters\ConverterRhinoGh\ConverterGrasshopper8\ConverterGrasshopper8.csproj", "{738A607A-C51C-447B-AFBB-47D7FED47CA0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{985946E0-ACEC-4EF7-92D6-E0B153271393}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Objects.Tests.Unit", "Tests\Objects.Tests.Unit\Objects.Tests.Unit.csproj", "{70AB0F97-B226-44F9-8CCE-0927A9C18037}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -151,13 +155,6 @@ Global {7EF0C96C-1FD9-42B2-85CE-BFD9B10DAC06}.Release|Any CPU.Build.0 = Release|Any CPU {7EF0C96C-1FD9-42B2-85CE-BFD9B10DAC06}.Release|x64.ActiveCfg = Release|Any CPU {7EF0C96C-1FD9-42B2-85CE-BFD9B10DAC06}.Release|x64.Build.0 = Release|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Debug|x64.ActiveCfg = Debug|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Debug|x64.Build.0 = Debug|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Release|Any CPU.ActiveCfg = Debug|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Release|x64.ActiveCfg = Release|Any CPU - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C}.Release|x64.Build.0 = Release|Any CPU {E4006179-462F-4133-9481-219279138B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E4006179-462F-4133-9481-219279138B93}.Debug|Any CPU.Build.0 = Debug|Any CPU {E4006179-462F-4133-9481-219279138B93}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -246,14 +243,6 @@ Global {6185B1A1-0A12-44B1-8AC5-0ED48147FB21}.Release|Any CPU.Build.0 = Release|Any CPU {6185B1A1-0A12-44B1-8AC5-0ED48147FB21}.Release|x64.ActiveCfg = Release|Any CPU {6185B1A1-0A12-44B1-8AC5-0ED48147FB21}.Release|x64.Build.0 = Release|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Debug|Any CPU.Build.0 = Debug|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Debug|x64.ActiveCfg = Debug|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Debug|x64.Build.0 = Debug|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Release|Any CPU.ActiveCfg = Release|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Release|Any CPU.Build.0 = Release|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Release|x64.ActiveCfg = Release|Any CPU - {528C7672-12C1-47DE-A7C0-775DDA8E7D92}.Release|x64.Build.0 = Release|Any CPU {90362309-466A-482B-814A-ADB1CE227607}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {90362309-466A-482B-814A-ADB1CE227607}.Debug|Any CPU.Build.0 = Debug|Any CPU {90362309-466A-482B-814A-ADB1CE227607}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -478,13 +467,36 @@ Global {BFBD40D4-BF2A-47B2-8F35-4371149DD1B6}.Release|Any CPU.Build.0 = Release|Any CPU {BFBD40D4-BF2A-47B2-8F35-4371149DD1B6}.Release|x64.ActiveCfg = Release|x64 {BFBD40D4-BF2A-47B2-8F35-4371149DD1B6}.Release|x64.Build.0 = Release|x64 + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Debug|x64.ActiveCfg = Debug|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Debug|x64.Build.0 = Debug|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Release|Any CPU.Build.0 = Release|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Release|x64.ActiveCfg = Release|Any CPU + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9}.Release|x64.Build.0 = Release|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Debug|x64.ActiveCfg = Debug|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Debug|x64.Build.0 = Debug|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Release|Any CPU.Build.0 = Release|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Release|x64.ActiveCfg = Release|Any CPU + {738A607A-C51C-447B-AFBB-47D7FED47CA0}.Release|x64.Build.0 = Release|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Debug|x64.ActiveCfg = Debug|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Debug|x64.Build.0 = Debug|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Release|Any CPU.Build.0 = Release|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Release|x64.ActiveCfg = Release|Any CPU + {70AB0F97-B226-44F9-8CCE-0927A9C18037}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {7EF0C96C-1FD9-42B2-85CE-BFD9B10DAC06} = {986B7226-6A4C-4881-8481-ADAFD0EC70B0} - {D9C88135-B4B3-4C6C-A9D9-01A59A00BC0C} = {CCC09288-CE76-4FDB-B0C9-220112F88CD9} {1987848E-D753-4791-B89E-F74EDF136CB3} = {CCC09288-CE76-4FDB-B0C9-220112F88CD9} {E4006179-462F-4133-9481-219279138B93} = {1987848E-D753-4791-B89E-F74EDF136CB3} {BF5515B4-C97C-4FB9-9F93-1740D2B615B3} = {1987848E-D753-4791-B89E-F74EDF136CB3} @@ -541,6 +553,9 @@ Global {D6814B75-3C4F-433E-9BE8-A9CD3A476C55} = {5419488F-6509-4F16-A342-BB2BE2689E00} {C43EEDA1-2DBB-40B5-8C52-12BCBDA34D43} = {5419488F-6509-4F16-A342-BB2BE2689E00} {BFBD40D4-BF2A-47B2-8F35-4371149DD1B6} = {A2F9F9A0-0479-4FE0-83B3-AB38A9402821} + {DB55FC55-0FE8-4622-AA0B-66F5EF9737B9} = {1A35077C-2936-4A3D-8D48-65F39F76D999} + {738A607A-C51C-447B-AFBB-47D7FED47CA0} = {1A35077C-2936-4A3D-8D48-65F39F76D999} + {70AB0F97-B226-44F9-8CCE-0927A9C18037} = {985946E0-ACEC-4EF7-92D6-E0B153271393} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DA57EC2E-0A9E-4F59-B1F7-A65F76A74B74} @@ -585,6 +600,7 @@ Global Converters\ConverterBentley\ConverterBentleyShared\ConverterBentleyShared.projitems*{c3903b4e-7b1c-4508-adeb-023fee156d3d}*SharedItemsImports = 5 Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{c43eeda1-2dbb-40b5-8c52-12bcbda34d43}*SharedItemsImports = 5 Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{d6814b75-3c4f-433e-9be8-a9cd3a476c55}*SharedItemsImports = 5 + Converters\ConverterRhinoGh\ConverterRhinoGhShared\ConverterRhinoGhShared.projitems*{db55fc55-0fe8-4622-aa0b-66f5ef9737b9}*SharedItemsImports = 5 Converters\ConverterAutocadCivil\ConverterAutocadCivilShared\ConverterAutocadCivilShared.projitems*{dd4add16-65f9-46e0-a610-2b7908a966b3}*SharedItemsImports = 5 Converters\ConverterCSI\ConverterCSIShared\ConverterCSIShared.projitems*{df4d24c3-2be8-476c-8d40-33892be07b1d}*SharedItemsImports = 5 Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{e4006179-462f-4133-9481-219279138b93}*SharedItemsImports = 5 diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelBolt.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelBolt.cs index 2d55320bed..e474b51a8d 100644 --- a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelBolt.cs +++ b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelBolt.cs @@ -12,8 +12,6 @@ public abstract class AsteelBolt : Base, IAsteelObject public Base userAttributes { get; set; } public Base asteelProperties { get; set; } - - public AsteelBolt() { } } public class AsteelCircularBolt : AsteelBolt diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelGrating.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelGrating.cs index fac263aa0b..d0b94c4602 100644 --- a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelGrating.cs +++ b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelGrating.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Objects.Geometry; -using Speckle.Core.Kits; using Speckle.Core.Models; namespace Objects.BuiltElements.AdvanceSteel; diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelPlate.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelPlate.cs index 60138a0c01..a8335933ce 100644 --- a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelPlate.cs +++ b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelPlate.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Objects.Geometry; using Objects.Structural.Materials; -using Objects.Structural.Properties.Profiles; using Speckle.Core.Kits; using Speckle.Core.Models; @@ -10,14 +9,14 @@ namespace Objects.BuiltElements.AdvanceSteel; public class AsteelPlate : Area, IDisplayValue>, IHasArea, IHasVolume, IAsteelObject { [DetachProperty] - public StructuralMaterial material { get; set; } + public StructuralMaterial? material { get; set; } public Base userAttributes { get; set; } public Base asteelProperties { get; set; } [SchemaInfo("AsteelPlate", "Creates a Advance Steel plate.", "Advance Steel", "Structure")] - public AsteelPlate(Polyline outline, string units, StructuralMaterial material = null) + public AsteelPlate(Polyline outline, string units, StructuralMaterial? material = null) { this.outline = outline; this.material = material; diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/SecondaryObjects/AsteelSectionProfile.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSectionProfile.cs similarity index 100% rename from Objects/Objects/BuiltElements/AdvanceSteel/SecondaryObjects/AsteelSectionProfile.cs rename to Objects/Objects/BuiltElements/AdvanceSteel/AsteelSectionProfile.cs diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/SecondaryObjects/AsteelSectionProfileDB.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSectionProfileDB.cs similarity index 100% rename from Objects/Objects/BuiltElements/AdvanceSteel/SecondaryObjects/AsteelSectionProfileDB.cs rename to Objects/Objects/BuiltElements/AdvanceSteel/AsteelSectionProfileDB.cs diff --git a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSlab.cs b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSlab.cs index b7b4642d1c..bed8a7c882 100644 --- a/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSlab.cs +++ b/Objects/Objects/BuiltElements/AdvanceSteel/AsteelSlab.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Objects.Geometry; using Objects.Structural.Materials; -using Objects.Structural.Properties.Profiles; using Speckle.Core.Kits; using Speckle.Core.Models; @@ -10,14 +9,14 @@ namespace Objects.BuiltElements.AdvanceSteel; public class AsteelSlab : Area, IDisplayValue>, IHasArea, IHasVolume, IAsteelObject { [DetachProperty] - public StructuralMaterial material { get; set; } + public StructuralMaterial? material { get; set; } public Base userAttributes { get; set; } public Base asteelProperties { get; set; } [SchemaInfo("AsteelSlab", "Creates a Advance Steel slab.", "Advance Steel", "Structure")] - public AsteelSlab(Polyline outline, string units, StructuralMaterial material = null) + public AsteelSlab(Polyline outline, string units, StructuralMaterial? material = null) { this.outline = outline; this.material = material; diff --git a/Objects/Objects/BuiltElements/Alignment.cs b/Objects/Objects/BuiltElements/Alignment.cs index 76c61b162a..476ee5208b 100644 --- a/Objects/Objects/BuiltElements/Alignment.cs +++ b/Objects/Objects/BuiltElements/Alignment.cs @@ -4,55 +4,35 @@ using Speckle.Core.Models; using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Alignment : Base, IDisplayValue - { - [JsonIgnore, Obsolete("Use curves property")] - public ICurve baseCurve { get; set; } - - public List curves { get; set; } - - public string name { get; set; } - - public double startStation { get; set; } +namespace Objects.BuiltElements; - public double endStation { get; set; } - - public List profiles { get; set; } +public class Alignment : Base, IDisplayValue +{ + [JsonIgnore, Obsolete("Use curves property")] + public ICurve baseCurve { get; set; } - /// - /// Station equation list contains doubles indicating raw station back, station back, and station ahead for each station equation - /// - public List stationEquations { get; set; } + public List curves { get; set; } - /// - /// Station equation direction for the corresponding station equation should be true for increasing or false for decreasing - /// - public List stationEquationDirections { get; set; } + public string name { get; set; } - public string units { get; set; } + public double startStation { get; set; } - [DetachProperty] - public Polyline displayValue { get; set; } - } -} + public double endStation { get; set; } -namespace Objects.BuiltElements.Civil -{ - public class CivilAlignment : Alignment - { - public string type { get; set; } + public List profiles { get; set; } - public string site { get; set; } + /// + /// Station equation list contains doubles indicating raw station back, station back, and station ahead for each station equation + /// + public List stationEquations { get; set; } - public string style { get; set; } + /// + /// Station equation direction for the corresponding station equation should be true for increasing or false for decreasing + /// + public List stationEquationDirections { get; set; } - public double offset { get; set; } + public string units { get; set; } - /// - /// Name of parent alignment if this is an offset alignment - /// - public string parent { get; set; } - } + [DetachProperty] + public Polyline displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadBeam.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadBeam.cs new file mode 100644 index 0000000000..4964a78b76 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadBeam.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Speckle.Core.Kits; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_beamtype +*/ +public class ArchicadBeam : Beam +{ + [SchemaInfo("ArchicadBeam", "Creates an Archicad beam by curve.", "Archicad", "Structure")] + public ArchicadBeam() { } + + // Element base + public string? elementType { get; set; } /*APINullabe*/ + + public List? classifications { get; set; } /*APINullabe*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + internal set + { + if (value is ArchicadLevel or null) + { + archicadLevel = value as ArchicadLevel; + } + else + { + throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); + } + } + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ + + public string? layer { get; set; } /*APINullabe*/ + + // Positioning + public Point begC { get; set; } + public Point endC { get; set; } + public bool? isSlanted { get; set; } /*APINullabe*/ + public double? slantAngle { get; set; } /*APINullabe*/ + public string? beamShape { get; set; } /*APINullabe*/ + public int? sequence { get; set; } /*APINullabe*/ + public double? curveAngle { get; set; } /*APINullabe*/ + public double? verticalCurveHeight { get; set; } /*APINullabe*/ + public bool? isFlipped { get; set; } /*APINullabe*/ + + // End Cuts + public uint? nCuts { get; set; } /*APINullabe*/ + public Dictionary? Cuts { get; set; } + + // Reference Axis + public short? anchorPoint { get; set; } /*APINullabe*/ + public double? offset { get; set; } + public double? profileAngle { get; set; } + + // Segment + public uint? nSegments { get; set; } /*APINullabe*/ + public uint? nProfiles { get; set; } /*APINullabe*/ + public Dictionary? segments { get; set; } /*APINullabe*/ + + // Scheme + public uint? nSchemes { get; set; } + public Dictionary? Schemes { get; set; } + + // Hole + public Dictionary? Holes { get; set; } + + // Floor Plan and Section - Floor Plan Display + public string? showOnStories { get; set; } /*APINullabe*/ + public string? displayOptionName { get; set; } /*APINullabe*/ + public string? uncutProjectionMode { get; set; } /*APINullabe*/ + public string? overheadProjectionMode { get; set; } /*APINullabe*/ + public string? showProjectionName { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cut Surfaces + public short? cutContourLinePen { get; set; } + public string? cutContourLineType { get; set; } + public short? overrideCutFillPen { get; set; } + public short? overrideCutFillBackgroundPen { get; set; } + + // Floor Plan and Section - Outlines + public string? showOutline { get; set; } /*APINullabe*/ + public short? uncutLinePen { get; set; } /*APINullabe*/ + public string? uncutLinetype { get; set; } /*APINullabe*/ + public short? overheadLinePen { get; set; } /*APINullabe*/ + public string? overheadLinetype { get; set; } /*APINullabe*/ + public short? hiddenLinePen { get; set; } /*APINullabe*/ + public string? hiddenLinetype { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Symbol + public string? showReferenceAxis { get; set; } /*APINullabe*/ + public short? referencePen { get; set; } /*APINullabe*/ + public string? referenceLinetype { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cover Fills + public bool? useCoverFill { get; set; } /*APINullabe*/ + public bool? useCoverFillFromSurface { get; set; } + public short? coverFillForegroundPen { get; set; } + public short? coverFillBackgroundPen { get; set; } + public string? coverFillType { get; set; } + public string? coverFillTransformationType { get; set; } + public double? coverFillTransformationOrigoX { get; set; } + public double? coverFillTransformationOrigoY { get; set; } + public double? coverFillTransformationXAxisX { get; set; } + public double? coverFillTransformationXAxisY { get; set; } + public double? coverFillTransformationYAxisX { get; set; } + public double? coverFillTransformationYAxisY { get; set; } + + public class BeamSegment : Base + { + // Segment override materials + public string? leftMaterial { get; set; } + public string? topMaterial { get; set; } + public string? rightMaterial { get; set; } + public string? bottomMaterial { get; set; } + + public string? endsMaterial { get; set; } + + // Segment - The overridden materials are chained + public bool? materialChained { get; set; } + public AssemblySegment assemblySegmentData { get; set; } + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadColumn.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadColumn.cs new file mode 100644 index 0000000000..59693a90c5 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadColumn.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Speckle.Core.Kits; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_columntype +*/ +public class ArchicadColumn : Column +{ + [SchemaInfo("ArchicadColumn", "Creates an Archicad Column by curve.", "Archicad", "Structure")] + public ArchicadColumn() { } + + // Element base + public string? elementType { get; set; } /*APINullabe*/ + + public List? classifications { get; set; } /*APINullabe*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + internal set + { + if (value is ArchicadLevel or null) + { + archicadLevel = value as ArchicadLevel; + } + else + { + throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); + } + } + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ + + public string? layer { get; set; } /*APINullabe*/ + + // Wall geometry + public Point origoPos { get; set; } + public double height { get; set; } + + // Positioning - story relation + public double? bottomOffset { get; set; } /*APINullabe*/ + public double? topOffset { get; set; } /*APINullabe*/ + public short? relativeTopStory { get; set; } /*APINullabe*/ + + // Positioning - slanted column + public bool? isSlanted { get; set; } /*APINullabe*/ + public double? slantAngle { get; set; } /*APINullabe*/ + public double? slantDirectionAngle { get; set; } /*APINullabe*/ + public bool? isFlipped { get; set; } /*APINullabe*/ + + // Positioning - wrapping + public bool? wrapping { get; set; } /*APINullabe*/ + + // Positioning - Defines the relation of column to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) + public string? columnRelationToZoneName { get; set; } /*APINullabe*/ + + // End Cuts + public uint? nCuts { get; set; } /*APINullabe*/ + public Dictionary? Cuts { get; set; } /*APINullabe*/ + + // Reference Axis + public short? coreAnchor { get; set; } + public double? axisRotationAngle { get; set; } + + // Segment + public uint? nSegments { get; set; } /*APINullabe*/ + public uint? nProfiles { get; set; } /*APINullabe*/ + public Dictionary? segments { get; set; } /*APINullabe*/ + + // Scheme + public uint? nSchemes { get; set; } + public Dictionary? Schemes { get; set; } + + // Floor Plan and Section - Floor Plan Display + public string? showOnStories { get; set; } /*APINullabe*/ + public string? displayOptionName { get; set; } /*APINullabe*/ + public string? showProjectionName { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cut Surfaces + public short? corePen { get; set; } + public string? contLtype { get; set; } + public short? venLinePen { get; set; } + public string? venLineType { get; set; } + public short? overrideCutFillPen { get; set; } + public short? overrideCutFillBackgroundPen { get; set; } + + // Floor Plan and Section - Outlines + public short? uncutLinePen { get; set; } /*APINullabe*/ + public string? uncutLinetype { get; set; } /*APINullabe*/ + public short? overheadLinePen { get; set; } /*APINullabe*/ + public string? overheadLinetype { get; set; } /*APINullabe*/ + public short? hiddenLinePen { get; set; } /*APINullabe*/ + public string? hiddenLinetype { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Floor Plan Symbol + public string? coreSymbolTypeName { get; set; } /*APINullabe*/ + public double? coreSymbolPar1 { get; set; } /*APINullabe*/ + public double? coreSymbolPar2 { get; set; } /*APINullabe*/ + public short? coreSymbolPen { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cover Fills + public bool? useCoverFill { get; set; } /*APINullabe*/ + public bool? useCoverFillFromSurface { get; set; } + public short? coverFillForegroundPen { get; set; } + public short? coverFillBackgroundPen { get; set; } + public string? coverFillType { get; set; } + public string? coverFillTransformationType { get; set; } + public double? coverFillTransformationOrigoX { get; set; } + public double? coverFillTransformationOrigoY { get; set; } + public double? coverFillTransformationXAxisX { get; set; } + public double? coverFillTransformationXAxisY { get; set; } + public double? coverFillTransformationYAxisX { get; set; } + public double? coverFillTransformationYAxisY { get; set; } + + public class ColumnSegment : Base + { + // Segment - Veneer attributes + public string? veneerType { get; set; } + public string? veneerBuildingMaterial { get; set; } + + public double? veneerThick { get; set; } + + // Segment - The extrusion overridden material name + public string? extrusionSurfaceMaterial { get; set; } + + // Segment - The ends overridden material name + public string? endsSurfaceMaterial { get; set; } + + // Segment - The overridden materials are chained + public bool? materialChained { get; set; } + public AssemblySegment assemblySegmentData { get; set; } + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadFloor.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadFloor.cs new file mode 100644 index 0000000000..734ad06d05 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadFloor.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_slabtype +*/ +public sealed class ArchicadFloor : Floor +{ + // Element base + public string? elementType { get; set; } /*APINullable*/ + + public List? classifications { get; set; } /*APINullable*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + internal set + { + if (value is ArchicadLevel or null) + { + archicadLevel = value as ArchicadLevel; + } + else + { + throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); + } + } + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ + + public string? layer { get; set; } /*APINullabe*/ + + // Geometry and positioning + public double? thickness { get; set; } + public ElementShape shape { get; set; } + public string? structure { get; set; } /*APINullabe*/ + public string? compositeName { get; set; } + public string? buildingMaterialName { get; set; } + public string? referencePlaneLocation { get; set; } /*APINullabe*/ + + // EdgeTrims + public string? edgeAngleType { get; set; } + public double? edgeAngle { get; set; } + + // Floor Plan and Section - Floor Plan Display + public string? showOnStories { get; set; } /*APINullabe*/ + public Visibility? visibilityCont { get; set; } + public Visibility? visibilityFill { get; set; } + + // Floor Plan and Section - Cut Surfaces + public short? sectContPen { get; set; } + public string? sectContLtype { get; set; } + public short? cutFillPen { get; set; } + public short? cutFillBackgroundPen { get; set; } + + // Floor Plan and Section - Outlines + public short? contourPen { get; set; } + public string? contourLineType { get; set; } + public short? hiddenContourLinePen { get; set; } + public string? hiddenContourLineType { get; set; } + + // Floor Plan and Section - Cover Fills + public bool? useFloorFill { get; set; } + public short? floorFillPen { get; set; } + public short? floorFillBGPen { get; set; } + public string? floorFillName { get; set; } + public bool? use3DHatching { get; set; } + public string? hatchOrientation { get; set; } + public double? hatchOrientationOrigoX { get; set; } + public double? hatchOrientationOrigoY { get; set; } + public double? hatchOrientationXAxisX { get; set; } + public double? hatchOrientationXAxisY { get; set; } + public double? hatchOrientationYAxisX { get; set; } + public double? hatchOrientationYAxisY { get; set; } + + // Model + public string? topMat { get; set; } + public string? sideMat { get; set; } + public string? botMat { get; set; } + public bool? materialsChained { get; set; } + + public class Visibility : Base + { + public bool? showOnHome { get; set; } + public bool? showAllAbove { get; set; } + public bool? showAllBelow { get; set; } + public short? showRelAbove { get; set; } + public short? showRelBelow { get; set; } + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadLevel.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadLevel.cs new file mode 100644 index 0000000000..92f33df851 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadLevel.cs @@ -0,0 +1,24 @@ +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_storytype +*/ +public class ArchicadLevel : Level +{ + public short index { get; set; } + + public ArchicadLevel() { } + + public ArchicadLevel(string name, double elevation, short index) + { + this.name = name; + this.elevation = elevation; + this.index = index; + } + + public ArchicadLevel(string name) + { + this.name = name; + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadRoof.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadRoof.cs new file mode 100644 index 0000000000..6cf965b962 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadRoof.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Other; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_shellbasetype +*/ +public class ArchicadShellBase : BuiltElements.Roof +{ + public class Visibility : Base + { + public bool? showOnHome { get; set; } + public bool? showAllAbove { get; set; } + public bool? showAllBelow { get; set; } + public short? showRelAbove { get; set; } + public short? showRelBelow { get; set; } + } + + // Element base + public string? elementType { get; set; } /*APINullabe*/ + + public List? classifications { get; set; } /*APINullabe*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + internal set + { + if (value is ArchicadLevel or null) + { + archicadLevel = value as ArchicadLevel; + } + else + { + throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); + } + } + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ + + public string? layer { get; set; } /*APINullabe*/ + + // Geometry and positioning + public double? thickness { get; set; } + public string? structure { get; set; } /*APINullabe*/ + public string? compositeName { get; set; } + public string? buildingMaterialName { get; set; } + + // EdgeTrims + public string? edgeAngleType { get; set; } + public double? edgeAngle { get; set; } + + // Floor Plan and Section - Floor Plan Display + public string? showOnStories { get; set; } /*APINullabe*/ + public Visibility? visibilityCont { get; set; } + public Visibility? visibilityFill { get; set; } + public string? displayOptionName { get; set; } /*APINullabe*/ + public string? showProjectionName { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cut Surfaces + public short? sectContPen { get; set; } /*APINullabe*/ + public string? sectContLtype { get; set; } /*APINullabe*/ + public short? cutFillPen { get; set; } + public short? cutFillBackgroundPen { get; set; } + + // Floor Plan and Section - Outlines + public short? contourPen { get; set; } /*APINullabe*/ + public string? contourLineType { get; set; } /*APINullabe*/ + public short? overheadLinePen { get; set; } /*APINullabe*/ + public string? overheadLinetype { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cover Fills + public bool? useFloorFill { get; set; } /*APINullabe*/ + public short? floorFillPen { get; set; } + public short? floorFillBGPen { get; set; } + public string? floorFillName { get; set; } + public bool? use3DHatching { get; set; } + public bool? useFillLocBaseLine { get; set; } + public bool? useSlantedFill { get; set; } + public string? hatchOrientation { get; set; } + public double? hatchOrientationOrigoX { get; set; } + public double? hatchOrientationOrigoY { get; set; } + public double? hatchOrientationXAxisX { get; set; } + public double? hatchOrientationXAxisY { get; set; } + public double? hatchOrientationYAxisX { get; set; } + public double? hatchOrientationYAxisY { get; set; } + + // Model + public string? topMat { get; set; } + public string? sideMat { get; set; } + public string? botMat { get; set; } + public bool? materialsChained { get; set; } + public string? trimmingBodyName { get; set; } /*APINullabe*/ +} + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_rooftype +*/ +public sealed class ArchicadRoof : ArchicadShellBase +{ + public class BaseLine : Base + { + public Point begC { get; set; } + public Point endC { get; set; } + } + + public class RoofLevel : Base + { + public double? levelHeight { get; set; } + public double? levelAngle { get; set; } + } + + public class LevelEdge : Base + { + public double? edgeLevelAngle { get; set; } + public double? eavesOverhang { get; set; } + public string? topMaterial { get; set; } + public string? bottomMaterial { get; set; } + public string? coverFillType { get; set; } + public string? angleType { get; set; } + } + + public class PivotPolyEdge : Base + { + public int? nLevelEdgeData { get; set; } + public Dictionary? roofLevels { get; set; } + } + + // Geometry and positioning + public string roofClassName { get; set; } + public double? planeRoofAngle { get; set; } + public ElementShape shape { get; set; } + public BaseLine? baseLine { get; set; } + public bool? posSign { get; set; } + public ElementShape? pivotPolygon { get; set; } /*APINullabe*/ + public short? levelNum { get; set; } + public Dictionary? levels { get; set; } /*APINullabe*/ + public Dictionary? roofPivotPolyEdges { get; set; } +} + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_shelltype +*/ +public sealed class ArchicadShell : ArchicadShellBase +{ + public class ShellContourEdgeData : Base + { + public string? sideTypeName { get; set; } + public double? sideAngle { get; set; } + public string? edgeTypeName { get; set; } + public string? edgeSideMaterial { get; set; } + } + + public class ShellContourData : Base + { + public ElementShape? shellContourPoly { get; set; } + public Transform shellContourPlane { get; set; } + public double? shellContourHeight { get; set; } + public int? shellContourID { get; set; } + public Dictionary? shellContourEdges { get; set; } + } + + // Geometry and positioning + public string? shellClassName { get; set; } /*APINullabe*/ + public Transform? basePlane { get; set; } /*APINullabe*/ + public bool? flipped { get; set; } /*APINullabe*/ + public bool? hasContour { get; set; } /*APINullabe*/ + public int? numHoles { get; set; } /*APINullabe*/ + public Dictionary? shellContours { get; set; } + public string? defaultEdgeType { get; set; } /*APINullabe*/ + + public double? slantAngle { get; set; } + public double? revolutionAngle { get; set; } + public double? distortionAngle { get; set; } + public bool? segmentedSurfaces { get; set; } + public double? shapePlaneTilt { get; set; } + public double? begPlaneTilt { get; set; } + public double? endPlaneTilt { get; set; } + public ElementShape shape { get; set; } + public ElementShape? shape1 { get; set; } /*APINullabe*/ + public ElementShape? shape2 { get; set; } /*APINullabe*/ + public Transform? axisBase { get; set; } /*APINullabe*/ + public Transform? plane1 { get; set; } /*APINullabe*/ + public Transform? plane2 { get; set; } /*APINullabe*/ + public Point? begC { get; set; } + public double? begAngle { get; set; } + public Vector? extrusionVector { get; set; } + public Vector? shapeDirection { get; set; } + public Vector? distortionVector { get; set; } + public string? morphingRuleName { get; set; } + + // Model + public class BegShapeEdge : Base + { + public string? begShapeEdgeTrimSideType { get; set; } + public double? begShapeEdgeTrimSideAngle { get; set; } + public string? begShapeEdgeSideMaterial { get; set; } + public string? begShapeEdgeType { get; set; } + } + + public class EndShapeEdge : Base + { + public string? endShapeEdgeTrimSideType { get; set; } + public double? endShapeEdgeTrimSideAngle { get; set; } + public string? endShapeEdgeSideMaterial { get; set; } + public string? endShapeEdgeType { get; set; } + } + + public class ExtrudedEdge1 : Base + { + public string? extrudedEdgeTrimSideType1 { get; set; } + public double? extrudedEdgeTrimSideAngle1 { get; set; } + public string? extrudedEdgeSideMaterial1 { get; set; } + public string? extrudedEdgeType1 { get; set; } + } + + public class ExtrudedEdge2 : Base + { + public string? extrudedEdgeTrimSideType2 { get; set; } + public double? extrudedEdgeTrimSideAngle2 { get; set; } + public string? extrudedEdgeSideMaterial2 { get; set; } + public string? extrudedEdgeType2 { get; set; } + } + + public class RevolvedEdge1 : Base + { + public string? revolvedEdgeTrimSideType1 { get; set; } + public double? revolvedEdgeTrimSideAngle1 { get; set; } + public string? revolvedEdgeSideMaterial1 { get; set; } + public string? revolvedEdgeType1 { get; set; } + } + + public class RevolvedEdge2 : Base + { + public string? revolvedEdgeTrimSideType2 { get; set; } + public double? revolvedEdgeTrimSideAngle2 { get; set; } + public string? revolvedEdgeSideMaterial2 { get; set; } + public string? revolvedEdgeType2 { get; set; } + } + + public class RuledEdge1 : Base + { + public string? ruledEdgeTrimSideType1 { get; set; } + public double? ruledEdgeTrimSideAngle1 { get; set; } + public string? ruledEdgeSideMaterial1 { get; set; } + public string? ruledEdgeType1 { get; set; } + } + + public class RuledEdge2 : Base + { + public string? ruledEdgeTrimSideType2 { get; set; } + public double? ruledEdgeTrimSideAngle2 { get; set; } + public string? ruledEdgeSideMaterial2 { get; set; } + public string? ruledEdgeType2 { get; set; } + } + + public BegShapeEdge? begShapeEdge { get; set; } + public EndShapeEdge? endShapeEdge { get; set; } + public ExtrudedEdge1? extrudedEdge1 { get; set; } + public ExtrudedEdge2? extrudedEdge2 { get; set; } + public RevolvedEdge1? revolvedEdge1 { get; set; } + public RevolvedEdge2? revolvedEdge2 { get; set; } + public RuledEdge1? ruledEdge1 { get; set; } + public RuledEdge2? ruledEdge2 { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadRoom.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadRoom.cs new file mode 100644 index 0000000000..993ba55371 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadRoom.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_zonetype +*/ +public class ArchicadRoom : Room +{ + // Element base + public string elementType { get; set; } + + public List classifications { get; set; } + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + set => archicadLevel = value as ArchicadLevel ?? null; + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } + + public string? layer { get; set; } /*APINullabe*/ + + public ElementShape shape { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ArchicadWall.cs b/Objects/Objects/BuiltElements/Archicad/ArchicadWall.cs new file mode 100644 index 0000000000..3047150487 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ArchicadWall.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Speckle.Core.Kits; +using Speckle.Core.Models; +using Speckle.Newtonsoft.Json; + +namespace Objects.BuiltElements.Archicad; + +/* +For further informations about given the variables, visit: +https://archicadapi.graphisoft.com/documentation/api_walltype +*/ +public class ArchicadWall : Wall +{ + [SchemaInfo("ArchicadWall", "Creates an Archicad wall.", "Archicad", "Structure")] + public ArchicadWall() { } + + // Element base + public string? elementType { get; set; } /*APINullabe*/ + + public List? classifications { get; set; } /*APINullabe*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } + + public override Level? level + { + get => archicadLevel; + internal set + { + if (value is ArchicadLevel or null) + { + archicadLevel = value as ArchicadLevel; + } + else + { + throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); + } + } + } + + [JsonIgnore] + public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ + + public string? layer { get; set; } /*APINullabe*/ + + // Wall geometry + public double? baseOffset { get; set; } /*APINullabe*/ + public Point startPoint { get; set; } + public Point endPoint { get; set; } + + public string? structure { get; set; } /*APINullabe*/ + public string? geometryMethod { get; set; } /*APINullabe*/ + public string? wallComplexity { get; set; } /*APINullabe*/ + + public string? buildingMaterialName { get; set; } + public string? compositeName { get; set; } + public string? profileName { get; set; } + public double? arcAngle { get; set; } + + public ElementShape? shape { get; set; } + + public double? thickness { get; set; } /*APINullabe*/ + + public double? outsideSlantAngle { get; set; } + public double? insideSlantAngle { get; set; } + + public bool? polyWalllCornersCanChange { get; set; } + + // Wall and stories relation + public double? topOffset { get; set; } /*APINullabe*/ + public short? relativeTopStory { get; set; } /*APINullabe*/ + public string? referenceLineLocation { get; set; } /*APINullabe*/ + public double? referenceLineOffset { get; set; } + public double? offsetFromOutside { get; set; } /*APINullabe*/ + public int? referenceLineStartIndex { get; set; } /*APINullabe*/ + public int? referenceLineEndIndex { get; set; } /*APINullabe*/ + public bool flipped { get; set; } + + // Floor Plan and Section - Floor Plan Display + public string? showOnStories { get; set; } /*APINullabe*/ + public string? displayOptionName { get; set; } /*APINullabe*/ + public string? showProjectionName { get; set; } /*APINullabe*/ + + // Floor Plan and Section - Cut Surfaces parameters + public short? cutLinePen { get; set; } + public string? cutLinetype { get; set; } + public short? overrideCutFillPen { get; set; } + public short? overrideCutFillBackgroundPen { get; set; } + + // Floor Plan and Section - Outlines parameters + public short? uncutLinePen { get; set; } /*APINullabe*/ + public string? uncutLinetype { get; set; } /*APINullabe*/ + public short? overheadLinePen { get; set; } /*APINullabe*/ + public string? overheadLinetype { get; set; } /*APINullabe*/ + + // Model - Override Surfaces + public string? referenceMaterialName { get; set; } + public int? referenceMaterialStartIndex { get; set; } + public int? referenceMaterialEndIndex { get; set; } + public string? oppositeMaterialName { get; set; } + public int? oppositeMaterialStartIndex { get; set; } + public int? oppositeMaterialEndIndex { get; set; } + public string? sideMaterialName { get; set; } + public bool? materialsChained { get; set; } /*APINullabe*/ + public bool? inheritEndSurface { get; set; } /*APINullabe*/ + public bool? alignTexture { get; set; } /*APINullabe*/ + public int? sequence { get; set; } /*APINullabe*/ + + // Model - Log Details (log height, start with half log, surface of horizontal edges, log shape) + public double? logHeight { get; set; } + public bool? startWithHalfLog { get; set; } + public string? surfaceOfHorizontalEdges { get; set; } + public string? logShape { get; set; } + + // Model - Defines the relation of wall to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) + public string? wallRelationToZoneName { get; set; } /*APINullabe*/ + + // Does it have any embedded object? + public bool? hasDoor { get; set; } /*APINullabe*/ + + public bool? hasWindow { get; set; } /*APINullabe*/ +} diff --git a/Objects/Objects/BuiltElements/Archicad/Classification.cs b/Objects/Objects/BuiltElements/Archicad/Classification.cs index 38beb85d2b..ef78cd1468 100644 --- a/Objects/Objects/BuiltElements/Archicad/Classification.cs +++ b/Objects/Objects/BuiltElements/Archicad/Classification.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; using Speckle.Core.Kits; using Speckle.Core.Models; @@ -11,7 +8,7 @@ public class Classification : Base public Classification() { } [SchemaInfo("Classification", "A classification to set on an element", "BIM", "All")] - public Classification(string system, string code = null, string name = null) + public Classification(string system, string? code = null, string? name = null) { this.system = system; this.code = code; diff --git a/Objects/Objects/BuiltElements/Archicad/ComponentProperties.cs b/Objects/Objects/BuiltElements/Archicad/ComponentProperties.cs new file mode 100644 index 0000000000..8183626f1d --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/ComponentProperties.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Archicad; + +public class ComponentProperties : Base +{ + public ComponentProperties() { } + + [SchemaInfo("ComponentProperties", "An Archicad element component properties", "Archicad", "Elements")] + public ComponentProperties( + string name, + List propertyGroups, + [SchemaParamInfo("(Optional) Speckle units.")] string units = "" + ) + { + this.name = name; + this.propertyGroups = propertyGroups; + this.units = units; + } + + public string name { get; set; } + public List? propertyGroups { get; set; } + public string units { get; set; } + + /// + /// Turns a List of ComponentProperties into a Base so that it can be used with the Speckle properties prop + /// + /// + /// + public static Base? ToBase(List? componentPropertiesList) + { + if (componentPropertiesList == null || componentPropertiesList.Count == 0) + { + return null; + } + + var @base = new Base(); + + foreach (ComponentProperties componentProperties in componentPropertiesList) + { + @base[RemoveDisallowedPropNameChars(componentProperties.name)] = PropertyGroup.ToBase( + componentProperties.propertyGroups + ); + } + + return @base; + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/ElementShape.cs b/Objects/Objects/BuiltElements/Archicad/ElementShape.cs index 4ef6e6bade..4da45cb3ae 100644 --- a/Objects/Objects/BuiltElements/Archicad/ElementShape.cs +++ b/Objects/Objects/BuiltElements/Archicad/ElementShape.cs @@ -9,7 +9,7 @@ public sealed class ElementShape : Base { public ElementShape() { } - public ElementShape(Polyline contourPolyline, List holePolylines = null) + public ElementShape(Polyline contourPolyline, List? holePolylines = null) { this.contourPolyline = contourPolyline; this.holePolylines = holePolylines; @@ -17,7 +17,7 @@ public ElementShape(Polyline contourPolyline, List holePolylines = nul public Polyline contourPolyline { get; set; } - public List holePolylines { get; set; } + public List? holePolylines { get; set; } public sealed class PolylineSegment : Base, ICurve { @@ -36,7 +36,7 @@ public PolylineSegment(Point startPoint, Point endPoint, double? arcAngle = null public double arcAngle { get; set; } public bool? bodyFlag { get; set; } public double length { get; set; } - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); } public sealed class Polyline : Base, ICurve @@ -50,6 +50,6 @@ public Polyline(List segments) public List polylineSegments { get; set; } = new(); public double length { get; set; } - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); } } diff --git a/Objects/Objects/BuiltElements/Archicad/Fenestration.cs b/Objects/Objects/BuiltElements/Archicad/Fenestration.cs index 2fb9de3356..ce262f92e1 100644 --- a/Objects/Objects/BuiltElements/Archicad/Fenestration.cs +++ b/Objects/Objects/BuiltElements/Archicad/Fenestration.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Objects.Geometry; using Speckle.Core.Models; @@ -11,7 +10,10 @@ public class ArchicadFenestration : Base, IDisplayValue> // Element base public string? elementType { get; set; } /*APINullabe*/ + public List? classifications { get; set; } /*APINullabe*/ + public Base? elementProperties { get; set; } + public Base? componentProperties { get; set; } public double? width { get; set; } /*APINullabe*/ public double? height { get; set; } /*APINullabe*/ @@ -65,7 +67,7 @@ public sealed class ArchicadWindow : ArchicadDoorWindowBase { } public sealed class ArchicadSkylight : ArchicadFenestration { - public UInt32? vertexID { get; set; } /*APINullabe*/ + public uint? vertexID { get; set; } /*APINullabe*/ public string? skylightFixMode { get; set; } /*APINullabe*/ public string? skylightAnchor { get; set; } /*APINullabe*/ public Point? anchorPosition { get; set; } /*APINullabe*/ diff --git a/Objects/Objects/BuiltElements/Archicad/Property.cs b/Objects/Objects/BuiltElements/Archicad/Property.cs new file mode 100644 index 0000000000..d7682bce93 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/Property.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Archicad; + +public class Property : Base +{ + public Property() { } + + [SchemaInfo("Property", "An Archicad element property", "Archicad", "Elements")] + public Property(string name, object value, [SchemaParamInfo("(Optional) Speckle units.")] string units = "") + { + this.name = name; + this.value = value; + this.units = units; + } + + public string name { get; set; } + public object? value { get; set; } + public List? values { get; set; } + public string units { get; set; } + + /// + /// Turns a List of Property into a Base so that it can be used with the Speckle properties prop + /// + /// + /// + public static Base? ToBase(List? properties) + { + if (properties == null || properties.Count == 0) + { + return null; + } + + var @base = new Base(); + + foreach (Property property in properties) + { + var key = RemoveDisallowedPropNameChars(property.name); + if (string.IsNullOrEmpty(key) || @base[key] != null) + { + continue; + } + + @base[key] = property.value; + + // todo + //property.values; + } + + return @base; + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/PropertyGroup.cs b/Objects/Objects/BuiltElements/Archicad/PropertyGroup.cs new file mode 100644 index 0000000000..4eb949cf48 --- /dev/null +++ b/Objects/Objects/BuiltElements/Archicad/PropertyGroup.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Archicad; + +public class PropertyGroup : Base +{ + public PropertyGroup() { } + + [SchemaInfo("PropertyGroup", "An Archicad element property group", "Archicad", "Elements")] + public PropertyGroup( + string name, + List propertyList, + [SchemaParamInfo("(Optional) Speckle units.")] string units = "" + ) + { + this.name = name; + this.propertyList = propertyList; + this.units = units; + } + + public string name { get; set; } + public List? propertyList { get; set; } + public string units { get; set; } + + /// + /// Turns a List of PropertyGroup into a Base so that it can be used with the Speckle properties prop + /// + /// + /// + public static Base? ToBase(List? propertyGroups) + { + if (propertyGroups == null || propertyGroups.Count == 0) + { + return null; + } + + var @base = new Base(); + + foreach (PropertyGroup propertyGroup in propertyGroups) + { + @base[RemoveDisallowedPropNameChars(propertyGroup.name)] = Property.ToBase(propertyGroup.propertyList); + } + + return @base; + } +} diff --git a/Objects/Objects/BuiltElements/Archicad/SubElementData.cs b/Objects/Objects/BuiltElements/Archicad/SubElementData.cs deleted file mode 100644 index 0714318b8f..0000000000 --- a/Objects/Objects/BuiltElements/Archicad/SubElementData.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Objects.BuiltElements.Archicad; - -public sealed class SubElementData -{ - public string applicationId { get; set; } - public string elementType { get; set; } -} diff --git a/Objects/Objects/BuiltElements/Area.cs b/Objects/Objects/BuiltElements/Area.cs index fdb7ce4026..9305f8733f 100644 --- a/Objects/Objects/BuiltElements/Area.cs +++ b/Objects/Objects/BuiltElements/Area.cs @@ -10,9 +10,8 @@ public class Area : Base, IHasArea, IHasVolume, IDisplayValue> public Area() { } /// - /// SchemaBuilder constructor for a Room + /// SchemaBuilder constructor for an Area /// - /// Assign units when using this constructor due to param [SchemaInfo("Area", "Creates a Speckle area", "BIM", "Other")] public Area(string name, string number, Level level, [SchemaMainParam] Point center) { diff --git a/Objects/Objects/BuiltElements/Beam.cs b/Objects/Objects/BuiltElements/Beam.cs index f3c6ceb245..7d917c6c93 100644 --- a/Objects/Objects/BuiltElements/Beam.cs +++ b/Objects/Objects/BuiltElements/Beam.cs @@ -1,248 +1,26 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Structural.Materials; -using Objects.Structural.Properties.Profiles; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Beam : Base, IDisplayValue> - { - public Beam() { } - - [SchemaInfo("Beam", "Creates a Speckle beam", "BIM", "Structure")] - public Beam([SchemaMainParam] ICurve baseLine) - { - this.baseLine = baseLine; - } - - public ICurve baseLine { get; set; } +namespace Objects.BuiltElements; - public virtual Level? level { get; internal set; } - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Beam : Base, IDisplayValue> { - public class RevitBeam : Beam - { - public RevitBeam() { } + public Beam() { } - [SchemaInfo("RevitBeam", "Creates a Revit beam by curve and base level.", "Revit", "Structure")] - public RevitBeam( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.parameters = parameters.ToBase(); - this.level = level; - } - - public string family { get; set; } - public string type { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - - public new Level? level - { - get => base.level; - set => base.level = value; - } - } -} - -namespace Objects.BuiltElements.TeklaStructures -{ - public class TeklaBeam : Beam, IHasVolume, IHasArea + [SchemaInfo("Beam", "Creates a Speckle beam", "BIM", "Structure")] + public Beam([SchemaMainParam] ICurve baseLine) { - public TeklaBeam() { } - - [SchemaInfo("TeklaBeam", "Creates a Tekla Structures beam by curve.", "Tekla", "Structure")] - public TeklaBeam([SchemaMainParam] ICurve baseLine, SectionProfile profile, StructuralMaterial material) - { - this.baseLine = baseLine; - this.profile = profile; - this.material = material; - } - - public string name { get; set; } - - [DetachProperty] - public SectionProfile profile { get; set; } - - [DetachProperty] - public StructuralMaterial material { get; set; } - - [DetachProperty] - public string finish { get; set; } - - [DetachProperty] - public string classNumber { get; set; } - - public Vector alignmentVector { get; set; } // This can be set to get proper rotation if coming from an application that doesn't have positioning - - [DetachProperty] - public TeklaPosition position { get; set; } - - public Base userProperties { get; set; } - - [DetachProperty] - public Base rebars { get; set; } - - public TeklaBeamType TeklaBeamType { get; set; } - public double area { get; set; } - public double volume { get; set; } - } - - public class SpiralBeam : TeklaBeam - { - public Point startPoint { get; set; } - public Point rotationAxisPt1 { get; set; } - public Point rotationAxisPt2 { get; set; } - public double totalRise { get; set; } - public double rotationAngle { get; set; } - public double twistAngleStart { get; set; } - public double twistAngleEnd { get; set; } + this.baseLine = baseLine; } -} - -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_beamtype - */ - public class ArchicadBeam : Beam - { - [SchemaInfo("ArchicadBeam", "Creates an Archicad beam by curve.", "Archicad", "Structure")] - public ArchicadBeam() { } - - // Element base - public string? elementType { get; set; } /*APINullabe*/ - public List? classifications { get; set; } /*APINullabe*/ - - public override Level? level - { - get => archicadLevel; - internal set - { - if (value is ArchicadLevel or null) - { - archicadLevel = value as ArchicadLevel; - } - else - { - throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); - } - } - } - - [JsonIgnore] - public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ - public string? layer { get; set; } /*APINullabe*/ + public ICurve baseLine { get; set; } - // Positioning - public Point begC { get; set; } - public Point endC { get; set; } - public bool? isSlanted { get; set; } /*APINullabe*/ - public double? slantAngle { get; set; } /*APINullabe*/ - public string? beamShape { get; set; } /*APINullabe*/ - public int? sequence { get; set; } /*APINullabe*/ - public double? curveAngle { get; set; } /*APINullabe*/ - public double? verticalCurveHeight { get; set; } /*APINullabe*/ - public bool? isFlipped { get; set; } /*APINullabe*/ + public virtual Level? level { get; internal set; } - // End Cuts - public uint? nCuts { get; set; } /*APINullabe*/ - public Dictionary? Cuts { get; set; } + public string units { get; set; } - // Reference Axis - public short? anchorPoint { get; set; } /*APINullabe*/ - public double? offset { get; set; } - public double? profileAngle { get; set; } - - // Segment - public uint? nSegments { get; set; } /*APINullabe*/ - public uint? nProfiles { get; set; } /*APINullabe*/ - public Dictionary? segments { get; set; } /*APINullabe*/ - - // Scheme - public uint? nSchemes { get; set; } - public Dictionary? Schemes { get; set; } - - // Hole - public Dictionary? Holes { get; set; } - - // Floor Plan and Section - Floor Plan Display - public string? showOnStories { get; set; } /*APINullabe*/ - public string? displayOptionName { get; set; } /*APINullabe*/ - public string? uncutProjectionMode { get; set; } /*APINullabe*/ - public string? overheadProjectionMode { get; set; } /*APINullabe*/ - public string? showProjectionName { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cut Surfaces - public short? cutContourLinePen { get; set; } - public string? cutContourLineType { get; set; } - public short? overrideCutFillPen { get; set; } - public short? overrideCutFillBackgroundPen { get; set; } - - // Floor Plan and Section - Outlines - public string? showOutline { get; set; } /*APINullabe*/ - public short? uncutLinePen { get; set; } /*APINullabe*/ - public string? uncutLinetype { get; set; } /*APINullabe*/ - public short? overheadLinePen { get; set; } /*APINullabe*/ - public string? overheadLinetype { get; set; } /*APINullabe*/ - public short? hiddenLinePen { get; set; } /*APINullabe*/ - public string? hiddenLinetype { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Symbol - public string? showReferenceAxis { get; set; } /*APINullabe*/ - public short? referencePen { get; set; } /*APINullabe*/ - public string? referenceLinetype { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cover Fills - public bool? useCoverFill { get; set; } /*APINullabe*/ - public bool? useCoverFillFromSurface { get; set; } - public short? coverFillForegroundPen { get; set; } - public short? coverFillBackgroundPen { get; set; } - public string? coverFillType { get; set; } - public string? coverFillTransformationType { get; set; } - public double? coverFillTransformationOrigoX { get; set; } - public double? coverFillTransformationOrigoY { get; set; } - public double? coverFillTransformationXAxisX { get; set; } - public double? coverFillTransformationXAxisY { get; set; } - public double? coverFillTransformationYAxisX { get; set; } - public double? coverFillTransformationYAxisY { get; set; } - - public class BeamSegment : Base - { - // Segment override materials - public string? leftMaterial { get; set; } - public string? topMaterial { get; set; } - public string? rightMaterial { get; set; } - public string? bottomMaterial { get; set; } - - public string? endsMaterial { get; set; } - - // Segment - The overridden materials are chained - public bool? materialChained { get; set; } - public AssemblySegment assemblySegmentData { get; set; } - } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Brace.cs b/Objects/Objects/BuiltElements/Brace.cs index 4885016be9..c51cd56828 100644 --- a/Objects/Objects/BuiltElements/Brace.cs +++ b/Objects/Objects/BuiltElements/Brace.cs @@ -1,56 +1,24 @@ using System.Collections.Generic; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Brace : Base, IDisplayValue> - { - public Brace() { } - - [SchemaInfo("Brace", "Creates a Speckle brace", "BIM", "Structure")] - public Brace([SchemaMainParam] ICurve baseLine) - { - this.baseLine = baseLine; - } +namespace Objects.BuiltElements; - public ICurve baseLine { get; set; } - - public string units { get; set; } +public class Brace : Base, IDisplayValue> +{ + public Brace() { } - [DetachProperty] - public List displayValue { get; set; } + [SchemaInfo("Brace", "Creates a Speckle brace", "BIM", "Structure")] + public Brace([SchemaMainParam] ICurve baseLine) + { + this.baseLine = baseLine; } -} -namespace Objects.BuiltElements.Revit -{ - public class RevitBrace : Brace - { - public RevitBrace() { } + public ICurve baseLine { get; set; } - [SchemaInfo("RevitBrace", "Creates a Revit brace by curve and base level.", "Revit", "Structure")] - public RevitBrace( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.parameters = parameters.ToBase(); - this.level = level; - } + public string units { get; set; } - public string family { get; set; } - public string type { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public Level level { get; set; } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/CableTray.cs b/Objects/Objects/BuiltElements/CableTray.cs index 47541507c5..f567fc182d 100644 --- a/Objects/Objects/BuiltElements/CableTray.cs +++ b/Objects/Objects/BuiltElements/CableTray.cs @@ -1,33 +1,18 @@ using System.Collections.Generic; -using Objects.BuiltElements.Revit.Interfaces; using Objects.Geometry; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class CableTray : Base, IDisplayValue> - { - public ICurve baseCurve { get; set; } - public double width { get; set; } - public double height { get; set; } - public double length { get; set; } +namespace Objects.BuiltElements; - public string units { get; set; } +public class CableTray : Base, IDisplayValue> +{ + public ICurve baseCurve { get; set; } + public double width { get; set; } + public double height { get; set; } + public double length { get; set; } - [DetachProperty] - public List displayValue { get; set; } - } -} + public string units { get; set; } -namespace Objects.BuiltElements.Revit -{ - public class RevitCableTray : CableTray, IHasMEPConnectors - { - public string family { get; set; } - public string type { get; set; } - public Level level { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public List Connectors { get; set; } = new(); - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Ceiling.cs b/Objects/Objects/BuiltElements/Ceiling.cs index 5c84f4635a..b88c9264b8 100644 --- a/Objects/Objects/BuiltElements/Ceiling.cs +++ b/Objects/Objects/BuiltElements/Ceiling.cs @@ -1,102 +1,34 @@ -using System; using System.Collections.Generic; using Objects.Geometry; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Ceiling : Base, IDisplayValue> - { - public Ceiling() { } - - [SchemaInfo("Ceiling", "Creates a Speckle ceiling", "BIM", "Architecture")] - public Ceiling( - [SchemaMainParam] ICurve outline, - List voids = null, - [SchemaParamInfo("Any nested elements that this ceiling might have")] List elements = null - ) - { - this.outline = outline; - this.voids = voids; - this.elements = elements; - } - - public ICurve outline { get; set; } - public List voids { get; set; } = new(); - - [DetachProperty] - public List elements { get; set; } - - public string units { get; set; } +namespace Objects.BuiltElements; - [DetachProperty] - public List displayValue { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Ceiling : Base, IDisplayValue> { - public class RevitCeiling : Ceiling + public Ceiling() { } + + [SchemaInfo("Ceiling", "Creates a Speckle ceiling", "BIM", "Architecture")] + public Ceiling( + [SchemaMainParam] ICurve outline, + List? voids = null, + [SchemaParamInfo("Any nested elements that this ceiling might have")] List? elements = null + ) { - public RevitCeiling() { } - - [SchemaDeprecated, SchemaInfo("RevitCeiling", "Creates a Revit ceiling", "Revit", "Architecture")] - public RevitCeiling( - [SchemaMainParam, SchemaParamInfo("Planar boundary curve")] ICurve outline, - string family, - string type, - Level level, - double slope = 0, - [SchemaParamInfo("Planar line indicating slope direction")] Line slopeDirection = null, - double offset = 0, - List voids = null, - [SchemaParamInfo("Any nested elements that this ceiling might have")] List elements = null - ) - { - this.outline = outline; - this.family = family; - this.type = type; - this.level = level; - this.slope = slope; - this.slopeDirection = slopeDirection; - this.offset = offset; - this.voids = voids; - this.elements = elements; - } + this.outline = outline; + this.voids = voids ?? new(); + this.elements = elements; + } - [SchemaInfo("RevitCeiling", "Creates a Revit ceiling", "Revit", "Architecture")] - public RevitCeiling( - [SchemaMainParam, SchemaParamInfo("Planar boundary curve")] ICurve outline, - string family, - string type, - Level level, - double slope = 0, - [SchemaParamInfo("Planar line indicating slope direction")] Line slopeDirection = null, - List voids = null, - [SchemaParamInfo("Any nested elements that this ceiling might have")] List elements = null - ) - { - this.outline = outline; - this.family = family; - this.type = type; - this.level = level; - this.slope = slope; - this.slopeDirection = slopeDirection; - this.voids = voids; - this.elements = elements; - } + public ICurve outline { get; set; } + public List voids { get; set; } = new(); - public string family { get; set; } - public string type { get; set; } - public Level level { get; set; } - public double slope { get; set; } - public Line slopeDirection { get; set; } + [DetachProperty] + public List? elements { get; set; } - [Obsolete("Offset property is now captured in parameters to match the behavior of other Revit objects")] - public double offset { get; set; } + public string units { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Civil/CivilAlignment.cs b/Objects/Objects/BuiltElements/Civil/CivilAlignment.cs new file mode 100644 index 0000000000..c0be779e75 --- /dev/null +++ b/Objects/Objects/BuiltElements/Civil/CivilAlignment.cs @@ -0,0 +1,17 @@ +namespace Objects.BuiltElements.Civil; + +public class CivilAlignment : Alignment +{ + public string type { get; set; } + + public string site { get; set; } + + public string style { get; set; } + + public double offset { get; set; } + + /// + /// Name of parent alignment if this is an offset alignment + /// + public string parent { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Civil/CivilProfile.cs b/Objects/Objects/BuiltElements/Civil/CivilProfile.cs new file mode 100644 index 0000000000..53ff30c2ef --- /dev/null +++ b/Objects/Objects/BuiltElements/Civil/CivilProfile.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Objects.Geometry; + +namespace Objects.BuiltElements.Civil; + +public class CivilProfile : Profile +{ + public string type { get; set; } + + public string style { get; set; } + + public double offset { get; set; } + + /// + /// Points of vertical intersection + /// + public List pvis { get; set; } + + /// + /// Name of parent profile if this is an offset profile + /// + public string parent { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Column.cs b/Objects/Objects/BuiltElements/Column.cs index 500ffb4dc2..e13e054eaa 100644 --- a/Objects/Objects/BuiltElements/Column.cs +++ b/Objects/Objects/BuiltElements/Column.cs @@ -1,284 +1,26 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Column : Base, IDisplayValue> - { - public Column() { } - - [SchemaInfo("Column", "Creates a Speckle column", "BIM", "Structure")] - public Column([SchemaMainParam] ICurve baseLine) - { - this.baseLine = baseLine; - } - - public ICurve baseLine { get; set; } - - public virtual Level? level { get; internal set; } - - public string units { get; set; } +namespace Objects.BuiltElements; - [DetachProperty] - public List displayValue { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Column : Base, IDisplayValue> { - public class RevitColumn : Column - { - public RevitColumn() { } - - /// - /// SchemaBuilder constructor for a Revit column - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to and params - [SchemaInfo( - "RevitColumn Vertical", - "Creates a vertical Revit Column by point and levels.", - "Revit", - "Architecture" - )] - public RevitColumn( - string family, - string type, - [SchemaParamInfo("Only the lower point of this line will be used as base point."), SchemaMainParam] - ICurve baseLine, - Level level, - Level topLevel, - double baseOffset = 0, - double topOffset = 0, - bool structural = false, - [SchemaParamInfo("Rotation angle in radians")] double rotation = 0, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.topLevel = topLevel; - this.baseOffset = baseOffset; - this.topOffset = topOffset; - //this.structural = structural; - this.rotation = rotation; - this.parameters = parameters.ToBase(); - this.level = level; - } + public Column() { } - [ - SchemaDeprecated, - SchemaInfo("RevitColumn Slanted (old)", "Creates a slanted Revit Column by curve.", "Revit", "Structure") - ] - public RevitColumn( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - bool structural = false, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.level = level; - //this.structural = structural; - isSlanted = true; - this.parameters = parameters.ToBase(); - } - - [SchemaInfo("RevitColumn Slanted", "Creates a slanted Revit Column by curve.", "Revit", "Structure")] - public RevitColumn( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - Level topLevel = null, - bool structural = false, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.level = level; - this.topLevel = topLevel; - //this.structural = structural; - isSlanted = true; - this.parameters = parameters.ToBase(); - } - - public new Level? level - { - get => base.level; - set => base.level = value; - } - - public Level topLevel { get; set; } - public double baseOffset { get; set; } - public double topOffset { get; set; } - public bool facingFlipped { get; set; } - - public bool handFlipped { get; set; } - - //public bool structural { get; set; } - public double rotation { get; set; } - public bool isSlanted { get; set; } - public string family { get; set; } - public string type { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } -} - -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_columntype - */ - public class ArchicadColumn : Column + [SchemaInfo("Column", "Creates a Speckle column", "BIM", "Structure")] + public Column([SchemaMainParam] ICurve baseLine) { - [SchemaInfo("ArchicadColumn", "Creates an Archicad Column by curve.", "Archicad", "Structure")] - public ArchicadColumn() { } - - // Element base - public string? elementType { get; set; } /*APINullabe*/ - public List? classifications { get; set; } /*APINullabe*/ - - public override Level? level - { - get => archicadLevel; - internal set - { - if (value is ArchicadLevel or null) - { - archicadLevel = value as ArchicadLevel; - } - else - { - throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); - } - } - } - - [JsonIgnore] - public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ - - public string? layer { get; set; } /*APINullabe*/ - - // Wall geometry - public Point origoPos { get; set; } - public double height { get; set; } - - // Positioning - story relation - public double? bottomOffset { get; set; } /*APINullabe*/ - public double? topOffset { get; set; } /*APINullabe*/ - public short? relativeTopStory { get; set; } /*APINullabe*/ - - // Positioning - slanted column - public bool? isSlanted { get; set; } /*APINullabe*/ - public double? slantAngle { get; set; } /*APINullabe*/ - public double? slantDirectionAngle { get; set; } /*APINullabe*/ - public bool? isFlipped { get; set; } /*APINullabe*/ - - // Positioning - wrapping - public bool? wrapping { get; set; } /*APINullabe*/ - - // Positioning - Defines the relation of column to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) - public string? columnRelationToZoneName { get; set; } /*APINullabe*/ - - // End Cuts - public uint? nCuts { get; set; } /*APINullabe*/ - public Dictionary? Cuts { get; set; } /*APINullabe*/ - - // Reference Axis - public short? coreAnchor { get; set; } - public double? axisRotationAngle { get; set; } - - // Segment - public uint? nSegments { get; set; } /*APINullabe*/ - public uint? nProfiles { get; set; } /*APINullabe*/ - public Dictionary? segments { get; set; } /*APINullabe*/ - - // Scheme - public uint? nSchemes { get; set; } - public Dictionary? Schemes { get; set; } - - // Floor Plan and Section - Floor Plan Display - public string? showOnStories { get; set; } /*APINullabe*/ - public string? displayOptionName { get; set; } /*APINullabe*/ - public string? showProjectionName { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cut Surfaces - public short? corePen { get; set; } - public string? contLtype { get; set; } - public short? venLinePen { get; set; } - public string? venLineType { get; set; } - public short? overrideCutFillPen { get; set; } - public short? overrideCutFillBackgroundPen { get; set; } - - // Floor Plan and Section - Outlines - public short? uncutLinePen { get; set; } /*APINullabe*/ - public string? uncutLinetype { get; set; } /*APINullabe*/ - public short? overheadLinePen { get; set; } /*APINullabe*/ - public string? overheadLinetype { get; set; } /*APINullabe*/ - public short? hiddenLinePen { get; set; } /*APINullabe*/ - public string? hiddenLinetype { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Floor Plan Symbol - public string? coreSymbolTypeName { get; set; } /*APINullabe*/ - public double? coreSymbolPar1 { get; set; } /*APINullabe*/ - public double? coreSymbolPar2 { get; set; } /*APINullabe*/ - public short? coreSymbolPen { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cover Fills - public bool? useCoverFill { get; set; } /*APINullabe*/ - public bool? useCoverFillFromSurface { get; set; } - public short? coverFillForegroundPen { get; set; } - public short? coverFillBackgroundPen { get; set; } - public string? coverFillType { get; set; } - public string? coverFillTransformationType { get; set; } - public double? coverFillTransformationOrigoX { get; set; } - public double? coverFillTransformationOrigoY { get; set; } - public double? coverFillTransformationXAxisX { get; set; } - public double? coverFillTransformationXAxisY { get; set; } - public double? coverFillTransformationYAxisX { get; set; } - public double? coverFillTransformationYAxisY { get; set; } - - public class ColumnSegment : Base - { - // Segment - Veneer attributes - public string? veneerType { get; set; } - public string? veneerBuildingMaterial { get; set; } + this.baseLine = baseLine; + } - public double? veneerThick { get; set; } + public ICurve baseLine { get; set; } - // Segment - The extrusion overridden material name - public string? extrusionSurfaceMaterial { get; set; } + public virtual Level? level { get; internal set; } - // Segment - The ends overridden material name - public string? endsSurfaceMaterial { get; set; } + public string units { get; set; } - // Segment - The overridden materials are chained - public bool? materialChained { get; set; } - public AssemblySegment assemblySegmentData { get; set; } - } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Conduit.cs b/Objects/Objects/BuiltElements/Conduit.cs index 3317fd6593..aaa908e22b 100644 --- a/Objects/Objects/BuiltElements/Conduit.cs +++ b/Objects/Objects/BuiltElements/Conduit.cs @@ -1,36 +1,17 @@ using System.Collections.Generic; -using Objects.BuiltElements.Revit.Interfaces; using Objects.Geometry; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Conduit : Base, IDisplayValue> - { - public ICurve baseCurve { get; set; } - public double diameter { get; set; } - public double length { get; set; } - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - } -} +namespace Objects.BuiltElements; -namespace Objects.BuiltElements.Revit +public class Conduit : Base, IDisplayValue> { - public class RevitConduit : Conduit, IHasMEPConnectors - { - public string family { get; set; } - - public string type { get; set; } - - public Level level { get; set; } + public ICurve baseCurve { get; set; } + public double diameter { get; set; } + public double length { get; set; } - public Base parameters { get; set; } + public string units { get; set; } - public string elementId { get; set; } - public List Connectors { get; set; } = new(); - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Duct.cs b/Objects/Objects/BuiltElements/Duct.cs index e8951f58f7..f530be6faf 100644 --- a/Objects/Objects/BuiltElements/Duct.cs +++ b/Objects/Objects/BuiltElements/Duct.cs @@ -1,228 +1,66 @@ using System; using System.Collections.Generic; -using Objects.BuiltElements.Revit.Interfaces; using Objects.Geometry; -using Objects.Organization; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Duct : Base, IDisplayValue> - { - public Duct() { } - - /// - /// SchemaBuilder constructor for a Speckle duct - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("Duct", "Creates a Speckle duct", "BIM", "MEP"), SchemaDeprecated] - public Duct([SchemaMainParam] Line baseLine, double width, double height, double diameter, double velocity = 0) - { - baseCurve = baseLine; - this.width = width; - this.height = height; - this.diameter = diameter; - this.velocity = velocity; - } - - /// - /// SchemaBuilder constructor for a Speckle duct - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("Duct", "Creates a Speckle duct", "BIM", "MEP")] - public Duct([SchemaMainParam] ICurve baseCurve, double width, double height, double diameter, double velocity = 0) - { - this.baseCurve = baseCurve; - this.width = width; - this.height = height; - this.diameter = diameter; - this.velocity = velocity; - } +namespace Objects.BuiltElements; - [JsonIgnore, Obsolete("Replaced with baseCurve property")] - public Line baseLine { get; set; } - - public ICurve baseCurve { get; set; } - public double width { get; set; } - public double height { get; set; } - public double diameter { get; set; } - public double length { get; set; } - public double velocity { get; set; } - - public string units { get; set; } +public class Duct : Base, IDisplayValue> +{ + public Duct() { } - [DetachProperty] - public List displayValue { get; set; } + /// + /// SchemaBuilder constructor for a Speckle duct + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("Duct", "Creates a Speckle duct", "BIM", "MEP"), SchemaDeprecated] + public Duct([SchemaMainParam] Line baseLine, double width, double height, double diameter, double velocity = 0) + { + baseCurve = baseLine; + this.width = width; + this.height = height; + this.diameter = diameter; + this.velocity = velocity; } -} -namespace Objects.BuiltElements.Revit -{ - public class RevitDuct : Duct, IHasMEPConnectors + /// + /// SchemaBuilder constructor for a Speckle duct + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("Duct", "Creates a Speckle duct", "BIM", "MEP")] + public Duct([SchemaMainParam] ICurve baseCurve, double width, double height, double diameter, double velocity = 0) { - public RevitDuct() { } - - /// - /// SchemaBuilder constructor for a Revit duct (deprecated) - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("RevitDuct", "Creates a Revit duct", "Revit", "MEP"), SchemaDeprecated] - public RevitDuct( - string family, - string type, - [SchemaMainParam] Line baseLine, - string systemName, - string systemType, - Level level, - double width, - double height, - double diameter, - double velocity = 0, - List parameters = null - ) - { - baseCurve = baseLine; - this.family = family; - this.type = type; - this.width = width; - this.height = height; - this.diameter = diameter; - this.velocity = velocity; - this.systemName = systemName; - this.systemType = systemType; - this.parameters = parameters.ToBase(); - this.level = level; - } - - /// - /// SchemaBuilder constructor for a Revit duct - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("RevitDuct", "Creates a Revit duct", "Revit", "MEP")] - public RevitDuct( - string family, - string type, - [SchemaMainParam] ICurve baseCurve, - string systemName, - string systemType, - Level level, - double width, - double height, - double diameter, - double velocity = 0, - List parameters = null - ) - { - this.baseCurve = baseCurve; - this.family = family; - this.type = type; - this.width = width; - this.height = height; - this.diameter = diameter; - this.velocity = velocity; - this.systemName = systemName; - this.systemType = systemType; - this.parameters = parameters.ToBase(); - this.level = level; - } - - public string family { get; set; } - public string type { get; set; } - public string systemName { get; set; } - public string systemType { get; set; } - public Level level { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public List Connectors { get; set; } = new(); + this.baseCurve = baseCurve; + this.width = width; + this.height = height; + this.diameter = diameter; + this.velocity = velocity; } - public class RevitFlexDuct : RevitDuct - { - public RevitFlexDuct() { } + [JsonIgnore, Obsolete("Replaced with baseCurve property")] + public Line baseLine { get; set; } - /// - /// SchemaBuilder constructor for a Revit flex duct - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("RevitFlexDuct", "Creates a Revit flex duct", "Revit", "MEP")] - public RevitFlexDuct( - string family, - string type, - [SchemaMainParam] ICurve baseCurve, - string systemName, - string systemType, - Level level, - double width, - double height, - double diameter, - Vector startTangent, - Vector endTangent, - double velocity = 0, - List parameters = null - ) - { - this.baseCurve = baseCurve; - this.family = family; - this.type = type; - this.width = width; - this.height = height; - this.diameter = diameter; - this.startTangent = startTangent; - this.endTangent = endTangent; - this.velocity = velocity; - this.systemName = systemName; - this.systemType = systemType; - this.parameters = parameters.ToBase(); - this.level = level; - } + public ICurve baseCurve { get; set; } + public double width { get; set; } + public double height { get; set; } + public double diameter { get; set; } + public double length { get; set; } + public double velocity { get; set; } - public Vector startTangent { get; set; } - public Vector endTangent { get; set; } - } + public string units { get; set; } + + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Featureline.cs b/Objects/Objects/BuiltElements/Featureline.cs index a8380c38f3..3033d75e5d 100644 --- a/Objects/Objects/BuiltElements/Featureline.cs +++ b/Objects/Objects/BuiltElements/Featureline.cs @@ -1,8 +1,6 @@ -using System; using System.Collections.Generic; using Objects.Geometry; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; namespace Objects.BuiltElements; diff --git a/Objects/Objects/BuiltElements/Floor.cs b/Objects/Objects/BuiltElements/Floor.cs index 877cbf136d..80ae0dde9c 100644 --- a/Objects/Objects/BuiltElements/Floor.cs +++ b/Objects/Objects/BuiltElements/Floor.cs @@ -1,180 +1,36 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Floor : Base, IDisplayValue> - { - public Floor() { } - - [SchemaInfo("Floor", "Creates a Speckle floor", "BIM", "Architecture")] - public Floor( - [SchemaMainParam] ICurve outline, - List voids = null, - [SchemaParamInfo("Any nested elements that this floor might have")] List elements = null - ) - { - this.outline = outline; - this.voids = voids; - this.elements = elements; - } - - public ICurve outline { get; set; } - public List voids { get; set; } = new(); - - [DetachProperty] - public List elements { get; set; } - public virtual Level? level { get; internal set; } - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - } -} +namespace Objects.BuiltElements; -namespace Objects.BuiltElements.Revit +public class Floor : Base, IDisplayValue> { - public class RevitFloor : Floor + public Floor() { } + + [SchemaInfo("Floor", "Creates a Speckle floor", "BIM", "Architecture")] + public Floor( + [SchemaMainParam] ICurve outline, + List? voids = null, + [SchemaParamInfo("Any nested elements that this floor might have")] List? elements = null + ) { - public RevitFloor() { } - - [SchemaInfo("RevitFloor", "Creates a Revit floor by outline and level", "Revit", "Architecture")] - public RevitFloor( - string family, - string type, - [SchemaMainParam] ICurve outline, - Level level, - bool structural = false, - double slope = 0, - Line slopeDirection = null, - List voids = null, - [SchemaParamInfo("Any nested elements that this floor might have")] List elements = null, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.level = level; - this.structural = structural; - this.slope = slope; - this.slopeDirection = slopeDirection; - this.parameters = parameters.ToBase(); - this.outline = outline; - this.voids = voids; - this.elements = elements; - } + this.outline = outline; - public string family { get; set; } - public string type { get; set; } + this.voids = voids ?? new(); - public new Level? level - { - get => base.level; - set => base.level = value; - } - - public bool structural { get; set; } - public double slope { get; set; } - public Line slopeDirection { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } + this.elements = elements; } -} -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_slabtype - */ - public sealed class ArchicadFloor : Floor - { - // Element base - public string? elementType { get; set; } /*APINullabe*/ - public List? classifications { get; set; } /*APINullabe*/ - - public override Level? level - { - get => archicadLevel; - internal set - { - if (value is ArchicadLevel or null) - { - archicadLevel = value as ArchicadLevel; - } - else - { - throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); - } - } - } - - [JsonIgnore] - public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ - - public string? layer { get; set; } /*APINullabe*/ - - // Geometry and positioning - public double? thickness { get; set; } - public ElementShape shape { get; set; } - public string? structure { get; set; } /*APINullabe*/ - public string? compositeName { get; set; } - public string? buildingMaterialName { get; set; } - public string? referencePlaneLocation { get; set; } /*APINullabe*/ - - // EdgeTrims - public string? edgeAngleType { get; set; } - public double? edgeAngle { get; set; } + public ICurve outline { get; set; } + public List voids { get; set; } = new(); - // Floor Plan and Section - Floor Plan Display - public string? showOnStories { get; set; } /*APINullabe*/ - public Visibility? visibilityCont { get; set; } - public Visibility? visibilityFill { get; set; } + [DetachProperty] + public List? elements { get; set; } + public virtual Level? level { get; internal set; } + public string units { get; set; } - // Floor Plan and Section - Cut Surfaces - public short? sectContPen { get; set; } - public string? sectContLtype { get; set; } - public short? cutFillPen { get; set; } - public short? cutFillBackgroundPen { get; set; } - - // Floor Plan and Section - Outlines - public short? contourPen { get; set; } - public string? contourLineType { get; set; } - public short? hiddenContourLinePen { get; set; } - public string? hiddenContourLineType { get; set; } - - // Floor Plan and Section - Cover Fills - public bool? useFloorFill { get; set; } - public short? floorFillPen { get; set; } - public short? floorFillBGPen { get; set; } - public string? floorFillName { get; set; } - public bool? use3DHatching { get; set; } - public string? hatchOrientation { get; set; } - public double? hatchOrientationOrigoX { get; set; } - public double? hatchOrientationOrigoY { get; set; } - public double? hatchOrientationXAxisX { get; set; } - public double? hatchOrientationXAxisY { get; set; } - public double? hatchOrientationYAxisX { get; set; } - public double? hatchOrientationYAxisY { get; set; } - - // Model - public string? topMat { get; set; } - public string? sideMat { get; set; } - public string? botMat { get; set; } - public bool? materialsChained { get; set; } - - public class Visibility : Base - { - public bool? showOnHome { get; set; } - public bool? showAllAbove { get; set; } - public bool? showAllBelow { get; set; } - public short? showRelAbove { get; set; } - public short? showRelBelow { get; set; } - } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/GridLine.cs b/Objects/Objects/BuiltElements/GridLine.cs index 7864b6722d..c6fb7e01cd 100644 --- a/Objects/Objects/BuiltElements/GridLine.cs +++ b/Objects/Objects/BuiltElements/GridLine.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Speckle.Core.Kits; using Speckle.Core.Models; -using Objects.Geometry; namespace Objects.BuiltElements; diff --git a/Objects/Objects/BuiltElements/Level.cs b/Objects/Objects/BuiltElements/Level.cs index 928d3abbde..1eb136216e 100644 --- a/Objects/Objects/BuiltElements/Level.cs +++ b/Objects/Objects/BuiltElements/Level.cs @@ -1,112 +1,29 @@ -using System.Collections.Generic; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Level : Base - { - //public List elements { get; set; } - - public Level() { } - - /// - /// SchemaBuilder constructor for a Speckle level - /// - /// - /// - /// Assign units when using this constructor due to param - [SchemaInfo("Level", "Creates a Speckle level", "BIM", "Architecture")] - public Level(string name, double elevation) - { - this.name = name; - this.elevation = elevation; - } - - public string name { get; set; } - public double elevation { get; set; } +namespace Objects.BuiltElements; - public string units { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Level : Base { - public class RevitLevel : Level + //public List elements { get; set; } + + public Level() { } + + /// + /// SchemaBuilder constructor for a Speckle level + /// + /// + /// + /// Assign units when using this constructor due to param + [SchemaInfo("Level", "Creates a Speckle level", "BIM", "Architecture")] + public Level(string name, double elevation) { - public RevitLevel() { } - - /// - /// SchemaBuilder constructor for a Revit level - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to param - [SchemaInfo( - "RevitLevel", - "Creates a new Revit level unless one with the same elevation already exists", - "Revit", - "Architecture" - )] - public RevitLevel( - [SchemaParamInfo("Level name. NOTE: updating level name is not supported")] string name, - [SchemaParamInfo( - "Level elevation. NOTE: updating level elevation is not supported, a new one will be created unless another level at the new elevation already exists." - )] - double elevation, - [SchemaParamInfo( - "If true, it creates an associated view in Revit. NOTE: only used when creating a level for the first time" - )] - bool createView, - List parameters = null - ) - { - this.name = name; - this.elevation = elevation; - this.createView = createView; - this.parameters = parameters.ToBase(); - referenceOnly = false; - } - - [SchemaInfo("RevitLevel by name", "Gets an existing Revit level by name", "Revit", "Architecture")] - public RevitLevel(string name) - { - this.name = name; - referenceOnly = true; - } - - public bool createView { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public bool referenceOnly { get; set; } + this.name = name; + this.elevation = elevation; } -} - -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_storytype - */ - public class ArchicadLevel : Level - { - public short index { get; set; } - public ArchicadLevel() { } + public string name { get; set; } + public double elevation { get; set; } - public ArchicadLevel(string name, double elevation, short index) - { - this.name = name; - this.elevation = elevation; - this.index = index; - } - - public ArchicadLevel(string name) - { - this.name = name; - } - } + public string units { get; set; } } diff --git a/Objects/Objects/BuiltElements/Network.cs b/Objects/Objects/BuiltElements/Network.cs index e8201e13d1..d20d641249 100644 --- a/Objects/Objects/BuiltElements/Network.cs +++ b/Objects/Objects/BuiltElements/Network.cs @@ -1,158 +1,88 @@ using System; using System.Collections.Generic; using System.Linq; -using Objects.Geometry; using Speckle.Core.Models; using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements +namespace Objects.BuiltElements; + +/// +/// Represents graph connections between built elements objects +/// +/// +/// Network may need to be created first in native applications before they are linked. +/// +[Obsolete("Networks are no longer used in any connector to assemble MEP systems.")] +public class Network : Base +{ + public Network() { } + + public string name { get; set; } + + /// + /// The elements contained in the network + /// + public List elements { get; set; } + + /// + /// The connections between + /// + public List links { get; set; } +} + +[Obsolete("Networks are no longer used in any connector to assemble MEP systems.")] +public class NetworkElement : Base { + public NetworkElement() { } + + public string name { get; set; } + /// - /// Represents graph connections between built elements objects + /// The Base object representing the element in the network (eg Pipe, Duct, etc) /// /// - /// Network may need to be created first in native applications before they are linked. + /// Currently named "elements" to assist with receiving in connector flatten method. /// - public class Network : Base - { - [Obsolete( - "The Network was previously used to assemble MEP systems, but now MEP systems are assembled by the RevitCommitObjectBuilder as MEP elements are converted." - )] - public Network() { } - - public string name { get; set; } - - /// - /// The elements contained in the network - /// - public List elements { get; set; } - - /// - /// The connections between - /// - public List links { get; set; } - } - - public class NetworkElement : Base - { - [Obsolete("The NetworkElement class is obsolete because the Network class is now obsolete")] - public NetworkElement() { } - - public string name { get; set; } - - [DetachProperty] - /// - /// The Base object representing the element in the network (eg Pipe, Duct, etc) - /// - /// - /// Currently named "elements" to assist with receiving in connector flatten method. - /// - public Base elements { get; set; } - - /// - /// The index of the links in that are connected to this element - /// - public List linkIndices { get; set; } - - [JsonIgnore] - public Network network { get; set; } - - /// - /// Retrieves the links for this element - /// - [JsonIgnore] - public List links => linkIndices.Select(i => network?.links[i]).ToList(); - } - - public class NetworkLink : Base - { - [Obsolete("The NetworkLink class is obsolete because the Network class is now obsolete")] - public NetworkLink() { } - - public string name { get; set; } - - /// - /// The index of the elements in that are connected by this link - /// - public List elementIndices { get; set; } - - [JsonIgnore] - public Network network { get; set; } - - /// - /// Retrieves the elements for this link - /// - [JsonIgnore] - public List elements => elementIndices.Select(i => network?.elements[i]).ToList(); - } + [DetachProperty] + public Base elements { get; set; } + + /// + /// The index of the links in that are connected to this element + /// + public List linkIndices { get; set; } + + [JsonIgnore] + public Network network { get; set; } + + /// + /// Retrieves the links for this element + /// + [JsonIgnore] +#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type. Reason: obsolete. + public List links => linkIndices.Select(i => network?.links[i]).ToList(); +#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type. Reason: obsolete. } -namespace Objects.BuiltElements.Revit +[Obsolete("Networks are no longer used in any connector to assemble MEP systems.")] +public class NetworkLink : Base { - public class RevitNetworkElement : NetworkElement - { - [Obsolete("The RevitNetworkElement class is obsolete because the Network class is now obsolete")] - public RevitNetworkElement() { } - - /// - /// Indicates if this element was constructed from an MEP curve - /// - public bool isCurveBased { get; set; } - - /// - /// Indicates if this element needs temporary placeholder objects to be created first when receiving - /// - /// - /// For example, some fittings cannot be created based on connectors, and so will be created similarly to mechanical equipment - /// - public bool isConnectorBased { get; set; } - } - - public class RevitNetworkLink : NetworkLink - { - public double height { get; set; } - public double width { get; set; } - public double diameter { get; set; } - public Point origin { get; set; } - public Vector direction { get; set; } - - /// - /// The system category - /// - public string systemName { get; set; } - - public string systemType { get; set; } - - /// - /// The connector profile shape of the - /// - public string shape { get; set; } - - /// - /// The link domain - /// - public string domain { get; set; } - - /// - /// The index indicating the position of this link on the connected fitting element, if applicable - /// - /// - /// Revit fitting links are 1-indexed. For example, "T" fittings will have ordered links from index 1-3. - /// - public int fittingIndex { get; set; } - - /// - /// Indicates if this link needs temporary placeholder objects to be created first when receiving - /// - /// - /// Placeholder geometry are curves. - /// For example, U-bend links need temporary pipes to be created first, if one or more linked pipes have not yet been created in the network. - /// - public bool needsPlaceholders { get; set; } - - /// - /// Indicates if this link has been connected to its elements - /// - public bool isConnected { get; set; } - } + public NetworkLink() { } + + public string name { get; set; } + + /// + /// The index of the elements in that are connected by this link + /// + public List elementIndices { get; set; } + + [JsonIgnore] + public Network network { get; set; } + + /// + /// Retrieves the elements for this link + /// + [JsonIgnore] +#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type. Reason: obsolete. + public List elements => elementIndices.Select(i => network?.elements[i]).ToList(); +#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type. Reason: obsolete. } diff --git a/Objects/Objects/BuiltElements/Opening.cs b/Objects/Objects/BuiltElements/Opening.cs index 597024a55b..85985a332f 100644 --- a/Objects/Objects/BuiltElements/Opening.cs +++ b/Objects/Objects/BuiltElements/Opening.cs @@ -1,147 +1,19 @@ -using System; -using System.Collections.Generic; -using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; -using Speckle.Core.Logging; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Opening : Base - { - public Opening() { } - - [SchemaInfo("Arch Opening", "Creates a Speckle opening", "BIM", "Architecture")] - public Opening(ICurve outline) - { - this.outline = outline; - } - - public ICurve outline { get; set; } +namespace Objects.BuiltElements; - public string units { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Opening : Base { - public class RevitOpening : Opening - { - //public string family { get; set; } - //public string type { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } - - public class RevitVerticalOpening : RevitOpening { } + public Opening() { } - public class RevitWallOpening : RevitOpening + [SchemaInfo("Arch Opening", "Creates a Speckle opening", "BIM", "Architecture")] + public Opening(ICurve outline) { - public RevitWallOpening() { } - - [ - Obsolete("Use constructor with Polyline input instead"), - SchemaDeprecated, - SchemaInfo("Revit Wall Opening (Deprecated)", "Creates a Speckle Wall opening for revit", "BIM", "Architecture") - ] - public RevitWallOpening(ICurve outline, RevitWall? host = null) - { - if (outline is not Polyline) - { - throw new SpeckleException("Outline should be a rectangular-shaped polyline", false); - } - - this.outline = outline; - this.host = host; - } - - [SchemaInfo("Revit Wall Opening", "Creates a Speckle Wall opening for revit", "Revit", "Architecture")] - public RevitWallOpening(Polyline outline, RevitWall? host = null) - { - if (outline == null) - { - throw new SpeckleException("Outline cannot be null"); - } - - if (outline.GetPoints().Count != 4) - { - throw new SpeckleException("Outline should be a rectangular-shaped polyline"); - } - - this.outline = outline; - this.host = host; - } - - public RevitWall? host { get; set; } + this.outline = outline; } - public class RevitShaft : RevitOpening - { - public RevitShaft() { } - - /// - /// SchemaBuilder constructor for a Revit shaft - /// - /// - /// - /// - /// - [SchemaInfo("RevitShaft", "Creates a Revit shaft from a bottom and top level", "Revit", "Architecture")] - public RevitShaft( - [SchemaMainParam] ICurve outline, - Level bottomLevel, - Level topLevel, - List parameters = null - ) - { - this.outline = outline; - this.bottomLevel = bottomLevel; - this.topLevel = topLevel; - this.parameters = parameters.ToBase(); - } - - public Level bottomLevel { get; set; } - public Level topLevel { get; set; } - public double height { get; set; } - - /* - /// - /// SchemaBuilder constructor for a Revit shaft - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to param - [SchemaInfo("RevitShaft", "Creates a Revit shaft from a bottom level and height")] - public RevitShaft(ICurve outline, Level bottomLevel, double height, List parameters = null) - { - this.outline = outline; - this.bottomLevel = bottomLevel; - this.height = height; - this.parameters = parameters.ToBase(); - } - */ - } -} + public ICurve outline { get; set; } -namespace Objects.BuiltElements.TeklaStructures -{ - public class TeklaOpening : Opening - { - public string openingHostId { get; set; } - public TeklaOpeningTypeEnum openingType { get; set; } - } - - public class TeklaContourOpening : TeklaOpening - { - public TeklaContourPlate cuttingPlate { get; set; } - public double thickness { get; set; } - } - - public class TeklaBeamOpening : TeklaOpening - { - public TeklaBeam cuttingBeam { get; set; } - } + public string units { get; set; } } diff --git a/Objects/Objects/BuiltElements/Pipe.cs b/Objects/Objects/BuiltElements/Pipe.cs index 6f39ebfd5f..7c6bf1d817 100644 --- a/Objects/Objects/BuiltElements/Pipe.cs +++ b/Objects/Objects/BuiltElements/Pipe.cs @@ -1,110 +1,36 @@ using System.Collections.Generic; -using Objects.BuiltElements.Revit.Interfaces; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Pipe : Base, IDisplayValue> - { - public Pipe() { } - - [SchemaInfo("Pipe", "Creates a Speckle pipe", "BIM", "MEP")] - public Pipe( - [SchemaMainParam] ICurve baseCurve, - double length, - double diameter, - double flowrate = 0, - double relativeRoughness = 0 - ) - { - this.baseCurve = baseCurve; - this.length = length; - this.diameter = diameter; - } - - public ICurve baseCurve { get; set; } - public double length { get; set; } - public double diameter { get; set; } - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - } -} +namespace Objects.BuiltElements; -namespace Objects.BuiltElements.Revit +public class Pipe : Base, IDisplayValue> { - public class RevitPipe : Pipe, IHasMEPConnectors + public Pipe() { } + + [SchemaInfo("Pipe", "Creates a Speckle pipe", "BIM", "MEP")] + public Pipe( + [SchemaMainParam] ICurve baseCurve, + double length, + double diameter, + double flowrate = 0, + double relativeRoughness = 0 + ) { - public RevitPipe() { } - - [SchemaInfo("RevitPipe", "Creates a Revit pipe", "Revit", "MEP")] - public RevitPipe( - string family, - string type, - [SchemaMainParam] ICurve baseCurve, - double diameter, - Level level, - string systemName = "", - string systemType = "", - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseCurve = baseCurve; - this.diameter = diameter; - this.systemName = systemName; - this.systemType = systemType; - this.level = level; - this.parameters = parameters.ToBase(); - } - - public string family { get; set; } - public string type { get; set; } - public string systemName { get; set; } - public string systemType { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public Level level { get; set; } - public List Connectors { get; set; } = new(); + this.baseCurve = baseCurve; + this.length = length; + this.diameter = diameter; + this["flowRate"] = flowrate; + this["relativeRoughness"] = relativeRoughness; } - public class RevitFlexPipe : RevitPipe - { - public RevitFlexPipe() { } + public ICurve baseCurve { get; set; } + public double length { get; set; } + public double diameter { get; set; } - [SchemaInfo("RevitFlexPipe", "Creates a Revit flex pipe", "Revit", "MEP")] - public RevitFlexPipe( - string family, - string type, - [SchemaMainParam] ICurve baseCurve, - double diameter, - Level level, - Vector startTangent, - Vector endTangent, - string systemName = "", - string systemType = "", - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseCurve = baseCurve; - this.diameter = diameter; - this.startTangent = startTangent; - this.endTangent = endTangent; - this.systemName = systemName; - this.systemType = systemType; - this.level = level; - this.parameters = parameters.ToBase(); - } + public string units { get; set; } - public Vector startTangent { get; set; } - public Vector endTangent { get; set; } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Profile.cs b/Objects/Objects/BuiltElements/Profile.cs index aab45cd152..3f4be956bc 100644 --- a/Objects/Objects/BuiltElements/Profile.cs +++ b/Objects/Objects/BuiltElements/Profile.cs @@ -2,43 +2,20 @@ using Objects.Geometry; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Profile : Base, IDisplayValue - { - public List curves { get; set; } - - public string name { get; set; } - - public double startStation { get; set; } - - public double endStation { get; set; } +namespace Objects.BuiltElements; - public string units { get; set; } - - [DetachProperty] - public Polyline displayValue { get; set; } - } -} - -namespace Objects.BuiltElements.Civil +public class Profile : Base, IDisplayValue { - public class CivilProfile : Profile - { - public string type { get; set; } + public List curves { get; set; } + + public string name { get; set; } - public string style { get; set; } + public double startStation { get; set; } - public double offset { get; set; } + public double endStation { get; set; } - /// - /// Points of vertical intersection - /// - public List pvis { get; set; } + public string units { get; set; } - /// - /// Name of parent profile if this is an offset profile - /// - public string parent { get; set; } - } + [DetachProperty] + public Polyline displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Rebar.cs b/Objects/Objects/BuiltElements/Rebar.cs index 1db5764df0..4034847242 100644 --- a/Objects/Objects/BuiltElements/Rebar.cs +++ b/Objects/Objects/BuiltElements/Rebar.cs @@ -1,289 +1,158 @@ using System; using System.Collections.Generic; -using Speckle.Newtonsoft.Json; -using Objects.BuiltElements.TeklaStructures; using Objects.Geometry; -using Objects.Structural.Materials; using Speckle.Core.Models; -namespace Objects.BuiltElements +namespace Objects.BuiltElements; + +/// +/// A reinforcement bar group comprised of reinforcing bars of the same type and shape. +/// +/// +/// This class is not suitable for freeform rebar, which can have multiple shapes. +/// +public class RebarGroup : Base, IHasVolume, IDisplayValue> + where T : RebarShape { + public RebarGroup() { } + + /// + /// The shape of the rebar group + /// + [DetachProperty] + public RebarShape shape { get; set; } + /// - /// A reinforcement bar group comprised of reinforcing bars of the same type and shape. + /// The number of rebars in the rebar group /// /// - /// This class is not suitable for freeform rebar, which can have multiple shapes. + /// Excluded end bars are not included in the count /// - public class RebarGroup : Base, IHasVolume, IDisplayValue> - where T : RebarShape - { - public RebarGroup() { } - - /// - /// The shape of the rebar group - /// - [DetachProperty] - public RebarShape shape { get; set; } - - /// - /// The number of rebars in the rebar group - /// - /// - /// Excluded end bars are not included in the count - /// - public int number { get; set; } - - /// - /// Indicates if rebar set includes the first bar - /// - /// - /// Only applicable to stirrup (transverse) rebar - /// - public bool hasFirstBar { get; set; } - - /// - /// Indicates if rebar set includes the last bar - /// - /// - /// Only applicable to stirrup (transverse) rebar - /// - public bool hasLastBar { get; set; } - - /// - /// The start hook of bars in the rebar group - /// - /// - /// Null indicates no start hook - /// - [DetachProperty] - public virtual RebarHook? startHook { get; set; } - - /// - /// The end hook of bars in the rebar group - /// - /// - /// Null indicates no end hook - /// - [DetachProperty] - public virtual RebarHook? endHook { get; set; } - - /// - /// The display representation of the rebar group as centerline curves - /// - [DetachProperty] - public List displayValue { get; set; } - - /// - /// The total volume of the rebar group. - /// - public double volume { get; set; } - - public string units { get; set; } - } + public int number { get; set; } /// - /// The shape describing the geometry and geometry parameters of a reinforcing bar + /// Indicates if rebar set includes the first bar /// - public class RebarShape : Base - { - public RebarShape() { } - - /// - /// The name of the rebar shape - /// - public string name { get; set; } - - /// - /// The type of the rebar shape - /// - public RebarType rebarType { get; set; } - - /// - /// The curves of the rebar shape - /// - /// - /// Typically suppresses hooks and bend radius - /// - public List curves { get; set; } = new(); - - /// - /// The diameter of the rebar bar - /// - public double barDiameter { get; set; } - - public string units { get; set; } - } - - public class RebarHook : Base - { - public RebarHook() { } - - /// - /// The angle of the hook in radians. - /// - public double angle { get; set; } - - /// - /// The length of the hook. - /// - public double length { get; set; } - - /// - /// The radius of the bend of the hook. - /// - public double radius { get; set; } + /// + /// Only applicable to stirrup (transverse) rebar + /// + public bool hasFirstBar { get; set; } - public string units { get; set; } - } + /// + /// Indicates if rebar set includes the last bar + /// + /// + /// Only applicable to stirrup (transverse) rebar + /// + public bool hasLastBar { get; set; } - public enum RebarType - { - Unknown = 0, - Standard = 10, - StirrupPolygonal = 20, - StirrupSpiral = 30, - StirrupTapered = 40 - } + /// + /// The start hook of bars in the rebar group + /// + /// + /// Null indicates no start hook + /// + [DetachProperty] + public virtual RebarHook? startHook { get; set; } - #region Obsolete - [Obsolete("Deprecated in 2.17: Use the RebarGroup class instead")] - public class Rebar : Base, IHasVolume, IDisplayValue> - { - public List curves { get; set; } = new(); + /// + /// The end hook of bars in the rebar group + /// + /// + /// Null indicates no end hook + /// + [DetachProperty] + public virtual RebarHook? endHook { get; set; } - public string units { get; set; } + /// + /// The display representation of the rebar group as centerline curves + /// + [DetachProperty] + public List displayValue { get; set; } - [DetachProperty] - public List displayValue { get; set; } + /// + /// The total volume of the rebar group. + /// + public double volume { get; set; } - public double volume { get; set; } - } - #endregion + public string units { get; set; } } -namespace Objects.BuiltElements.TeklaStructures +/// +/// The shape describing the geometry and geometry parameters of a reinforcing bar +/// +public class RebarShape : Base { - #region Obsolete - [Obsolete("Deprecated in 2.17: Create a TeklaRebarGroup class instead")] - public class TeklaRebar : Rebar - { - public string name { get; set; } - - [DetachProperty] - public Hook startHook { get; set; } + public RebarShape() { } - [DetachProperty] - public Hook endHook { get; set; } + /// + /// The name of the rebar shape + /// + public string name { get; set; } - public double classNumber { get; set; } - public string size { get; set; } + /// + /// The type of the rebar shape + /// + public RebarType rebarType { get; set; } - [DetachProperty] - public StructuralMaterial material { get; set; } - } + /// + /// The curves of the rebar shape + /// + /// + /// Typically suppresses hooks and bend radius + /// + public List curves { get; set; } = new(); - [Obsolete("Deprecated in 2.17: Use a RebarHook class instead")] - public class Hook : Base - { - public double angle { get; set; } - public double length { get; set; } - public double radius { get; set; } - public shape shape { get; set; } - } + /// + /// The diameter of the rebar bar + /// + public double barDiameter { get; set; } - [Obsolete("Deprecated in 2.17: set starthook and endhook to null or refer to hook angle instead")] - public enum shape - { - NO_HOOK = 0, - HOOK_90_DEGREES = 1, - HOOK_135_DEGREES = 2, - HOOK_180_DEGREES = 3, - CUSTOM_HOOK = 4 - } - #endregion + public string units { get; set; } } -namespace Objects.BuiltElements.Revit +public class RebarHook : Base { - public class RevitRebarGroup : RebarGroup - { - public RevitRebarGroup() { } - - [JsonIgnore] - public RevitRebarShape revitShape { get; set; } - - public override RebarHook? startHook - { - get => revitStartHook; - set - { - if (value is not RevitRebarHook && value is not null) - { - throw new ArgumentException($"Expected object of type {nameof(RevitRebarHook)} or null"); - } + public RebarHook() { } - revitStartHook = (RevitRebarHook)value; - } - } - - [JsonIgnore] - public RevitRebarHook? revitStartHook { get; set; } - - public override RebarHook? endHook - { - get => revitEndHook; - set - { - if (value is not RevitRebarHook && value is not null) - { - throw new ArgumentException($"Expected object of type {nameof(RevitRebarHook)} or null"); - } + /// + /// The angle of the hook in radians. + /// + public double angle { get; set; } - revitEndHook = (RevitRebarHook)value; - } - } + /// + /// The length of the hook. + /// + public double length { get; set; } - [JsonIgnore] - public RevitRebarHook? revitEndHook { get; set; } + /// + /// The radius of the bend of the hook. + /// + public double radius { get; set; } - public string family { get; set; } - public string type { get; set; } - public int barPositions { get; set; } - public Vector normal { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } + public string units { get; set; } +} - public class RevitRebarShape : RebarShape - { - public RevitRebarShape() { } +public enum RebarType +{ + Unknown = 0, + Standard = 10, + StirrupPolygonal = 20, + StirrupSpiral = 30, + StirrupTapered = 40 +} - public Base parameters { get; set; } - public string elementId { get; set; } - } +#region Obsolete +[Obsolete("Deprecated in 2.17: Use the RebarGroup class instead")] +public class Rebar : Base, IHasVolume, IDisplayValue> +{ + public List curves { get; set; } = new(); - public class RevitRebarHook : RebarHook - { - public RevitRebarHook() { } + public string units { get; set; } - public double multiplier { get; set; } - public string orientation { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } + [DetachProperty] + public List displayValue { get; set; } - #region Obsolete - [Obsolete("Deprecated in 2.17: Use RevitRebarGroup class instead", true)] - public class RevitRebar : Rebar - { - public string family { get; set; } - public string type { get; set; } - public string host { get; set; } - public string barType { get; set; } - public string barStyle { get; set; } - public List shapes { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } - #endregion + public double volume { get; set; } } +#endregion diff --git a/Objects/Objects/BuiltElements/Revit/AdaptiveComponent.cs b/Objects/Objects/BuiltElements/Revit/AdaptiveComponent.cs index c752ffd865..e06fb4ada6 100644 --- a/Objects/Objects/BuiltElements/Revit/AdaptiveComponent.cs +++ b/Objects/Objects/BuiltElements/Revit/AdaptiveComponent.cs @@ -16,14 +16,14 @@ public AdaptiveComponent( string family, List basePoints, bool flipped = false, - List parameters = null + List? parameters = null ) { this.type = type; this.family = family; this.basePoints = basePoints; this.flipped = flipped; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public string type { get; set; } @@ -31,7 +31,7 @@ public AdaptiveComponent( public List basePoints { get; set; } public bool flipped { get; set; } public string elementId { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string units { get; set; } diff --git a/Objects/Objects/BuiltElements/Revit/ModelCurves.cs b/Objects/Objects/BuiltElements/Revit/Curve/ModelCurves.cs similarity index 78% rename from Objects/Objects/BuiltElements/Revit/ModelCurves.cs rename to Objects/Objects/BuiltElements/Revit/Curve/ModelCurves.cs index b30d1ce108..b0f458481a 100644 --- a/Objects/Objects/BuiltElements/Revit/ModelCurves.cs +++ b/Objects/Objects/BuiltElements/Revit/Curve/ModelCurves.cs @@ -10,16 +10,16 @@ public class ModelCurve : Base public ModelCurve() { } [SchemaInfo("ModelCurve", "Creates a Revit model curve", "Revit", "Curves")] - public ModelCurve([SchemaMainParam] ICurve baseCurve, string lineStyle, List parameters = null) + public ModelCurve([SchemaMainParam] ICurve baseCurve, string lineStyle, List? parameters = null) { this.baseCurve = baseCurve; this.lineStyle = lineStyle; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public ICurve baseCurve { get; set; } public string lineStyle { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } public string units { get; set; } @@ -30,16 +30,16 @@ public class DetailCurve : Base public DetailCurve() { } [SchemaInfo("DetailCurve", "Creates a Revit detail curve", "Revit", "Curves")] - public DetailCurve([SchemaMainParam] ICurve baseCurve, string lineStyle, List parameters = null) + public DetailCurve([SchemaMainParam] ICurve baseCurve, string lineStyle, List? parameters = null) { this.baseCurve = baseCurve; this.lineStyle = lineStyle; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public ICurve baseCurve { get; set; } public string lineStyle { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } public string units { get; set; } @@ -50,14 +50,14 @@ public class RoomBoundaryLine : Base public RoomBoundaryLine() { } [SchemaInfo("RoomBoundaryLine", "Creates a Revit room boundary line", "Revit", "Curves")] - public RoomBoundaryLine([SchemaMainParam] ICurve baseCurve, List parameters = null) + public RoomBoundaryLine([SchemaMainParam] ICurve baseCurve, List? parameters = null) { this.baseCurve = baseCurve; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public ICurve baseCurve { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } public Level level { get; set; } public string units { get; set; } @@ -68,14 +68,14 @@ public class SpaceSeparationLine : Base public SpaceSeparationLine() { } [SchemaInfo("SpaceSeparationLine", "Creates a Revit space separation line", "Revit", "Curves")] - public SpaceSeparationLine([SchemaMainParam] ICurve baseCurve, List parameters = null) + public SpaceSeparationLine([SchemaMainParam] ICurve baseCurve, List? parameters = null) { this.baseCurve = baseCurve; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public ICurve baseCurve { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } public string units { get; set; } } diff --git a/Objects/Objects/BuiltElements/Revit/DirectShape.cs b/Objects/Objects/BuiltElements/Revit/DirectShape.cs index 12f8dd8caf..aa1031006a 100644 --- a/Objects/Objects/BuiltElements/Revit/DirectShape.cs +++ b/Objects/Objects/BuiltElements/Revit/DirectShape.cs @@ -23,27 +23,27 @@ public DirectShape() { } "Revit", "Families" )] - public DirectShape(string name, RevitCategory category, List baseGeometries, List parameters = null) + public DirectShape(string name, RevitCategory category, List baseGeometries, List? parameters = null) { this.name = name; this.category = category; this.baseGeometries = baseGeometries.FindAll(IsValidObject); - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } // moving away from using the RevitCategory Enum - public DirectShape(string name, string builtInCategory, List baseGeometries, List parameters = null) + public DirectShape(string name, string builtInCategory, List baseGeometries, List? parameters = null) { this.name = name; this.baseGeometries = baseGeometries.FindAll(IsValidObject); - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); //TODO: move to typed property alongside all other revit elements this["builtInCategory"] = builtInCategory; } public string name { get; set; } public RevitCategory category { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } [DetachProperty] diff --git a/Objects/Objects/BuiltElements/Revit/FamilyInstance.cs b/Objects/Objects/BuiltElements/Revit/FamilyInstance.cs index c30c6ad5fa..62a2242b47 100644 --- a/Objects/Objects/BuiltElements/Revit/FamilyInstance.cs +++ b/Objects/Objects/BuiltElements/Revit/FamilyInstance.cs @@ -19,7 +19,7 @@ public FamilyInstance( double rotation = 0, bool facingFlipped = false, bool handFlipped = false, - List parameters = null + List? parameters = null ) { this.basePoint = basePoint; @@ -30,7 +30,7 @@ public FamilyInstance( this.facingFlipped = facingFlipped; this.handFlipped = handFlipped; mirrored = false; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public Point basePoint { get; set; } @@ -42,7 +42,7 @@ public FamilyInstance( public bool facingFlipped { get; set; } public bool handFlipped { get; set; } public bool mirrored { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } public string elementId { get; set; } [DetachProperty] diff --git a/Objects/Objects/BuiltElements/Revit/FreeformElement.cs b/Objects/Objects/BuiltElements/Revit/FreeformElement.cs index 662440169c..a94eb7f928 100644 --- a/Objects/Objects/BuiltElements/Revit/FreeformElement.cs +++ b/Objects/Objects/BuiltElements/Revit/FreeformElement.cs @@ -19,7 +19,7 @@ public FreeformElement() { } "Revit", "Families" )] - public FreeformElement(List baseGeometries, string subcategory = "", List parameters = null) + public FreeformElement(List baseGeometries, string subcategory = "", List? parameters = null) { this.baseGeometries = baseGeometries; //this.category = category; @@ -29,12 +29,11 @@ public FreeformElement(List baseGeometries, string subcategory = "", List< throw new Exception("Freeform elements can only be created from BREPs or Meshes"); } - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } - public Base parameters { get; set; } + public Base? parameters { get; set; } - //public RevitCategory category { get; set; } public string subcategory { get; set; } public string elementId { get; set; } @@ -45,6 +44,11 @@ public FreeformElement(List baseGeometries, string subcategory = "", List< /// It will set the first item on the baseGeometries list, and instantiate a list if necessary. /// [JsonIgnore, SchemaIgnore, Obsolete("Use 'baseGeometries' instead", true)] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1044:Properties should not be write only", + Justification = "Obsolete" + )] public Base baseGeometry { set @@ -93,7 +97,12 @@ public bool IsValidObject(Base @base) "Families" ) ] - public FreeformElement(Base baseGeometry, List parameters = null) + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Usage", + "CA2201:Do not raise reserved exception types", + Justification = "Obsolete" + )] + public FreeformElement(Base baseGeometry, List? parameters = null) { if (!IsValidObject(baseGeometry)) { @@ -101,7 +110,7 @@ public FreeformElement(Base baseGeometry, List parameters = null) } baseGeometries = new List { baseGeometry }; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } [ @@ -113,7 +122,12 @@ public FreeformElement(Base baseGeometry, List parameters = null) "Families" ) ] - public FreeformElement(List baseGeometries, List parameters = null) + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Usage", + "CA2201:Do not raise reserved exception types", + Justification = "Obsolete" + )] + public FreeformElement(List baseGeometries, List? parameters = null) { this.baseGeometries = baseGeometries; if (!IsValid()) @@ -121,7 +135,7 @@ public FreeformElement(List baseGeometries, List parameters = n throw new Exception("Freeform elements can only be created from BREPs or Meshes"); } - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } #endregion diff --git a/Objects/Objects/BuiltElements/Revit/Interfaces/IHasMEPConnectors.cs b/Objects/Objects/BuiltElements/Revit/Interfaces/IHasMEPConnectors.cs index 19a3620b27..664aba86f2 100644 --- a/Objects/Objects/BuiltElements/Revit/Interfaces/IHasMEPConnectors.cs +++ b/Objects/Objects/BuiltElements/Revit/Interfaces/IHasMEPConnectors.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; namespace Objects.BuiltElements.Revit.Interfaces; diff --git a/Objects/Objects/BuiltElements/Revit/Parameter.cs b/Objects/Objects/BuiltElements/Revit/Parameter.cs index 39bd1ed954..864ac646a2 100644 --- a/Objects/Objects/BuiltElements/Revit/Parameter.cs +++ b/Objects/Objects/BuiltElements/Revit/Parameter.cs @@ -1,4 +1,3 @@ -#nullable enable using Speckle.Core.Kits; using Speckle.Core.Models; @@ -34,14 +33,14 @@ public Parameter( /// If True it's a Shared Parameter, in which case the ApplicationId field will contain this parameter GUID, /// otherwise it will store its BuiltInParameter name /// - public bool isShared { get; set; } = false; + public bool isShared { get; set; } - public bool isReadOnly { get; set; } = false; + public bool isReadOnly { get; set; } /// /// True = Type Parameter, False = Instance Parameter /// - public bool isTypeParameter { get; set; } = false; + public bool isTypeParameter { get; set; } public string units { get; set; } } diff --git a/Objects/Objects/BuiltElements/Revit/ParameterUpdater.cs b/Objects/Objects/BuiltElements/Revit/ParameterUpdater.cs index cce89421c2..7c50e1b1ce 100644 --- a/Objects/Objects/BuiltElements/Revit/ParameterUpdater.cs +++ b/Objects/Objects/BuiltElements/Revit/ParameterUpdater.cs @@ -17,5 +17,5 @@ public ParameterUpdater([SchemaParamInfo("A Revit ElementId or UniqueId")] strin public ParameterUpdater() { } public string elementId { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } } diff --git a/Objects/Objects/BuiltElements/Revit/RevitBeam.cs b/Objects/Objects/BuiltElements/Revit/RevitBeam.cs new file mode 100644 index 0000000000..b483b12a11 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitBeam.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitBeam : Beam +{ + public RevitBeam() { } + + [SchemaInfo("RevitBeam", "Creates a Revit beam by curve and base level.", "Revit", "Structure")] + public RevitBeam( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + public string family { get; set; } + public string type { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitBrace.cs b/Objects/Objects/BuiltElements/Revit/RevitBrace.cs new file mode 100644 index 0000000000..99499f8826 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitBrace.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitBrace : Brace +{ + public RevitBrace() { } + + [SchemaInfo("RevitBrace", "Creates a Revit brace by curve and base level.", "Revit", "Structure")] + public RevitBrace( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + public string family { get; set; } + public string type { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + public Level level { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitCableTray.cs b/Objects/Objects/BuiltElements/Revit/RevitCableTray.cs new file mode 100644 index 0000000000..0b7b485299 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitCableTray.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit.Interfaces; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitCableTray : CableTray, IHasMEPConnectors +{ + public string family { get; set; } + public string type { get; set; } + public Level level { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } + public List Connectors { get; set; } = new(); +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitCeiling.cs b/Objects/Objects/BuiltElements/Revit/RevitCeiling.cs new file mode 100644 index 0000000000..874ca2efa2 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitCeiling.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitCeiling : Ceiling +{ + public RevitCeiling() { } + + [SchemaDeprecated, SchemaInfo("RevitCeiling", "Creates a Revit ceiling", "Revit", "Architecture")] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Style", + "IDE0060:Remove unused parameter", + Justification = "Obsolete" + )] + public RevitCeiling( + [SchemaMainParam, SchemaParamInfo("Planar boundary curve")] ICurve outline, + string family, + string type, + Level level, + double slope = 0, + [SchemaParamInfo("Planar line indicating slope direction")] Line? slopeDirection = null, + double offset = 0, + List? voids = null, + [SchemaParamInfo("Any nested elements that this ceiling might have")] List? elements = null + ) + { + this.outline = outline; + this.family = family; + this.type = type; + this.level = level; + this.slope = slope; + this.slopeDirection = slopeDirection; + this.voids = voids ?? new(); + this.elements = elements; + } + + [SchemaInfo("RevitCeiling", "Creates a Revit ceiling", "Revit", "Architecture")] + public RevitCeiling( + [SchemaMainParam, SchemaParamInfo("Planar boundary curve")] ICurve outline, + string family, + string type, + Level level, + double slope = 0, + [SchemaParamInfo("Planar line indicating slope direction")] Line? slopeDirection = null, + List? voids = null, + [SchemaParamInfo("Any nested elements that this ceiling might have")] List? elements = null + ) + { + this.outline = outline; + this.family = family; + this.type = type; + this.level = level; + this.slope = slope; + this.slopeDirection = slopeDirection; + this.voids = voids ?? new(); + this.elements = elements; + } + + public string family { get; set; } + public string type { get; set; } + public Level level { get; set; } + public double slope { get; set; } + public Line? slopeDirection { get; set; } + + [Obsolete("Offset property is now captured in parameters to match the behavior of other Revit objects", true)] + public double offset { get; set; } + + public Base parameters { get; set; } + public string elementId { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitColumn.cs b/Objects/Objects/BuiltElements/Revit/RevitColumn.cs new file mode 100644 index 0000000000..5a770db9ba --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitColumn.cs @@ -0,0 +1,114 @@ +using System.Collections.Generic; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitColumn : Column +{ + public RevitColumn() { } + + /// + /// SchemaBuilder constructor for a Revit column + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to and params + [SchemaInfo("RevitColumn Vertical", "Creates a vertical Revit Column by point and levels.", "Revit", "Architecture")] + public RevitColumn( + string family, + string type, + [SchemaParamInfo("Only the lower point of this line will be used as base point."), SchemaMainParam] ICurve baseLine, + Level level, + Level topLevel, + double baseOffset = 0, + double topOffset = 0, + bool structural = false, + [SchemaParamInfo("Rotation angle in radians")] double rotation = 0, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.topLevel = topLevel; + this.baseOffset = baseOffset; + this.topOffset = topOffset; + this.rotation = rotation; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + [ + SchemaDeprecated, + SchemaInfo("RevitColumn Slanted (old)", "Creates a slanted Revit Column by curve.", "Revit", "Structure") + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Style", + "IDE0060:Remove unused parameter", + Justification = "Obsolete" + )] + public RevitColumn( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + bool structural = false, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.level = level; + isSlanted = true; + this.parameters = parameters?.ToBase(); + } + + [SchemaInfo("RevitColumn Slanted", "Creates a slanted Revit Column by curve.", "Revit", "Structure")] + public RevitColumn( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + Level? topLevel = null, + bool structural = false, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.level = level; + this.topLevel = topLevel; + isSlanted = true; + this.parameters = parameters?.ToBase(); + } + + public new Level? level + { + get => base.level; + set => base.level = value; + } + + public Level? topLevel { get; set; } + public double baseOffset { get; set; } + public double topOffset { get; set; } + public bool facingFlipped { get; set; } + public bool handFlipped { get; set; } + public double rotation { get; set; } + public bool isSlanted { get; set; } + public string family { get; set; } + public string type { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitConduit.cs b/Objects/Objects/BuiltElements/Revit/RevitConduit.cs new file mode 100644 index 0000000000..6b4acfabee --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitConduit.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit.Interfaces; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitConduit : Conduit, IHasMEPConnectors +{ + public string family { get; set; } + + public string type { get; set; } + + public Level level { get; set; } + + public Base parameters { get; set; } + + public string elementId { get; set; } + public List Connectors { get; set; } = new(); +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitCurtainWallPanel.cs b/Objects/Objects/BuiltElements/Revit/RevitCurtainWallPanel.cs index e3b331eb2d..71fbefcd46 100644 --- a/Objects/Objects/BuiltElements/Revit/RevitCurtainWallPanel.cs +++ b/Objects/Objects/BuiltElements/Revit/RevitCurtainWallPanel.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace Objects.BuiltElements.Revit; public class RevitCurtainWallPanel : RevitElement { } diff --git a/Objects/Objects/BuiltElements/Revit/RevitDuct.cs b/Objects/Objects/BuiltElements/Revit/RevitDuct.cs new file mode 100644 index 0000000000..8c75f4ba04 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitDuct.cs @@ -0,0 +1,163 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit.Interfaces; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitDuct : Duct, IHasMEPConnectors +{ + public RevitDuct() { } + + /// + /// SchemaBuilder constructor for a Revit duct (deprecated) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("RevitDuct", "Creates a Revit duct", "Revit", "MEP"), SchemaDeprecated] + public RevitDuct( + string family, + string type, + [SchemaMainParam] Line baseLine, + string systemName, + string systemType, + Level level, + double width, + double height, + double diameter, + double velocity = 0, + List? parameters = null + ) + { + baseCurve = baseLine; + this.family = family; + this.type = type; + this.width = width; + this.height = height; + this.diameter = diameter; + this.velocity = velocity; + this.systemName = systemName; + this.systemType = systemType; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + /// + /// SchemaBuilder constructor for a Revit duct + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("RevitDuct", "Creates a Revit duct", "Revit", "MEP")] + public RevitDuct( + string family, + string type, + [SchemaMainParam] ICurve baseCurve, + string systemName, + string systemType, + Level level, + double width, + double height, + double diameter, + double velocity = 0, + List? parameters = null + ) + { + this.baseCurve = baseCurve; + this.family = family; + this.type = type; + this.width = width; + this.height = height; + this.diameter = diameter; + this.velocity = velocity; + this.systemName = systemName; + this.systemType = systemType; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + public string family { get; set; } + public string type { get; set; } + public string systemName { get; set; } + public string systemType { get; set; } + public Level level { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + public List Connectors { get; set; } = new(); +} + +public class RevitFlexDuct : RevitDuct +{ + public RevitFlexDuct() { } + + /// + /// SchemaBuilder constructor for a Revit flex duct + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("RevitFlexDuct", "Creates a Revit flex duct", "Revit", "MEP")] + public RevitFlexDuct( + string family, + string type, + [SchemaMainParam] ICurve baseCurve, + string systemName, + string systemType, + Level level, + double width, + double height, + double diameter, + Vector startTangent, + Vector endTangent, + double velocity = 0, + List? parameters = null + ) + { + this.baseCurve = baseCurve; + this.family = family; + this.type = type; + this.width = width; + this.height = height; + this.diameter = diameter; + this.startTangent = startTangent; + this.endTangent = endTangent; + this.velocity = velocity; + this.systemName = systemName; + this.systemType = systemType; + this.parameters = parameters?.ToBase(); + this.level = level; + } + + public Vector startTangent { get; set; } + public Vector endTangent { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitFloor.cs b/Objects/Objects/BuiltElements/Revit/RevitFloor.cs new file mode 100644 index 0000000000..35baa3d8a3 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitFloor.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitFloor : Floor +{ + public RevitFloor() { } + + [SchemaInfo("RevitFloor", "Creates a Revit floor by outline and level", "Revit", "Architecture")] + public RevitFloor( + string family, + string type, + [SchemaMainParam] ICurve outline, + Level level, + bool structural = false, + double slope = 0, + Line? slopeDirection = null, + List? voids = null, + [SchemaParamInfo("Any nested elements that this floor might have")] List? elements = null, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.level = level; + this.structural = structural; + this.slope = slope; + this.slopeDirection = slopeDirection; + this.parameters = parameters?.ToBase(); + this.outline = outline; + this.voids = voids ?? new(); + this.elements = elements; + } + + public string family { get; set; } + public string type { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } + + public bool structural { get; set; } + public double slope { get; set; } + public Line? slopeDirection { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitLevel.cs b/Objects/Objects/BuiltElements/Revit/RevitLevel.cs new file mode 100644 index 0000000000..a3c8c7ce42 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitLevel.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitLevel : Level +{ + public RevitLevel() { } + + /// + /// SchemaBuilder constructor for a Revit level + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to param + [SchemaInfo( + "RevitLevel", + "Creates a new Revit level unless one with the same elevation already exists", + "Revit", + "Architecture" + )] + public RevitLevel( + [SchemaParamInfo("Level name. NOTE: updating level name is not supported")] string name, + [SchemaParamInfo( + "Level elevation. NOTE: updating level elevation is not supported, a new one will be created unless another level at the new elevation already exists." + )] + double elevation, + [SchemaParamInfo( + "If true, it creates an associated view in Revit. NOTE: only used when creating a level for the first time" + )] + bool createView, + List? parameters = null + ) + { + this.name = name; + this.elevation = elevation; + this.createView = createView; + this.parameters = parameters?.ToBase(); + referenceOnly = false; + } + + [SchemaInfo("RevitLevel by name", "Gets an existing Revit level by name", "Revit", "Architecture")] + public RevitLevel(string name) + { + this.name = name; + referenceOnly = true; + } + + public bool createView { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + public bool referenceOnly { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitMEPConnector.cs b/Objects/Objects/BuiltElements/Revit/RevitMEPConnector.cs index 9ce825778a..8032ef22a5 100644 --- a/Objects/Objects/BuiltElements/Revit/RevitMEPConnector.cs +++ b/Objects/Objects/BuiltElements/Revit/RevitMEPConnector.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; -using System.Linq; using Objects.Geometry; -using Objects.Organization; using Speckle.Core.Models; namespace Objects.BuiltElements.Revit; diff --git a/Objects/Objects/BuiltElements/Revit/RevitNetwork.cs b/Objects/Objects/BuiltElements/Revit/RevitNetwork.cs new file mode 100644 index 0000000000..16cfdadb92 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitNetwork.cs @@ -0,0 +1,76 @@ +using System; +using Objects.Geometry; + +namespace Objects.BuiltElements.Revit; + +[Obsolete( + "Networks are no longer used to assemble MEP systems in Revit. See the RevitCommitBuilder for MEP systems conversion." +)] +public class RevitNetworkElement : NetworkElement +{ + public RevitNetworkElement() { } + + /// + /// Indicates if this element was constructed from an MEP curve + /// + public bool isCurveBased { get; set; } + + /// + /// Indicates if this element needs temporary placeholder objects to be created first when receiving + /// + /// + /// For example, some fittings cannot be created based on connectors, and so will be created similarly to mechanical equipment + /// + public bool isConnectorBased { get; set; } +} + +[Obsolete( + "Networks are no longer used to assemble MEP systems in Revit. See the RevitCommitBuilder for MEP systems conversion." +)] +public class RevitNetworkLink : NetworkLink +{ + public double height { get; set; } + public double width { get; set; } + public double diameter { get; set; } + public Point origin { get; set; } + public Vector direction { get; set; } + + /// + /// The system category + /// + public string systemName { get; set; } + + public string systemType { get; set; } + + /// + /// The connector profile shape of the + /// + public string shape { get; set; } + + /// + /// The link domain + /// + public string domain { get; set; } + + /// + /// The index indicating the position of this link on the connected fitting element, if applicable + /// + /// + /// Revit fitting links are 1-indexed. For example, "T" fittings will have ordered links from index 1-3. + /// + public int fittingIndex { get; set; } + + /// + /// Indicates if this link needs temporary placeholder objects to be created first when receiving + /// + /// + /// Placeholder geometry are curves. + /// For example, U-bend links need temporary pipes to be created first, if one or more linked pipes have not yet been created in the network. + /// + public bool needsPlaceholders { get; set; } + + /// + /// Indicates if this link has been connected to its elements + /// + public bool isConnected { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitOpening.cs b/Objects/Objects/BuiltElements/Revit/RevitOpening.cs new file mode 100644 index 0000000000..d502ab4d1c --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitOpening.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Logging; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitOpening : Opening +{ + public Base? parameters { get; set; } + public string elementId { get; set; } +} + +public class RevitVerticalOpening : RevitOpening { } + +public class RevitWallOpening : RevitOpening +{ + public RevitWallOpening() { } + + [ + Obsolete("Use constructor with Polyline input instead"), + SchemaDeprecated, + SchemaInfo("Revit Wall Opening (Deprecated)", "Creates a Speckle Wall opening for revit", "BIM", "Architecture") + ] + public RevitWallOpening(ICurve outline, RevitWall? host = null) + { + if (outline is not Polyline) + { + throw new SpeckleException("Outline should be a rectangular-shaped polyline", false); + } + + this.outline = outline; + this.host = host; + } + + [SchemaInfo("Revit Wall Opening", "Creates a Speckle Wall opening for revit", "Revit", "Architecture")] + public RevitWallOpening(Polyline outline, RevitWall? host = null) + { + if (outline == null) + { + throw new SpeckleException("Outline cannot be null"); + } + + if (outline.GetPoints().Count != 4) + { + throw new SpeckleException("Outline should be a rectangular-shaped polyline"); + } + + this.outline = outline; + this.host = host; + } + + public RevitWall? host { get; set; } +} + +public class RevitShaft : RevitOpening +{ + public RevitShaft() { } + + /// + /// SchemaBuilder constructor for a Revit shaft + /// + /// + /// + /// + /// + [SchemaInfo("RevitShaft", "Creates a Revit shaft from a bottom and top level", "Revit", "Architecture")] + public RevitShaft( + [SchemaMainParam] ICurve outline, + Level bottomLevel, + Level topLevel, + List? parameters = null + ) + { + this.outline = outline; + this.bottomLevel = bottomLevel; + this.topLevel = topLevel; + this.parameters = parameters?.ToBase(); + } + + public Level bottomLevel { get; set; } + public Level topLevel { get; set; } + public double height { get; set; } + + /* + /// + /// SchemaBuilder constructor for a Revit shaft + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to param + [SchemaInfo("RevitShaft", "Creates a Revit shaft from a bottom level and height")] + public RevitShaft(ICurve outline, Level bottomLevel, double height, List parameters = null) + { + this.outline = outline; + this.bottomLevel = bottomLevel; + this.height = height; + this.parameters = parameters.ToBase(); + } + */ +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitPipe.cs b/Objects/Objects/BuiltElements/Revit/RevitPipe.cs new file mode 100644 index 0000000000..6084bd61b8 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitPipe.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit.Interfaces; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitPipe : Pipe, IHasMEPConnectors +{ + public RevitPipe() { } + + [SchemaInfo("RevitPipe", "Creates a Revit pipe", "Revit", "MEP")] + public RevitPipe( + string family, + string type, + [SchemaMainParam] ICurve baseCurve, + double diameter, + Level level, + string systemName = "", + string systemType = "", + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseCurve = baseCurve; + this.diameter = diameter; + this.systemName = systemName; + this.systemType = systemType; + this.level = level; + this.parameters = parameters?.ToBase(); + } + + public string family { get; set; } + public string type { get; set; } + public string systemName { get; set; } + public string systemType { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + public Level level { get; set; } + public List Connectors { get; set; } = new(); +} + +public class RevitFlexPipe : RevitPipe +{ + public RevitFlexPipe() { } + + [SchemaInfo("RevitFlexPipe", "Creates a Revit flex pipe", "Revit", "MEP")] + public RevitFlexPipe( + string family, + string type, + [SchemaMainParam] ICurve baseCurve, + double diameter, + Level level, + Vector startTangent, + Vector endTangent, + string systemName = "", + string systemType = "", + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseCurve = baseCurve; + this.diameter = diameter; + this.startTangent = startTangent; + this.endTangent = endTangent; + this.systemName = systemName; + this.systemType = systemType; + this.level = level; + this.parameters = parameters?.ToBase(); + } + + public Vector startTangent { get; set; } + public Vector endTangent { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitRebar.cs b/Objects/Objects/BuiltElements/Revit/RevitRebar.cs new file mode 100644 index 0000000000..e84cdce399 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitRebar.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using Speckle.Newtonsoft.Json; +using Objects.Geometry; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitRebarGroup : RebarGroup +{ + public RevitRebarGroup() { } + + [JsonIgnore] + public RevitRebarShape revitShape { get; set; } + + public override RebarHook? startHook + { + get => revitStartHook; + set => + revitStartHook = value switch + { + RevitRebarHook o => o, + null => null, + _ => throw new ArgumentException($"Expected object of type {nameof(RevitRebarHook)} or null"), + }; + } + + [JsonIgnore] + public RevitRebarHook? revitStartHook { get; set; } + + public override RebarHook? endHook + { + get => revitEndHook; + set => + revitEndHook = value switch + { + RevitRebarHook o => o, + null => null, + _ => throw new ArgumentException($"Expected object of type {nameof(RevitRebarHook)} or null"), + }; + } + + [JsonIgnore] + public RevitRebarHook? revitEndHook { get; set; } + + public string family { get; set; } + public string type { get; set; } + public int barPositions { get; set; } + public Vector normal { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } +} + +public class RevitRebarShape : RebarShape +{ + public RevitRebarShape() { } + + public Base parameters { get; set; } + public string elementId { get; set; } +} + +public class RevitRebarHook : RebarHook +{ + public RevitRebarHook() { } + + public double multiplier { get; set; } + public string orientation { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } +} + +#region Obsolete +[Obsolete("Deprecated in 2.17: Use RevitRebarGroup class instead")] +public class RevitRebar : Rebar +{ + public string family { get; set; } + public string type { get; set; } + public string host { get; set; } + public string barType { get; set; } + public string barStyle { get; set; } + public List shapes { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } +} +#endregion diff --git a/Objects/Objects/BuiltElements/Revit/RevitRoof/RevitRoof.cs b/Objects/Objects/BuiltElements/Revit/RevitRoof/RevitRoof.cs new file mode 100644 index 0000000000..3f13b8eb6a --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitRoof/RevitRoof.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit.RevitRoof; + +public class RevitRoof : Roof +{ + public string family { get; set; } + public string type { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } +} + +public class RevitExtrusionRoof : RevitRoof +{ + public RevitExtrusionRoof() { } + + /// + /// SchemaBuilder constructor for a Revit extrusion roof + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to and params + [SchemaInfo("RevitExtrusionRoof", "Creates a Revit roof by extruding a curve", "Revit", "Architecture")] + public RevitExtrusionRoof( + string family, + string type, + [SchemaParamInfo("Extrusion start")] double start, + [SchemaParamInfo("Extrusion end")] double end, + [SchemaParamInfo("Profile along which to extrude the roof"), SchemaMainParam] Line referenceLine, + Level level, + List? elements = null, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.parameters = parameters?.ToBase(); + this.level = level; + this.start = start; + this.end = end; + this.referenceLine = referenceLine; + this.elements = elements; + } + + public double start { get; set; } + public double end { get; set; } + public Line referenceLine { get; set; } +} + +public class RevitFootprintRoof : RevitRoof +{ + public RevitFootprintRoof() { } + + [SchemaInfo("RevitFootprintRoof", "Creates a Revit roof by outline", "Revit", "Architecture")] + public RevitFootprintRoof( + [SchemaMainParam] ICurve outline, + string family, + string type, + Level level, + RevitLevel? cutOffLevel = null, + double slope = 0, + List? voids = null, + List? elements = null, + List? parameters = null + ) + { + this.outline = outline; + this.voids = voids ?? new(); + this.family = family; + this.type = type; + this.slope = slope; + this.parameters = parameters?.ToBase(); + this.level = level; + this.cutOffLevel = cutOffLevel; + this.elements = elements; + } + + public RevitLevel? cutOffLevel { get; set; } + public double? slope { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitTopography.cs b/Objects/Objects/BuiltElements/Revit/RevitTopography.cs new file mode 100644 index 0000000000..f7205a9414 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitTopography.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitTopography : Topography +{ + public RevitTopography() { } + + [SchemaInfo("RevitTopography", "Creates a Revit topography", "Revit", "Architecture")] + public RevitTopography([SchemaMainParam] Mesh displayMesh, List? parameters = null) + { + displayValue = new List { displayMesh }; + this.parameters = parameters?.ToBase(); + } + + public string elementId { get; set; } + public Base? parameters { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitToposolid.cs b/Objects/Objects/BuiltElements/Revit/RevitToposolid.cs index f5ad34dab7..096b201b96 100644 --- a/Objects/Objects/BuiltElements/Revit/RevitToposolid.cs +++ b/Objects/Objects/BuiltElements/Revit/RevitToposolid.cs @@ -14,16 +14,16 @@ public RevitToposolid() { } public RevitToposolid( Level level, List profiles, - List topPlanePoints = null, - [SchemaParamInfo("Any nested elements that this floor might have")] List elements = null, - List parameters = null + List? topPlanePoints = null, + [SchemaParamInfo("Any nested elements that this floor might have")] List? elements = null, + List? parameters = null ) { this.profiles = profiles; this.level = level; - this.points = topPlanePoints; + this.points = topPlanePoints ?? new(); this.elements = elements; - this.parameters = parameters.ToBase(); + this.parameters = parameters?.ToBase(); } public List profiles { get; set; } = new(); @@ -31,7 +31,7 @@ public RevitToposolid( public List points { get; set; } = new(); [DetachProperty] - public List elements { get; set; } + public List? elements { get; set; } [DetachProperty] public List displayValue { get; set; } @@ -39,5 +39,5 @@ public RevitToposolid( public string family { get; set; } public string type { get; set; } public Level level { get; set; } - public Base parameters { get; set; } + public Base? parameters { get; set; } } diff --git a/Objects/Objects/BuiltElements/Revit/RevitWall.cs b/Objects/Objects/BuiltElements/Revit/RevitWall.cs new file mode 100644 index 0000000000..ac9d4bfe29 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitWall.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using Objects.Geometry; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitWall : Wall +{ + public RevitWall() { } + + /// + /// SchemaBuilder constructor for a Revit wall + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to and params + [SchemaInfo( + "RevitWall by curve and levels", + "Creates a Revit wall with a top and base level.", + "Revit", + "Architecture" + )] + public RevitWall( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + Level topLevel, + double baseOffset = 0, + double topOffset = 0, + bool flipped = false, + bool structural = false, + [SchemaParamInfo("Set in here any nested elements that this level might have.")] List? elements = null, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.baseOffset = baseOffset; + this.topOffset = topOffset; + this.flipped = flipped; + this.structural = structural; + this.level = level; + this.topLevel = topLevel; + this.elements = elements; + this.parameters = parameters?.ToBase(); + } + + /// + /// SchemaBuilder constructor for a Revit wall + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Assign units when using this constructor due to , , and params + [SchemaInfo("RevitWall by curve and height", "Creates an unconnected Revit wall.", "Revit", "Architecture")] + public RevitWall( + string family, + string type, + [SchemaMainParam] ICurve baseLine, + Level level, + double height, + double baseOffset = 0, + double topOffset = 0, + bool flipped = false, + bool structural = false, + [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List? elements = null, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.baseLine = baseLine; + this.height = height; + this.baseOffset = baseOffset; + this.topOffset = topOffset; + this.flipped = flipped; + this.structural = structural; + this.level = level; + this.elements = elements; + this.parameters = parameters?.ToBase(); + } + + public string family { get; set; } + public string type { get; set; } + public double baseOffset { get; set; } + public double topOffset { get; set; } + public bool flipped { get; set; } + public bool structural { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } + + public Level topLevel { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } +} + +public class RevitFaceWall : Wall +{ + public RevitFaceWall() { } + + [SchemaInfo("RevitWall by face", "Creates a Revit wall from a surface.", "Revit", "Architecture")] + public RevitFaceWall( + string family, + string type, + [SchemaParamInfo("Surface or single face Brep to use"), SchemaMainParam] Brep surface, + Level level, + LocationLine locationLine = LocationLine.Interior, + [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List? elements = null, + List? parameters = null + ) + { + if (surface.Surfaces.Count == 0) + { + throw new Exception("Cannot create a RevitWall with an empty BREP"); + } + + if (surface.Surfaces.Count > 1) + { + throw new Exception( + "The provided brep has more than 1 surface. Please deconstruct/explode it to create multiple instances" + ); + } + + this.family = family; + this.type = type; + brep = surface; + this.locationLine = locationLine; + this.level = level; + this.elements = elements; + this.parameters = parameters?.ToBase(); + } + + public string family { get; set; } + public string type { get; set; } + + public Brep brep { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } + + public LocationLine locationLine { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } +} + +public class RevitProfileWall : Wall +{ + public RevitProfileWall() { } + + [SchemaInfo("RevitWall by profile", "Creates a Revit wall from a profile.", "Revit", "Architecture")] + public RevitProfileWall( + string family, + string type, + [SchemaParamInfo("Profile to use"), SchemaMainParam] Polycurve profile, + Level level, + LocationLine locationLine = LocationLine.Interior, + bool structural = false, + [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List? elements = null, + List? parameters = null + ) + { + this.family = family; + this.type = type; + this.profile = profile; + this.locationLine = locationLine; + this.structural = structural; + this.level = level; + this.elements = elements; + this.parameters = parameters?.ToBase(); + } + + public string family { get; set; } + public string type { get; set; } + public Polycurve profile { get; set; } + + public new Level? level + { + get => base.level; + set => base.level = value; + } + + public LocationLine locationLine { get; set; } + public bool structural { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } +} + +// [SchemaDescription("Not supported yet.")] +// [SchemaIgnore] +// public class RevitCurtainWall : Wall +// { +// // TODO +// // What props do/can curtain walls have? - grid, mullions, etc. +// +// [SchemaOptional] +// public bool flipped { get; set; } +// +// [SchemaOptional] +// public Base parameters { get; set; } +// +// [SchemaIgnore] +// public string elementId { get; set; } +// } +// +// [SchemaDescription("Not supported yet.")] +// [SchemaIgnore] +// public class RevitWallByPoint : Base +// { +// [SchemaOptional] +// public Base parameters { get; set; } +// +// [SchemaIgnore] +// public string elementId { get; set; } +// } diff --git a/Objects/Objects/BuiltElements/Revit/RevitWire.cs b/Objects/Objects/BuiltElements/Revit/RevitWire.cs new file mode 100644 index 0000000000..02e532f45e --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitWire.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit.Interfaces; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitWire : Wire, IHasMEPConnectors +{ + public RevitWire() { } + + [SchemaInfo("RevitWire", "Creates a Revit wire from points and level", "Revit", "MEP")] + public RevitWire( + List constructionPoints, + string family, + string type, + Level level, + string wiringType = "Arc", + List? parameters = null + ) + { + this.constructionPoints = constructionPoints; + this.family = family; + this.type = type; + this.level = level; + this.wiringType = wiringType; + this.parameters = parameters?.ToBase(); + } + + public string family { get; set; } + public string type { get; set; } + public string wiringType { get; set; } + public List constructionPoints { get; set; } // used in constructor for revit native wires + public string system { get; set; } + public Level level { get; set; } + public Base? parameters { get; set; } + public string elementId { get; set; } + public List Connectors { get; set; } = new(); +} diff --git a/Objects/Objects/BuiltElements/Revit/RevitZone.cs b/Objects/Objects/BuiltElements/Revit/RevitZone.cs new file mode 100644 index 0000000000..3dac0466f9 --- /dev/null +++ b/Objects/Objects/BuiltElements/Revit/RevitZone.cs @@ -0,0 +1,15 @@ +using Speckle.Core.Models; + +namespace Objects.BuiltElements.Revit; + +public class RevitZone : Zone +{ + public RevitZone() { } + + public Level level { get; set; } + public string phaseName { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } + public bool isDefault { get; set; } + public string serviceType { get; set; } +} diff --git a/Objects/Objects/BuiltElements/Roof.cs b/Objects/Objects/BuiltElements/Roof.cs index 503f968544..fd076aeb8a 100644 --- a/Objects/Objects/BuiltElements/Roof.cs +++ b/Objects/Objects/BuiltElements/Roof.cs @@ -1,397 +1,31 @@ -using System; using System.Collections.Generic; using Objects.Geometry; -using Objects.Other; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Roof : Base, IDisplayValue> - { - public Roof() { } - - [SchemaDeprecated, SchemaInfo("Roof", "Creates a Speckle roof", "BIM", "Architecture")] - public Roof([SchemaMainParam] ICurve outline, List voids = null, List elements = null) - { - this.outline = outline; - this.voids = voids; - this.elements = elements; - } - - public ICurve outline { get; set; } - public virtual Level? level { get; internal set; } - public List voids { get; set; } = new(); - - [DetachProperty] - public List elements { get; set; } - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - } -} +namespace Objects.BuiltElements; -namespace Objects.BuiltElements.Revit.RevitRoof +public class Roof : Base, IDisplayValue> { - public class RevitRoof : Roof - { - public string family { get; set; } - public string type { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } + public Roof() { } - public new Level? level - { - get => base.level; - set => base.level = value; - } - } - - public class RevitExtrusionRoof : RevitRoof + [SchemaDeprecated, SchemaInfo("Roof", "Creates a Speckle roof", "BIM", "Architecture")] + public Roof([SchemaMainParam] ICurve outline, List? voids = null, List? elements = null) { - public RevitExtrusionRoof() { } - - /// - /// SchemaBuilder constructor for a Revit extrusion roof - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to and params - [SchemaInfo("RevitExtrusionRoof", "Creates a Revit roof by extruding a curve", "Revit", "Architecture")] - public RevitExtrusionRoof( - string family, - string type, - [SchemaParamInfo("Extrusion start")] double start, - [SchemaParamInfo("Extrusion end")] double end, - [SchemaParamInfo("Profile along which to extrude the roof"), SchemaMainParam] Line referenceLine, - Level level, - List elements = null, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.parameters = parameters.ToBase(); - this.level = level; - this.start = start; - this.end = end; - this.referenceLine = referenceLine; - this.elements = elements; - } - - public double start { get; set; } - public double end { get; set; } - public Line referenceLine { get; set; } + this.outline = outline; + this.voids = voids ?? new(); + this.elements = elements; } - public class RevitFootprintRoof : RevitRoof - { - public RevitFootprintRoof() { } - - [SchemaInfo("RevitFootprintRoof", "Creates a Revit roof by outline", "Revit", "Architecture")] - public RevitFootprintRoof( - [SchemaMainParam] ICurve outline, - string family, - string type, - Level level, - RevitLevel cutOffLevel = null, - double slope = 0, - List voids = null, - List elements = null, - List parameters = null - ) - { - this.outline = outline; - this.voids = voids; - this.family = family; - this.type = type; - this.slope = slope; - this.parameters = parameters.ToBase(); - this.level = level; - this.cutOffLevel = cutOffLevel; - this.elements = elements; - } - - public RevitLevel cutOffLevel { get; set; } - public double? slope { get; set; } - } -} - -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_shellbasetype - */ - public class ArchicadShellBase : BuiltElements.Roof - { - public class Visibility : Base - { - public bool? showOnHome { get; set; } - public bool? showAllAbove { get; set; } - public bool? showAllBelow { get; set; } - public short? showRelAbove { get; set; } - public short? showRelBelow { get; set; } - } - - // Element base - public string? elementType { get; set; } /*APINullabe*/ - public List? classifications { get; set; } /*APINullabe*/ - - public override Level? level - { - get => archicadLevel; - internal set - { - if (value is ArchicadLevel or null) - { - archicadLevel = value as ArchicadLevel; - } - else - { - throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); - } - } - } - - [JsonIgnore] - public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ - - public string? layer { get; set; } /*APINullabe*/ - - // Geometry and positioning - public double? thickness { get; set; } - public string? structure { get; set; } /*APINullabe*/ - public string? compositeName { get; set; } - public string? buildingMaterialName { get; set; } + public ICurve outline { get; set; } + public virtual Level? level { get; internal set; } + public List voids { get; set; } = new(); - // EdgeTrims - public string? edgeAngleType { get; set; } - public double? edgeAngle { get; set; } + [DetachProperty] + public List? elements { get; set; } - // Floor Plan and Section - Floor Plan Display - public string? showOnStories { get; set; } /*APINullabe*/ - public Visibility? visibilityCont { get; set; } - public Visibility? visibilityFill { get; set; } - public string? displayOptionName { get; set; } /*APINullabe*/ - public string? showProjectionName { get; set; } /*APINullabe*/ + public string units { get; set; } - // Floor Plan and Section - Cut Surfaces - public short? sectContPen { get; set; } /*APINullabe*/ - public string? sectContLtype { get; set; } /*APINullabe*/ - public short? cutFillPen { get; set; } - public short? cutFillBackgroundPen { get; set; } - - // Floor Plan and Section - Outlines - public short? contourPen { get; set; } /*APINullabe*/ - public string? contourLineType { get; set; } /*APINullabe*/ - public short? overheadLinePen { get; set; } /*APINullabe*/ - public string? overheadLinetype { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cover Fills - public bool? useFloorFill { get; set; } /*APINullabe*/ - public short? floorFillPen { get; set; } - public short? floorFillBGPen { get; set; } - public string? floorFillName { get; set; } - public bool? use3DHatching { get; set; } - public bool? useFillLocBaseLine { get; set; } - public bool? useSlantedFill { get; set; } - public string? hatchOrientation { get; set; } - public double? hatchOrientationOrigoX { get; set; } - public double? hatchOrientationOrigoY { get; set; } - public double? hatchOrientationXAxisX { get; set; } - public double? hatchOrientationXAxisY { get; set; } - public double? hatchOrientationYAxisX { get; set; } - public double? hatchOrientationYAxisY { get; set; } - - // Model - public string? topMat { get; set; } - public string? sideMat { get; set; } - public string? botMat { get; set; } - public bool? materialsChained { get; set; } - public string? trimmingBodyName { get; set; } /*APINullabe*/ - } - - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_rooftype - */ - public sealed class ArchicadRoof : ArchicadShellBase - { - public class BaseLine : Base - { - public Point begC { get; set; } - public Point endC { get; set; } - } - - public class RoofLevel : Base - { - public double? levelHeight { get; set; } - public double? levelAngle { get; set; } - } - - public class LevelEdge : Base - { - public double? edgeLevelAngle { get; set; } - public double? eavesOverhang { get; set; } - public string? topMaterial { get; set; } - public string? bottomMaterial { get; set; } - public string? coverFillType { get; set; } - public string? angleType { get; set; } - } - - public class PivotPolyEdge : Base - { - public Int32? nLevelEdgeData { get; set; } - public Dictionary? roofLevels { get; set; } - } - - // Geometry and positioning - public string roofClassName { get; set; } - public double? planeRoofAngle { get; set; } - public ElementShape shape { get; set; } - public BaseLine? baseLine { get; set; } - public bool? posSign { get; set; } - public ElementShape? pivotPolygon { get; set; } /*APINullabe*/ - public short? levelNum { get; set; } - public Dictionary? levels { get; set; } /*APINullabe*/ - public Dictionary? roofPivotPolyEdges { get; set; } - } - - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_shelltype - */ - public sealed class ArchicadShell : ArchicadShellBase - { - public class ShellContourEdgeData : Base - { - public string? sideTypeName { get; set; } - public double? sideAngle { get; set; } - public string? edgeTypeName { get; set; } - public string? edgeSideMaterial { get; set; } - } - - public class ShellContourData : Base - { - public ElementShape? shellContourPoly { get; set; } - public Transform shellContourPlane { get; set; } - public double? shellContourHeight { get; set; } - public int? shellContourID { get; set; } - public Dictionary? shellContourEdges { get; set; } - } - - // Geometry and positioning - public string? shellClassName { get; set; } /*APINullabe*/ - public Transform? basePlane { get; set; } /*APINullabe*/ - public bool? flipped { get; set; } /*APINullabe*/ - public bool? hasContour { get; set; } /*APINullabe*/ - public int? numHoles { get; set; } /*APINullabe*/ - public Dictionary? shellContours { get; set; } - public string? defaultEdgeType { get; set; } /*APINullabe*/ - - public double? slantAngle { get; set; } - public double? revolutionAngle { get; set; } - public double? distortionAngle { get; set; } - public bool? segmentedSurfaces { get; set; } - public double? shapePlaneTilt { get; set; } - public double? begPlaneTilt { get; set; } - public double? endPlaneTilt { get; set; } - public ElementShape shape { get; set; } - public ElementShape? shape1 { get; set; } /*APINullabe*/ - public ElementShape? shape2 { get; set; } /*APINullabe*/ - public Transform? axisBase { get; set; } /*APINullabe*/ - public Transform? plane1 { get; set; } /*APINullabe*/ - public Transform? plane2 { get; set; } /*APINullabe*/ - public Point? begC { get; set; } - public double? begAngle { get; set; } - public Vector? extrusionVector { get; set; } - public Vector? shapeDirection { get; set; } - public Vector? distortionVector { get; set; } - public string? morphingRuleName { get; set; } - - // Model - public class BegShapeEdge : Base - { - public string? begShapeEdgeTrimSideType { get; set; } - public double? begShapeEdgeTrimSideAngle { get; set; } - public string? begShapeEdgeSideMaterial { get; set; } - public string? begShapeEdgeType { get; set; } - } - - public class EndShapeEdge : Base - { - public string? endShapeEdgeTrimSideType { get; set; } - public double? endShapeEdgeTrimSideAngle { get; set; } - public string? endShapeEdgeSideMaterial { get; set; } - public string? endShapeEdgeType { get; set; } - } - - public class ExtrudedEdge1 : Base - { - public string? extrudedEdgeTrimSideType1 { get; set; } - public double? extrudedEdgeTrimSideAngle1 { get; set; } - public string? extrudedEdgeSideMaterial1 { get; set; } - public string? extrudedEdgeType1 { get; set; } - } - - public class ExtrudedEdge2 : Base - { - public string? extrudedEdgeTrimSideType2 { get; set; } - public double? extrudedEdgeTrimSideAngle2 { get; set; } - public string? extrudedEdgeSideMaterial2 { get; set; } - public string? extrudedEdgeType2 { get; set; } - } - - public class RevolvedEdge1 : Base - { - public string? revolvedEdgeTrimSideType1 { get; set; } - public double? revolvedEdgeTrimSideAngle1 { get; set; } - public string? revolvedEdgeSideMaterial1 { get; set; } - public string? revolvedEdgeType1 { get; set; } - } - - public class RevolvedEdge2 : Base - { - public string? revolvedEdgeTrimSideType2 { get; set; } - public double? revolvedEdgeTrimSideAngle2 { get; set; } - public string? revolvedEdgeSideMaterial2 { get; set; } - public string? revolvedEdgeType2 { get; set; } - } - - public class RuledEdge1 : Base - { - public string? ruledEdgeTrimSideType1 { get; set; } - public double? ruledEdgeTrimSideAngle1 { get; set; } - public string? ruledEdgeSideMaterial1 { get; set; } - public string? ruledEdgeType1 { get; set; } - } - - public class RuledEdge2 : Base - { - public string? ruledEdgeTrimSideType2 { get; set; } - public double? ruledEdgeTrimSideAngle2 { get; set; } - public string? ruledEdgeSideMaterial2 { get; set; } - public string? ruledEdgeType2 { get; set; } - } - - public BegShapeEdge? begShapeEdge { get; set; } - public EndShapeEdge? endShapeEdge { get; set; } - public ExtrudedEdge1? extrudedEdge1 { get; set; } - public ExtrudedEdge2? extrudedEdge2 { get; set; } - public RevolvedEdge1? revolvedEdge1 { get; set; } - public RevolvedEdge2? revolvedEdge2 { get; set; } - public RuledEdge1? ruledEdge1 { get; set; } - public RuledEdge2? ruledEdge2 { get; set; } - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Room.cs b/Objects/Objects/BuiltElements/Room.cs index 513953f351..e0975d33bd 100644 --- a/Objects/Objects/BuiltElements/Room.cs +++ b/Objects/Objects/BuiltElements/Room.cs @@ -1,92 +1,62 @@ -using System; using System.Collections.Generic; using Objects.BuiltElements.Revit; using Objects.Geometry; using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements +namespace Objects.BuiltElements; + +public class Room : Base, IHasArea, IHasVolume, IDisplayValue> { - public class Room : Base, IHasArea, IHasVolume, IDisplayValue> + public Room() { } + + /// + /// SchemaBuilder constructor for a Room + /// + /// Assign units when using this constructor due to prop + [SchemaInfo("Room", "Creates a Speckle room", "BIM", "Architecture")] + public Room(string name, string number, Level level, [SchemaMainParam] Point basePoint) { - public Room() { } - - /// - /// SchemaBuilder constructor for a Room - /// - /// Assign units when using this constructor due to param - [SchemaInfo("Room", "Creates a Speckle room", "BIM", "Architecture")] - public Room(string name, string number, Level level, [SchemaMainParam] Point basePoint) - { - this.name = name; - this.number = number; - this.level = level; - this.basePoint = basePoint; - } - - /// - /// SchemaBuilder constructor for a Room - /// - /// Assign units when using this constructor due to param - [SchemaInfo("RevitRoom", "Creates a Revit room with parameters", "Revit", "Architecture")] - public Room( - string name, - string number, - Level level, - [SchemaMainParam] Point basePoint, - List parameters = null - ) - { - this.name = name; - this.number = number; - this.level = level; - this.basePoint = basePoint; - this["parameters"] = parameters.ToBase(); - } - - public string name { get; set; } - public string number { get; set; } - virtual public Level level { get; set; } - public Point basePoint { get; set; } - public double height { get; set; } - public List voids { get; set; } = new(); - public ICurve outline { get; set; } - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - - public double area { get; set; } - public double volume { get; set; } + this.name = name; + this.number = number; + this.level = level; + this.basePoint = basePoint; } -} -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_zonetype - */ - public class ArchicadRoom : Room + /// + /// SchemaBuilder constructor for a Room + /// + /// Assign units when using this constructor due to prop + [SchemaInfo("RevitRoom", "Creates a Revit room with parameters", "Revit", "Architecture")] + public Room( + string name, + string number, + Level level, + [SchemaMainParam] Point basePoint, + List? parameters = null + ) { - // Element base - public string elementType { get; set; } - public List classifications { get; set; } + this.name = name; + this.number = number; + this.level = level; + this.basePoint = basePoint; + this["parameters"] = parameters?.ToBase(); + } - public override Level level - { - get => archicadLevel; - set => archicadLevel = value as ArchicadLevel ?? null; - } + public string name { get; set; } + public string number { get; set; } + public virtual Level? level { get; set; } + public Point basePoint { get; set; } + public double height { get; set; } + public List voids { get; set; } = new(); + public ICurve outline { get; set; } - [JsonIgnore] - public ArchicadLevel archicadLevel { get; set; } + public string units { get; set; } - public string? layer { get; set; } /*APINullabe*/ + [DetachProperty] + public List displayValue { get; set; } - public ElementShape shape { get; set; } - } + public double area { get; set; } + public double volume { get; set; } } diff --git a/Objects/Objects/BuiltElements/Space.cs b/Objects/Objects/BuiltElements/Space.cs index 594100d1cb..076d146bee 100644 --- a/Objects/Objects/BuiltElements/Space.cs +++ b/Objects/Objects/BuiltElements/Space.cs @@ -59,7 +59,7 @@ double baseOffset // add the zone object for better forward compatibility public RevitZone? zone { get; set; } - [Obsolete] + [Obsolete("Use zone property instead")] public string zoneName { get; internal set; } public string units { get; set; } diff --git a/Objects/Objects/BuiltElements/TeklaStructures/TeklaBeam.cs b/Objects/Objects/BuiltElements/TeklaStructures/TeklaBeam.cs new file mode 100644 index 0000000000..7d2805f245 --- /dev/null +++ b/Objects/Objects/BuiltElements/TeklaStructures/TeklaBeam.cs @@ -0,0 +1,59 @@ +using Objects.Geometry; +using Objects.Structural.Materials; +using Objects.Structural.Properties.Profiles; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.TeklaStructures; + +public class TeklaBeam : Beam, IHasVolume, IHasArea +{ + public TeklaBeam() { } + + [SchemaInfo("TeklaBeam", "Creates a Tekla Structures beam by curve.", "Tekla", "Structure")] + public TeklaBeam([SchemaMainParam] ICurve baseLine, SectionProfile profile, StructuralMaterial material) + { + this.baseLine = baseLine; + this.profile = profile; + this.material = material; + } + + public string name { get; set; } + + [DetachProperty] + public SectionProfile profile { get; set; } + + [DetachProperty] + public StructuralMaterial material { get; set; } + + [DetachProperty] + public string finish { get; set; } + + [DetachProperty] + public string classNumber { get; set; } + + public Vector alignmentVector { get; set; } // This can be set to get proper rotation if coming from an application that doesn't have positioning + + [DetachProperty] + public TeklaPosition position { get; set; } + + public Base userProperties { get; set; } + + [DetachProperty] + public Base rebars { get; set; } + + public TeklaBeamType TeklaBeamType { get; set; } + public double area { get; set; } + public double volume { get; set; } +} + +public class SpiralBeam : TeklaBeam +{ + public Point startPoint { get; set; } + public Point rotationAxisPt1 { get; set; } + public Point rotationAxisPt2 { get; set; } + public double totalRise { get; set; } + public double rotationAngle { get; set; } + public double twistAngleStart { get; set; } + public double twistAngleEnd { get; set; } +} diff --git a/Objects/Objects/BuiltElements/TeklaStructures/TeklaContourPlate.cs b/Objects/Objects/BuiltElements/TeklaStructures/TeklaContourPlate.cs index 673c1536c8..7fcdcd22dc 100644 --- a/Objects/Objects/BuiltElements/TeklaStructures/TeklaContourPlate.cs +++ b/Objects/Objects/BuiltElements/TeklaStructures/TeklaContourPlate.cs @@ -16,9 +16,9 @@ public TeklaContourPlate( string finish, string classNumber, string units, - StructuralMaterial material = null, - TeklaPosition position = null, - Base rebars = null + StructuralMaterial? material = null, + TeklaPosition? position = null, + Base? rebars = null ) { this.profile = profile; @@ -26,7 +26,7 @@ public TeklaContourPlate( this.material = material; this.finish = finish; this.classNumber = classNumber; - this.position = position; + this.position = position ?? new(); this.rebars = rebars; this.units = units; } @@ -37,7 +37,7 @@ public TeklaContourPlate() { } public SectionProfile profile { get; set; } [DetachProperty] - public StructuralMaterial material { get; set; } + public StructuralMaterial? material { get; set; } [DetachProperty] public string finish { get; set; } @@ -46,10 +46,10 @@ public TeklaContourPlate() { } public string classNumber { get; set; } [DetachProperty] - public TeklaPosition position { get; set; } + public TeklaPosition position { get; set; } = new(); [DetachProperty] - public Base rebars { get; set; } + public Base? rebars { get; set; } public List contour { get; set; } // Use for ToNative to Tekla. Other programs can use Area.outline. } diff --git a/Objects/Objects/BuiltElements/TeklaStructures/TeklaOpening.cs b/Objects/Objects/BuiltElements/TeklaStructures/TeklaOpening.cs new file mode 100644 index 0000000000..8ab6fae3f9 --- /dev/null +++ b/Objects/Objects/BuiltElements/TeklaStructures/TeklaOpening.cs @@ -0,0 +1,18 @@ +namespace Objects.BuiltElements.TeklaStructures; + +public class TeklaOpening : Opening +{ + public string openingHostId { get; set; } + public TeklaOpeningTypeEnum openingType { get; set; } +} + +public class TeklaContourOpening : TeklaOpening +{ + public TeklaContourPlate cuttingPlate { get; set; } + public double thickness { get; set; } +} + +public class TeklaBeamOpening : TeklaOpening +{ + public TeklaBeam cuttingBeam { get; set; } +} diff --git a/Objects/Objects/BuiltElements/TeklaStructures/TeklaRebar.cs b/Objects/Objects/BuiltElements/TeklaStructures/TeklaRebar.cs new file mode 100644 index 0000000000..9908f5e291 --- /dev/null +++ b/Objects/Objects/BuiltElements/TeklaStructures/TeklaRebar.cs @@ -0,0 +1,45 @@ +using System; +using Objects.Structural.Materials; +using Speckle.Core.Models; + +namespace Objects.BuiltElements.TeklaStructures; + +#region Obsolete +[Obsolete("Deprecated in 2.17: Create a TeklaRebarGroup class instead")] +public class TeklaRebar : Rebar +{ + public string name { get; set; } + + [DetachProperty] + public Hook startHook { get; set; } + + [DetachProperty] + public Hook endHook { get; set; } + + public double classNumber { get; set; } + public string size { get; set; } + + [DetachProperty] + public StructuralMaterial material { get; set; } +} + +[Obsolete("Deprecated in 2.17: Use a RebarHook class instead")] +public class Hook : Base +{ + public double angle { get; set; } + public double length { get; set; } + public double radius { get; set; } + public shape shape { get; set; } +} + +[Obsolete("Deprecated in 2.17: set starthook and endhook to null or refer to hook angle instead")] +[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Obsolete")] +public enum shape +{ + NO_HOOK = 0, + HOOK_90_DEGREES = 1, + HOOK_135_DEGREES = 2, + HOOK_180_DEGREES = 3, + CUSTOM_HOOK = 4 +} +#endregion diff --git a/Objects/Objects/BuiltElements/Topography.cs b/Objects/Objects/BuiltElements/Topography.cs index 02294d94ac..bf629c5074 100644 --- a/Objects/Objects/BuiltElements/Topography.cs +++ b/Objects/Objects/BuiltElements/Topography.cs @@ -1,48 +1,28 @@ using System.Collections.Generic; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements +namespace Objects.BuiltElements; + +public class Topography : Base, IDisplayValue> { - public class Topography : Base, IDisplayValue> + public Topography() { - public Topography() - { - displayValue = new List(); - } - - [SchemaInfo("Topography", "Creates a Speckle topography", "BIM", "Architecture")] - public Topography([SchemaMainParam] Mesh displayMesh) - { - displayValue = new List { displayMesh }; - } - - public Mesh baseGeometry { get; set; } = new(); - - public string units { get; set; } - - [DetachProperty] - public List displayValue { get; set; } - //TODO Figure out if we should add a new constructor that takes a List or if Topography should just have a single mesh display value + displayValue = new List(); } -} -namespace Objects.BuiltElements.Revit -{ - public class RevitTopography : Topography + [SchemaInfo("Topography", "Creates a Speckle topography", "BIM", "Architecture")] + public Topography([SchemaMainParam] Mesh displayMesh) { - public RevitTopography() { } + displayValue = new List { displayMesh }; + } - [SchemaInfo("RevitTopography", "Creates a Revit topography", "Revit", "Architecture")] - public RevitTopography([SchemaMainParam] Mesh displayMesh, List parameters = null) - { - displayValue = new List { displayMesh }; - this.parameters = parameters.ToBase(); - } + public Mesh baseGeometry { get; set; } = new(); - public string elementId { get; set; } - public Base parameters { get; set; } - } + public string units { get; set; } + + [DetachProperty] + public List displayValue { get; set; } + //TODO Figure out if we should add a new constructor that takes a List or if Topography should just have a single mesh display value } diff --git a/Objects/Objects/BuiltElements/View.cs b/Objects/Objects/BuiltElements/View.cs index d3c796860d..d518f101e9 100644 --- a/Objects/Objects/BuiltElements/View.cs +++ b/Objects/Objects/BuiltElements/View.cs @@ -15,7 +15,7 @@ public class View3D : View public Vector upDirection { get; set; } public Vector forwardDirection { get; set; } public Box boundingBox { get; set; } // x is right, y is top of screen, z is towards viewer - public bool isOrthogonal { get; set; } = false; + public bool isOrthogonal { get; set; } public string units { get; set; } } @@ -25,42 +25,3 @@ public class View2D : View //public Point topLeft { get; set; } //public Point bottomRight { get; set; } } - - -//namespace Objects.BuiltElements.Revit -//{ - -// public class RevitLevel : Level -// { -// public bool createView { get; set; } - -// public Base parameters { get; set; } - -// public string elementId { get; set; } - -// public bool referenceOnly { get; set; } - -// public RevitLevel() { } - -// [SchemaInfo("Create level", "Creates a new Revit level unless one with the same elevation already exists")] -// public RevitLevel( -// [SchemaParamInfo("Level name. NOTE: updating level name is not supported")] string name, -// [SchemaParamInfo("Level elevation. NOTE: updating level elevation is not supported, a new one will be created unless another level at the new elevation already exists.")] double elevation, -// [SchemaParamInfo("If true, it creates an associated view in Revit. NOTE: only used when creating a level for the first time")] bool createView, -// List parameters = null) -// { -// this.name = name; -// this.elevation = elevation; -// this.createView = createView; -// this.parameters = parameters.ToBase(); -// this.referenceOnly = false; -// } - -// [SchemaInfo("Level by name", "Gets an existing Revit level by name")] -// public RevitLevel(string name) -// { -// this.name = name; -// this.referenceOnly = true; -// } -// } -//} diff --git a/Objects/Objects/BuiltElements/Wall.cs b/Objects/Objects/BuiltElements/Wall.cs index 496270a81a..9f6cb754d7 100644 --- a/Objects/Objects/BuiltElements/Wall.cs +++ b/Objects/Objects/BuiltElements/Wall.cs @@ -1,409 +1,43 @@ -using System; using System.Collections.Generic; -using System.Linq; using Objects.Geometry; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; -namespace Objects.BuiltElements -{ - public class Wall : Base, IDisplayValue> - { - public Wall() { } - - /// - /// SchemaBuilder constructor for a Speckle wall - /// - /// - /// - /// - /// Assign units when using this constructor due to param - [SchemaInfo("Wall", "Creates a Speckle wall", "BIM", "Architecture")] - public Wall( - double height, - [SchemaMainParam] ICurve baseLine, - [SchemaParamInfo("Any nested elements that this wall might have")] List elements = null - ) - { - this.height = height; - this.baseLine = baseLine; - this.elements = elements; - } - - public double height { get; set; } - - [DetachProperty] - public List elements { get; set; } - - public ICurve baseLine { get; set; } - public virtual Level? level { get; internal set; } - - public string units { get; set; } +namespace Objects.BuiltElements; - [DetachProperty] - public List displayValue { get; set; } - } -} - -namespace Objects.BuiltElements.Revit +public class Wall : Base, IDisplayValue> { - public class RevitWall : Wall - { - public RevitWall() { } - - /// - /// SchemaBuilder constructor for a Revit wall - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to and params - [SchemaInfo( - "RevitWall by curve and levels", - "Creates a Revit wall with a top and base level.", - "Revit", - "Architecture" - )] - public RevitWall( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - Level topLevel, - double baseOffset = 0, - double topOffset = 0, - bool flipped = false, - bool structural = false, - [SchemaParamInfo("Set in here any nested elements that this level might have.")] List elements = null, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.baseOffset = baseOffset; - this.topOffset = topOffset; - this.flipped = flipped; - this.structural = structural; - this.level = level; - this.topLevel = topLevel; - this.elements = elements; - this.parameters = parameters.ToBase(); - } - - /// - /// SchemaBuilder constructor for a Revit wall - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Assign units when using this constructor due to , , and params - [SchemaInfo("RevitWall by curve and height", "Creates an unconnected Revit wall.", "Revit", "Architecture")] - public RevitWall( - string family, - string type, - [SchemaMainParam] ICurve baseLine, - Level level, - double height, - double baseOffset = 0, - double topOffset = 0, - bool flipped = false, - bool structural = false, - [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List elements = null, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.baseLine = baseLine; - this.height = height; - this.baseOffset = baseOffset; - this.topOffset = topOffset; - this.flipped = flipped; - this.structural = structural; - this.level = level; - this.elements = elements; - this.parameters = parameters.ToBase(); - } - - public string family { get; set; } - public string type { get; set; } - public double baseOffset { get; set; } - public double topOffset { get; set; } - public bool flipped { get; set; } - public bool structural { get; set; } - - public new Level? level - { - get => base.level; - set => base.level = value; - } - - public Level topLevel { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } - - public class RevitFaceWall : Wall - { - public RevitFaceWall() { } - - [SchemaInfo("RevitWall by face", "Creates a Revit wall from a surface.", "Revit", "Architecture")] - public RevitFaceWall( - string family, - string type, - [SchemaParamInfo("Surface or single face Brep to use"), SchemaMainParam] Brep surface, - Level level, - LocationLine locationLine = LocationLine.Interior, - [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List elements = null, - List parameters = null - ) - { - if (surface.Surfaces.Count == 0) - { - throw new Exception("Cannot create a RevitWall with an empty BREP"); - } - - if (surface.Surfaces.Count > 1) - { - throw new Exception( - "The provided brep has more than 1 surface. Please deconstruct/explode it to create multiple instances" - ); - } - - this.family = family; - this.type = type; - brep = surface; - this.locationLine = locationLine; - this.level = level; - this.elements = elements; - this.parameters = parameters.ToBase(); - } - - public string family { get; set; } - public string type { get; set; } - - public Brep brep { get; set; } - - [Obsolete("Use `Wall.brep` instead", false), SchemaIgnore] - public Surface surface - { - get => brep?.Surfaces.FirstOrDefault(); - //TODO: This is a simplistic representation of a BREP, may not work in all cases. - set => new Brep { Surfaces = new List { value } }; - } - - public new Level? level - { - get => base.level; - set => base.level = value; - } - - public LocationLine locationLine { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - } - - public class RevitProfileWall : Wall + public Wall() { } + + /// + /// SchemaBuilder constructor for a Speckle wall + /// + /// + /// + /// + /// Assign units when using this constructor due to param + [SchemaInfo("Wall", "Creates a Speckle wall", "BIM", "Architecture")] + public Wall( + double height, + [SchemaMainParam] ICurve baseLine, + [SchemaParamInfo("Any nested elements that this wall might have")] List? elements = null + ) { - public RevitProfileWall() { } - - [SchemaInfo("RevitWall by profile", "Creates a Revit wall from a profile.", "Revit", "Architecture")] - public RevitProfileWall( - string family, - string type, - [SchemaParamInfo("Profile to use"), SchemaMainParam] Polycurve profile, - Level level, - LocationLine locationLine = LocationLine.Interior, - bool structural = false, - [SchemaParamInfo("Set in here any nested elements that this wall might have.")] List elements = null, - List parameters = null - ) - { - this.family = family; - this.type = type; - this.profile = profile; - this.locationLine = locationLine; - this.structural = structural; - this.level = level; - this.elements = elements; - this.parameters = parameters.ToBase(); - } - - public string family { get; set; } - public string type { get; set; } - public Polycurve profile { get; set; } - - public new Level? level - { - get => base.level; - set => base.level = value; - } - - public LocationLine locationLine { get; set; } - public bool structural { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } + this.height = height; + this.baseLine = baseLine; + this.elements = elements; } - // [SchemaDescription("Not supported yet.")] - // [SchemaIgnore] - // public class RevitCurtainWall : Wall - // { - // // TODO - // // What props do/can curtain walls have? - grid, mullions, etc. - // - // [SchemaOptional] - // public bool flipped { get; set; } - // - // [SchemaOptional] - // public Base parameters { get; set; } - // - // [SchemaIgnore] - // public string elementId { get; set; } - // } - // - // [SchemaDescription("Not supported yet.")] - // [SchemaIgnore] - // public class RevitWallByPoint : Base - // { - // [SchemaOptional] - // public Base parameters { get; set; } - // - // [SchemaIgnore] - // public string elementId { get; set; } - // } -} - -namespace Objects.BuiltElements.Archicad -{ - /* - For further informations about given the variables, visit: - https://archicadapi.graphisoft.com/documentation/api_walltype - */ - public class ArchicadWall : Wall - { - [SchemaInfo("ArchicadWall", "Creates an Archicad wall.", "Archicad", "Structure")] - public ArchicadWall() { } - - // Element base - public string? elementType { get; set; } /*APINullabe*/ - public List? classifications { get; set; } /*APINullabe*/ - - public override Level? level - { - get => archicadLevel; - internal set - { - if (value is ArchicadLevel or null) - { - archicadLevel = value as ArchicadLevel; - } - else - { - throw new ArgumentException($"Expected object of type {nameof(ArchicadLevel)}"); - } - } - } - - [JsonIgnore] - public ArchicadLevel? archicadLevel { get; set; } /*APINullabe*/ - - public string? layer { get; set; } /*APINullabe*/ + public double height { get; set; } - // Wall geometry - public double? baseOffset { get; set; } /*APINullabe*/ - public Point startPoint { get; set; } - public Point endPoint { get; set; } + [DetachProperty] + public List? elements { get; set; } - public string? structure { get; set; } /*APINullabe*/ - public string? geometryMethod { get; set; } /*APINullabe*/ - public string? wallComplexity { get; set; } /*APINullabe*/ + public ICurve baseLine { get; set; } + public virtual Level? level { get; internal set; } - public string? buildingMaterialName { get; set; } - public string? compositeName { get; set; } - public string? profileName { get; set; } - public double? arcAngle { get; set; } + public string units { get; set; } - public ElementShape? shape { get; set; } - - public double? thickness { get; set; } /*APINullabe*/ - - public double? outsideSlantAngle { get; set; } - public double? insideSlantAngle { get; set; } - - public bool? polyWalllCornersCanChange { get; set; } - - // Wall and stories relation - public double? topOffset { get; set; } /*APINullabe*/ - public short? relativeTopStory { get; set; } /*APINullabe*/ - public string? referenceLineLocation { get; set; } /*APINullabe*/ - public double? referenceLineOffset { get; set; } - public double? offsetFromOutside { get; set; } /*APINullabe*/ - public int? referenceLineStartIndex { get; set; } /*APINullabe*/ - public int? referenceLineEndIndex { get; set; } /*APINullabe*/ - public bool flipped { get; set; } - - // Floor Plan and Section - Floor Plan Display - public string? showOnStories { get; set; } /*APINullabe*/ - public string? displayOptionName { get; set; } /*APINullabe*/ - public string? showProjectionName { get; set; } /*APINullabe*/ - - // Floor Plan and Section - Cut Surfaces parameters - public short? cutLinePen { get; set; } - public string? cutLinetype { get; set; } - public short? overrideCutFillPen { get; set; } - public short? overrideCutFillBackgroundPen { get; set; } - - // Floor Plan and Section - Outlines parameters - public short? uncutLinePen { get; set; } /*APINullabe*/ - public string? uncutLinetype { get; set; } /*APINullabe*/ - public short? overheadLinePen { get; set; } /*APINullabe*/ - public string? overheadLinetype { get; set; } /*APINullabe*/ - - // Model - Override Surfaces - public string? referenceMaterialName { get; set; } - public int? referenceMaterialStartIndex { get; set; } - public int? referenceMaterialEndIndex { get; set; } - public string? oppositeMaterialName { get; set; } - public int? oppositeMaterialStartIndex { get; set; } - public int? oppositeMaterialEndIndex { get; set; } - public string? sideMaterialName { get; set; } - public bool? materialsChained { get; set; } /*APINullabe*/ - public bool? inheritEndSurface { get; set; } /*APINullabe*/ - public bool? alignTexture { get; set; } /*APINullabe*/ - public int? sequence { get; set; } /*APINullabe*/ - - // Model - Log Details (log height, start with half log, surface of horizontal edges, log shape) - public double? logHeight { get; set; } - public bool? startWithHalfLog { get; set; } - public string? surfaceOfHorizontalEdges { get; set; } - public string? logShape { get; set; } - - // Model - Defines the relation of wall to zones (Zone Boundary, Reduce Zone Area Only, No Effect on Zones) - public string? wallRelationToZoneName { get; set; } /*APINullabe*/ - - // Does it have any embedded object? - public bool? hasDoor { get; set; } /*APINullabe*/ - - public bool? hasWindow { get; set; } /*APINullabe*/ - } + [DetachProperty] + public List displayValue { get; set; } } diff --git a/Objects/Objects/BuiltElements/Wire.cs b/Objects/Objects/BuiltElements/Wire.cs index 50f22ed619..cc4aa32400 100644 --- a/Objects/Objects/BuiltElements/Wire.cs +++ b/Objects/Objects/BuiltElements/Wire.cs @@ -1,59 +1,20 @@ using System.Collections.Generic; -using Objects.BuiltElements.Revit.Interfaces; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Wire : Base - { - public Wire() { } - - [SchemaInfo("Wire", "Creates a Speckle wire from curve segments and points", "BIM", "MEP")] - public Wire(List segments) - { - this.segments = segments; - } - - public List segments { get; set; } - - public string units { get; set; } - } -} +namespace Objects.BuiltElements; -namespace Objects.BuiltElements.Revit +public class Wire : Base { - public class RevitWire : Wire, IHasMEPConnectors + public Wire() { } + + [SchemaInfo("Wire", "Creates a Speckle wire from curve segments and points", "BIM", "MEP")] + public Wire(List segments) { - public RevitWire() { } + this.segments = segments; + } - [SchemaInfo("RevitWire", "Creates a Revit wire from points and level", "Revit", "MEP")] - public RevitWire( - List constructionPoints, - string family, - string type, - Level level, - string wiringType = "Arc", - List parameters = null - ) - { - this.constructionPoints = constructionPoints; - this.family = family; - this.type = type; - this.level = level; - this.wiringType = wiringType; - this.parameters = parameters.ToBase(); - } + public List segments { get; set; } - public string family { get; set; } - public string type { get; set; } - public string wiringType { get; set; } - public List constructionPoints { get; set; } // used in constructor for revit native wires - public string system { get; set; } - public Level level { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public List Connectors { get; set; } = new(); - } + public string units { get; set; } } diff --git a/Objects/Objects/BuiltElements/Zone.cs b/Objects/Objects/BuiltElements/Zone.cs index 7bbaa1dffc..30d5364336 100644 --- a/Objects/Objects/BuiltElements/Zone.cs +++ b/Objects/Objects/BuiltElements/Zone.cs @@ -1,42 +1,24 @@ using System.Collections.Generic; -using Objects.Geometry; -using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.BuiltElements -{ - public class Zone : Base, IHasArea, IHasVolume - { - public Zone() { } - - public Zone(string name) - { - this.name = name; - } +namespace Objects.BuiltElements; - public string name { get; set; } - public string units { get; set; } - - public List spaces { get; set; } +public class Zone : Base, IHasArea, IHasVolume +{ + public Zone() { } - // implicit measurements - public double area { get; set; } - public double volume { get; set; } - public double perimeter { get; set; } + public Zone(string name) + { + this.name = name; } -} -namespace Objects.BuiltElements.Revit -{ - public class RevitZone : Zone - { - public RevitZone() { } + public string name { get; set; } + public string units { get; set; } - public Level level { get; set; } - public string phaseName { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - public bool isDefault { get; set; } - public string serviceType { get; set; } - } + public List spaces { get; set; } + + // implicit measurements + public double area { get; set; } + public double volume { get; set; } + public double perimeter { get; set; } } diff --git a/Objects/Objects/Utils/EncodingOptimisations.cs b/Objects/Objects/EncodingOptimisations.cs similarity index 100% rename from Objects/Objects/Utils/EncodingOptimisations.cs rename to Objects/Objects/EncodingOptimisations.cs diff --git a/Objects/Objects/GIS/GisTopography.cs b/Objects/Objects/GIS/GisTopography.cs index 502dd0c013..37ac571883 100644 --- a/Objects/Objects/GIS/GisTopography.cs +++ b/Objects/Objects/GIS/GisTopography.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; using Objects.BuiltElements; -using Objects.BuiltElements.Revit; -using Objects.Geometry; -using Speckle.Core.Models; namespace Objects.GIS; @@ -16,5 +13,5 @@ public class GisTopography : Topography public int y_size { get; set; } public float x_resolution { get; set; } public float y_resolution { get; set; } - public List noDataValue { get; set; } + public List noDataValue { get; set; } } diff --git a/Objects/Objects/GIS/PolygonElement.cs b/Objects/Objects/GIS/PolygonElement.cs index a1c35db2b8..54b63601b3 100644 --- a/Objects/Objects/GIS/PolygonElement.cs +++ b/Objects/Objects/GIS/PolygonElement.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using Objects.BuiltElements.Revit; using Speckle.Core.Models; namespace Objects.GIS; diff --git a/Objects/Objects/Geometry/Arc.cs b/Objects/Objects/Geometry/Arc.cs index 630fd37012..9ca35b9010 100644 --- a/Objects/Objects/Geometry/Arc.cs +++ b/Objects/Objects/Geometry/Arc.cs @@ -33,7 +33,7 @@ public Arc( double endAngle, double angleRadians, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { this.plane = plane; @@ -41,6 +41,7 @@ public Arc( this.startAngle = startAngle; this.endAngle = endAngle; this.angleRadians = angleRadians; + domain = angleRadians > 0 ? new Interval(0, angleRadians) : new Interval(angleRadians, 0); this.applicationId = applicationId; this.units = units; } @@ -60,7 +61,7 @@ public Arc( Point endPoint, double angleRadians, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) : this( new Plane(startPoint, new Vector(0, 0, 1), new Vector(1, 0, 0), new Vector(0, 1, 0), units), @@ -87,7 +88,7 @@ public Arc( Point endPoint, double angleRadians, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { // don't be annoying @@ -105,6 +106,7 @@ public Arc( this.startPoint = startPoint; this.endPoint = endPoint; this.angleRadians = angleRadians; + domain = angleRadians > 0 ? new Interval(0, angleRadians) : new Interval(angleRadians, 0); this.applicationId = applicationId; // find chord and chord angle which may differ from the arc angle @@ -202,7 +204,7 @@ public Arc( public string units { get; set; } /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 0); /// public double length { get; set; } @@ -220,9 +222,11 @@ public bool TransformTo(Transform transform, out Arc transformed) midPoint.TransformTo(transform, out Point transformedMidpoint); endPoint.TransformTo(transform, out Point transformedEndPoint); plane.TransformTo(transform, out Plane pln); - var arc = new Arc(pln, transformedStartPoint, transformedEndPoint, angleRadians, units); - arc.midPoint = transformedMidpoint; - arc.domain = domain; + var arc = new Arc(pln, transformedStartPoint, transformedEndPoint, angleRadians, units) + { + midPoint = transformedMidpoint, + domain = domain + }; transformed = arc; return true; } @@ -247,8 +251,8 @@ public List ToList() list.Add(startAngle ?? 0); list.Add(endAngle ?? 0); list.Add(angleRadians); - list.Add(domain.start ?? 0); - list.Add(domain.end ?? 0); + list.Add(domain?.start ?? 0); + list.Add(domain?.end ?? 0); list.AddRange(plane.ToList()); list.AddRange(startPoint.ToList()); @@ -269,15 +273,16 @@ public List ToList() /// A new with the values assigned from the list. public static Arc FromList(List list) { - var arc = new Arc(); - - arc.radius = list[2]; - arc.startAngle = list[3]; - arc.endAngle = list[4]; - arc.angleRadians = list[5]; - arc.domain = new Interval(list[6], list[7]); - arc.units = Units.GetUnitFromEncoding(list[list.Count - 1]); - arc.plane = Plane.FromList(list.GetRange(8, 13)); + var arc = new Arc + { + radius = list[2], + startAngle = list[3], + endAngle = list[4], + angleRadians = list[5], + domain = new Interval(list[6], list[7]), + units = Units.GetUnitFromEncoding(list[list.Count - 1]), + plane = Plane.FromList(list.GetRange(8, 13)) + }; arc.startPoint = Point.FromList(list.GetRange(21, 3), arc.units); arc.midPoint = Point.FromList(list.GetRange(24, 3), arc.units); arc.endPoint = Point.FromList(list.GetRange(27, 3), arc.units); diff --git a/Objects/Objects/Geometry/Box.cs b/Objects/Objects/Geometry/Box.cs index 7d32c4eb04..f4bdab9fef 100644 --- a/Objects/Objects/Geometry/Box.cs +++ b/Objects/Objects/Geometry/Box.cs @@ -27,7 +27,7 @@ public Box( Interval ySize, Interval zSize, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { this.basePlane = basePlane; diff --git a/Objects/Objects/Geometry/Brep.cs b/Objects/Objects/Geometry/Brep.cs index a19241d886..324cc59112 100644 --- a/Objects/Objects/Geometry/Brep.cs +++ b/Objects/Objects/Geometry/Brep.cs @@ -34,10 +34,10 @@ public Brep() Orientation = BrepOrientation.None; } - public Brep(string provenance, Mesh displayValue, string units = Units.Meters, string applicationId = null) + public Brep(string provenance, Mesh displayValue, string units = Units.Meters, string? applicationId = null) : this(provenance, new List { displayValue }, units, applicationId) { } - public Brep(string provenance, List displayValues, string units = Units.Meters, string applicationId = null) + public Brep(string provenance, List displayValues, string units = Units.Meters, string? applicationId = null) : this() { this.provenance = provenance; @@ -216,8 +216,8 @@ public List EdgesValue ints.Add(e.StartIndex); ints.Add(e.EndIndex); ints.Add(Convert.ToInt32(e.ProxyCurveIsReversed)); - ints.Add(e.Domain.start); - ints.Add(e.Domain.end); + ints.Add(e.Domain.start ?? 0); + ints.Add(e.Domain.end ?? 1); ints.AddRange(e.TrimIndices.Select(Convert.ToDouble).Cast()); return ints.Prepend(ints.Count); }) @@ -242,11 +242,8 @@ public List EdgesValue var proxyReversed = Convert.ToBoolean(loopValues[3]); var domainStart = loopValues[4]; var domainEnd = loopValues[5]; - Interval domain = null; - if (domainStart.HasValue && domainEnd.HasValue) - { - domain = new Interval(domainStart.Value, domainEnd.Value); - } + Interval domain = + domainStart.HasValue && domainEnd.HasValue ? new(domainStart.Value, domainEnd.Value) : new(0, 1); var trimIndices = loopValues.GetRange(6, loopValues.Count - 6).Select(d => Convert.ToInt32(d)).ToArray(); @@ -445,7 +442,7 @@ public List FacesValue public double volume { get; set; } /// - public bool TransformTo(Transform transform, out Brep brep) + public bool TransformTo(Transform transform, out Brep transformed) { // transform display values var displayValues = new List(displayValue.Count); @@ -487,7 +484,7 @@ public bool TransformTo(Transform transform, out Brep brep) transformedVertices.Add(transformedVertex); } - brep = new Brep + transformed = new Brep { provenance = provenance, units = units, @@ -507,21 +504,29 @@ public bool TransformTo(Transform transform, out Brep brep) foreach (var e in Edges) { - brep.Edges.Add( - new BrepEdge(brep, e.Curve3dIndex, e.TrimIndices, e.StartIndex, e.EndIndex, e.ProxyCurveIsReversed, e.Domain) + transformed.Edges.Add( + new BrepEdge( + transformed, + e.Curve3dIndex, + e.TrimIndices, + e.StartIndex, + e.EndIndex, + e.ProxyCurveIsReversed, + e.Domain + ) ); } foreach (var l in Loops) { - brep.Loops.Add(new BrepLoop(brep, l.FaceIndex, l.TrimIndices, l.Type)); + transformed.Loops.Add(new BrepLoop(transformed, l.FaceIndex, l.TrimIndices, l.Type)); } foreach (var t in Trims) { - brep.Trims.Add( + transformed.Trims.Add( new BrepTrim( - brep, + transformed, t.EdgeIndex, t.FaceIndex, t.LoopIndex, @@ -537,7 +542,9 @@ public bool TransformTo(Transform transform, out Brep brep) foreach (var f in Faces) { - brep.Faces.Add(new BrepFace(brep, f.SurfaceIndex, f.LoopIndices, f.OuterLoopIndex, f.OrientationReversed)); + transformed.Faces.Add( + new BrepFace(transformed, f.SurfaceIndex, f.LoopIndices, f.OuterLoopIndex, f.OrientationReversed) + ); } return success3D; diff --git a/Objects/Objects/Geometry/BrepEdge.cs b/Objects/Objects/Geometry/BrepEdge.cs index c8f3c8d06a..faffb3233c 100644 --- a/Objects/Objects/Geometry/BrepEdge.cs +++ b/Objects/Objects/Geometry/BrepEdge.cs @@ -20,7 +20,7 @@ public BrepEdge( int startIndex, int endIndex, bool proxyCurvedIsReversed, - Interval domain + Interval? domain ) { Brep = brep; @@ -29,7 +29,7 @@ Interval domain StartIndex = startIndex; EndIndex = endIndex; ProxyCurveIsReversed = proxyCurvedIsReversed; - Domain = domain; + Domain = domain ?? new(0, 1); } [JsonIgnore] @@ -42,7 +42,7 @@ Interval domain public bool ProxyCurveIsReversed { get; set; } - public Interval Domain { get; set; } + public Interval Domain { get; set; } = new(0, 1); [JsonIgnore] public Point StartVertex => Brep.Vertices[StartIndex]; diff --git a/Objects/Objects/Geometry/BrepTrim.cs b/Objects/Objects/Geometry/BrepTrim.cs index 8040f29fe3..cadc268f71 100644 --- a/Objects/Objects/Geometry/BrepTrim.cs +++ b/Objects/Objects/Geometry/BrepTrim.cs @@ -32,6 +32,8 @@ int endIndex IsoStatus = isoStatus; TrimType = trimType; IsReversed = reversed; + StartIndex = startIndex; + EndIndex = endIndex; } [JsonIgnore] @@ -47,7 +49,7 @@ int endIndex public BrepTrimType TrimType { get; set; } public bool IsReversed { get; set; } - public Interval Domain { get; set; } + public Interval Domain { get; set; } = new(0, 1); [JsonIgnore] public BrepFace Face => Brep.Faces[FaceIndex]; @@ -56,7 +58,7 @@ int endIndex public BrepLoop Loop => Brep.Loops[LoopIndex]; [JsonIgnore] - public BrepEdge Edge => EdgeIndex != -1 ? Brep.Edges[EdgeIndex] : null; + public BrepEdge? Edge => EdgeIndex != -1 ? Brep.Edges[EdgeIndex] : null; [JsonIgnore] public ICurve Curve2d => Brep.Curve2D[CurveIndex]; diff --git a/Objects/Objects/Geometry/Circle.cs b/Objects/Objects/Geometry/Circle.cs index efb07cacc8..56fd4b1609 100644 --- a/Objects/Objects/Geometry/Circle.cs +++ b/Objects/Objects/Geometry/Circle.cs @@ -22,7 +22,7 @@ public Circle() { } /// The radius of the circle /// The units the circle is modeled in /// The unique ID of this circle in a specific application - public Circle(Plane plane, double radius, string units = Units.Meters, string applicationId = null) + public Circle(Plane plane, double radius, string units = Units.Meters, string? applicationId = null) { this.plane = plane; this.radius = radius; @@ -46,7 +46,7 @@ public Circle(Plane plane, double radius, string units = Units.Meters, string ap public string units { get; set; } /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); /// public double length { get; set; } @@ -68,8 +68,8 @@ public List ToList() var list = new List(); list.Add(radius ?? 0); - list.Add(domain.start ?? 0); - list.Add(domain.end ?? 1); + list.Add(domain?.start ?? 0); + list.Add(domain?.end ?? 1); list.AddRange(plane.ToList()); list.Add(Units.GetEncodingFromUnit(units)); @@ -85,11 +85,13 @@ public List ToList() /// A new with the provided values. public static Circle FromList(List list) { - var circle = new Circle(); - circle.radius = list[2]; - circle.domain = new Interval(list[3], list[4]); - circle.plane = Plane.FromList(list.GetRange(5, 13)); - circle.units = Units.GetUnitFromEncoding(list[list.Count - 1]); + var circle = new Circle + { + radius = list[2], + domain = new Interval(list[3], list[4]), + plane = Plane.FromList(list.GetRange(5, 13)), + units = Units.GetUnitFromEncoding(list[list.Count - 1]) + }; return circle; } diff --git a/Objects/Objects/Geometry/ControlPoint.cs b/Objects/Objects/Geometry/ControlPoint.cs index 84d9314b96..82f02471c4 100755 --- a/Objects/Objects/Geometry/ControlPoint.cs +++ b/Objects/Objects/Geometry/ControlPoint.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Objects.Other; using Speckle.Newtonsoft.Json; @@ -8,13 +9,13 @@ public class ControlPoint : Point, ITransformable { public ControlPoint() { } - public ControlPoint(double x, double y, double z, string units, string applicationId = null) + public ControlPoint(double x, double y, double z, string units, string? applicationId = null) : base(x, y, z, units, applicationId) { weight = 1; } - public ControlPoint(double x, double y, double z, double w, string units, string applicationId = null) + public ControlPoint(double x, double y, double z, double w, string units, string? applicationId = null) : base(x, y, z, units, applicationId) { weight = w; @@ -22,12 +23,16 @@ public ControlPoint(double x, double y, double z, double w, string units, string /// /// OBSOLETE - This is just here for backwards compatibility. - /// You should not use this for anything. Access coordinates using X,Y,Z and weight fields. /// - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - private List value + [ + JsonProperty(NullValueHandling = NullValueHandling.Ignore), + Obsolete("Access coordinates using XYZ and weight fields", true) + ] + private new List value { +#pragma warning disable CS8603 // Possible null reference return. Reason: obsolete. get => null; +#pragma warning restore CS8603 // Possible null reference return. Reason: obsolete. set { x = value[0]; @@ -39,10 +44,17 @@ private List value public double weight { get; set; } - public bool TransformTo(Transform transform, out ControlPoint ctrlPt) + public bool TransformTo(Transform transform, out ControlPoint transformed) { TransformTo(transform, out Point transformedPoint); - ctrlPt = new ControlPoint(transformedPoint.x, transformedPoint.y, transformedPoint.z, weight, units, applicationId); + transformed = new ControlPoint( + transformedPoint.x, + transformedPoint.y, + transformedPoint.z, + weight, + units, + applicationId + ); return true; } @@ -56,7 +68,7 @@ public void Deconstruct(out double x, out double y, out double z, out double wei Deconstruct(out x, out y, out z, out weight, out _); } - public void Deconstruct(out double x, out double y, out double z, out double weight, out string units) + public void Deconstruct(out double x, out double y, out double z, out double weight, out string? units) { Deconstruct(out x, out y, out z, out units); weight = this.weight; diff --git a/Objects/Objects/Geometry/Curve.cs b/Objects/Objects/Geometry/Curve.cs index 50ef8a3207..daf8c62e66 100644 --- a/Objects/Objects/Geometry/Curve.cs +++ b/Objects/Objects/Geometry/Curve.cs @@ -22,7 +22,7 @@ public Curve() { } /// The polyline that will be this curve's /// The units this curve is be modelled in /// The unique ID of this curve in a specific application - public Curve(Polyline poly, string units = Units.Meters, string applicationId = null) + public Curve(Polyline poly, string units = Units.Meters, string? applicationId = null) { displayValue = poly; this.applicationId = applicationId; @@ -61,7 +61,7 @@ public Curve(Polyline poly, string units = Units.Meters, string applicationId = public string units { get; set; } /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new Interval(0, 1); /// public double length { get; set; } @@ -100,7 +100,7 @@ public bool TransformTo(Transform transform, out Curve transformed) closed = closed, units = units, applicationId = applicationId, - domain = domain != null ? new Interval { start = domain.start, end = domain.end } : null + domain = domain != null ? new Interval { start = domain.start, end = domain.end } : new Interval(0, 1) }; return result; @@ -135,7 +135,7 @@ public List GetPoints() } /// - /// Returns the vales of this as a list of numbers + /// Returns the values of this as a list of numbers /// /// A list of values representing the public List ToList() @@ -146,8 +146,8 @@ public List ToList() list.Add(curve.periodic ? 1 : 0); // 1 list.Add(curve.rational ? 1 : 0); // 2 list.Add(curve.closed ? 1 : 0); // 3 - list.Add((double)curve.domain.start); // 4 - list.Add((double)curve.domain.end); // 5 + list.Add(curve.domain?.start ?? 0); // 4 + list.Add(curve.domain?.end ?? 1); // 5 list.Add(curve.points.Count); // 6 list.Add(curve.weights.Count); // 7 @@ -180,12 +180,14 @@ public static Curve FromList(List list) throw new Exception($"Wrong curve type. Expected {CurveTypeEncoding.Curve}, got {list[1]}."); } - var curve = new Curve(); - curve.degree = (int)list[2]; - curve.periodic = list[3] == 1; - curve.rational = list[4] == 1; - curve.closed = list[5] == 1; - curve.domain = new Interval(list[6], list[7]); + var curve = new Curve + { + degree = (int)list[2], + periodic = list[3] == 1, + rational = list[4] == 1, + closed = list[5] == 1, + domain = new Interval(list[6], list[7]) + }; var pointsCount = (int)list[8]; var weightsCount = (int)list[9]; diff --git a/Objects/Objects/Geometry/Ellipse.cs b/Objects/Objects/Geometry/Ellipse.cs index d863d6d032..b248e145d4 100644 --- a/Objects/Objects/Geometry/Ellipse.cs +++ b/Objects/Objects/Geometry/Ellipse.cs @@ -21,7 +21,7 @@ public Ellipse() { } /// First radius of the ellipse. /// Second radius of the ellipse. /// Application ID, defaults to null. - public Ellipse(Plane plane, double radius1, double radius2, string units = Units.Meters, string applicationId = null) + public Ellipse(Plane plane, double radius1, double radius2, string units = Units.Meters, string? applicationId = null) : this(plane, radius1, radius2, new Interval(0, 1), null, units) { } /// @@ -38,9 +38,9 @@ public Ellipse( double radius1, double radius2, Interval domain, - Interval trimDomain, + Interval? trimDomain, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { this.plane = plane; @@ -70,7 +70,7 @@ public Ellipse( /// /// Gets or set the domain interval to trim this with. /// - public Interval trimDomain { get; set; } + public Interval? trimDomain { get; set; } /// public Box bbox { get; set; } @@ -80,12 +80,11 @@ public Ellipse( /// /// Gets or sets the domain interval for this . /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 0); /// public double length { get; set; } - /// //public Point center { get; set; } /// @@ -96,8 +95,8 @@ public List ToList() var list = new List(); list.Add(firstRadius ?? 0); list.Add(secondRadius ?? 0); - list.Add(domain.start ?? 0); - list.Add(domain.end ?? 0); + list.Add(domain?.start ?? 0); + list.Add(domain?.end ?? 0); list.AddRange(plane.ToList()); @@ -109,14 +108,14 @@ public List ToList() public static Ellipse FromList(List list) { - var ellipse = new Ellipse(); - - ellipse.firstRadius = list[2]; - ellipse.secondRadius = list[3]; - ellipse.domain = new Interval(list[4], list[5]); - - ellipse.plane = Plane.FromList(list.GetRange(6, 13)); - ellipse.units = Units.GetUnitFromEncoding(list[list.Count - 1]); + var ellipse = new Ellipse + { + firstRadius = list[2], + secondRadius = list[3], + domain = new Interval(list[4], list[5]), + plane = Plane.FromList(list.GetRange(6, 13)), + units = Units.GetUnitFromEncoding(list[list.Count - 1]) + }; return ellipse; } } diff --git a/Objects/Objects/Geometry/Extrusion.cs b/Objects/Objects/Geometry/Extrusion.cs index 3cea2e0d63..aaa382f1cc 100644 --- a/Objects/Objects/Geometry/Extrusion.cs +++ b/Objects/Objects/Geometry/Extrusion.cs @@ -1,16 +1,21 @@ +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Speckle.Core.Kits; using Speckle.Core.Models; namespace Objects.Geometry; +[Obsolete("Unused")] +[SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "Obsolete")] public class Extrusion : Base, IHasVolume, IHasArea, IHasBoundingBox { + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Obsolete")] public double? length; public Extrusion() { } - public Extrusion(Base profile, double length, bool capped, string units = Units.Meters, string applicationId = null) + public Extrusion(Base profile, double length, bool capped, string units = Units.Meters, string? applicationId = null) { this.profile = profile; this.length = length; diff --git a/Objects/Objects/Geometry/Line.cs b/Objects/Objects/Geometry/Line.cs index ab20f49ed7..310085e39d 100644 --- a/Objects/Objects/Geometry/Line.cs +++ b/Objects/Objects/Geometry/Line.cs @@ -14,15 +14,18 @@ public class Line : Base, ICurve, IHasBoundingBox, ITransformable { public Line() { } - public Line(double x, double y, double z = 0, string units = Units.Meters, string applicationId = null) + [Obsolete("Line should not use a constructor that only sets the start point. Deprecated in 2.18.", true)] + public Line(double x, double y, double z = 0, string units = Units.Meters, string? applicationId = null) { start = new Point(x, y, z); +#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. Reason: Obsolete. end = null; +#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. Reason: Obsolete. this.applicationId = applicationId; this.units = units; } - public Line(Point start, Point end, string units = Units.Meters, string applicationId = null) + public Line(Point start, Point end, string units = Units.Meters, string? applicationId = null) { this.start = start; this.end = end; @@ -31,7 +34,7 @@ public Line(Point start, Point end, string units = Units.Meters, string applicat this.units = units; } - public Line(IList coordinates, string units = Units.Meters, string applicationId = null) + public Line(IList coordinates, string units = Units.Meters, string? applicationId = null) { if (coordinates.Count < 6) { @@ -45,8 +48,8 @@ public Line(IList coordinates, string units = Units.Meters, string appli this.units = units; } - [Obsolete("Use IList constructor")] - public Line(IEnumerable coordinatesArray, string units = Units.Meters, string applicationId = null) + [Obsolete("Use IList constructor", true)] + public Line(IEnumerable coordinatesArray, string units = Units.Meters, string? applicationId = null) : this(coordinatesArray.ToList(), units, applicationId) { } /// @@ -57,7 +60,9 @@ public Line(IEnumerable coordinatesArray, string units = Units.Meters, s [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public List value { +#pragma warning disable CS8603 // Possible null reference return. Reason: Obsolete. get => null; +#pragma warning restore CS8603 // Possible null reference return. Reason: Obsolete. set { if (value == null) @@ -77,7 +82,7 @@ public List value public Point start { get; set; } public Point end { get; set; } - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); public double length { get; set; } public Box bbox { get; set; } @@ -92,7 +97,7 @@ public bool TransformTo(Transform transform, out Line transformed) end = transformedEnd, applicationId = applicationId, units = units, - domain = domain == null ? null : new Interval { start = domain.start, end = domain.end } + domain = domain is null ? new(0, 1) : new() { start = domain.start, end = domain.end } }; return true; } @@ -109,8 +114,8 @@ public List ToList() var list = new List(); list.AddRange(start.ToList()); list.AddRange(end.ToList()); - list.Add(domain.start ?? 0); - list.Add(domain.end ?? 1); + list.Add(domain?.start ?? 0); + list.Add(domain?.end ?? 1); list.Add(Units.GetEncodingFromUnit(units)); list.Insert(0, CurveTypeEncoding.Line); list.Insert(0, list.Count); @@ -122,8 +127,7 @@ public static Line FromList(List list) var units = Units.GetUnitFromEncoding(list[list.Count - 1]); var startPt = new Point(list[2], list[3], list[4], units); var endPt = new Point(list[5], list[6], list[7], units); - var line = new Line(startPt, endPt, units); - line.domain = new Interval(list[8], list[9]); + var line = new Line(startPt, endPt, units) { domain = new Interval(list[8], list[9]) }; return line; } } diff --git a/Objects/Objects/Geometry/Mesh.cs b/Objects/Objects/Geometry/Mesh.cs index 39ed58cf76..1c2409f4f0 100644 --- a/Objects/Objects/Geometry/Mesh.cs +++ b/Objects/Objects/Geometry/Mesh.cs @@ -25,10 +25,10 @@ public Mesh() { } public Mesh( List vertices, List faces, - List colors = null, - List texture_coords = null, + List? colors = null, + List? texture_coords = null, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { this.vertices = vertices; @@ -39,16 +39,23 @@ public Mesh( this.units = units; } - [Obsolete("Use lists constructor")] + [Obsolete("Use lists constructor", true)] public Mesh( double[] vertices, int[] faces, - int[] colors = null, - double[] texture_coords = null, + int[]? colors = null, + double[]? texture_coords = null, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) - : this(vertices.ToList(), faces.ToList(), colors?.ToList(), texture_coords?.ToList(), applicationId, units) { } + : this( + vertices.ToList(), + faces.ToList(), + colors?.ToList() ?? new(), + texture_coords?.ToList() ?? new(), + units, + applicationId + ) { } [DetachProperty, Chunkable(31250)] public List vertices { get; set; } = new(); @@ -67,7 +74,7 @@ public Mesh( /// The unit's this is in. /// This should be one of /// - public string units { get; set; } + public string units { get; set; } = Units.None; /// public double area { get; set; } @@ -94,7 +101,7 @@ public bool Transform(Transform transform) } /// - public bool TransformTo(Transform transform, out Mesh mesh) + public bool TransformTo(Transform transform, out Mesh transformed) { // transform vertices var transformedVertices = new List(); @@ -104,7 +111,7 @@ public bool TransformTo(Transform transform, out Mesh mesh) transformedVertices.Add(transformedVertex); } - mesh = new Mesh + transformed = new Mesh { vertices = transformedVertices.SelectMany(o => o.ToList()).ToList(), textureCoordinates = textureCoordinates, @@ -113,7 +120,7 @@ public bool TransformTo(Transform transform, out Mesh mesh) colors = colors, units = units }; - mesh["renderMaterial"] = this["renderMaterial"]; + transformed["renderMaterial"] = this["renderMaterial"]; return true; } @@ -166,10 +173,10 @@ public List GetPoints() } /// - /// Gets a texture coordinate as a by + /// Gets a texture coordinate as a by /// /// The index of the texture coordinate - /// Texture coordinate as a + /// Texture coordinate as a public (double, double) GetTextureCoordinate(int index) { index *= 2; diff --git a/Objects/Objects/Geometry/Plane.cs b/Objects/Objects/Geometry/Plane.cs index 0671a0bf5d..c636ab066d 100644 --- a/Objects/Objects/Geometry/Plane.cs +++ b/Objects/Objects/Geometry/Plane.cs @@ -30,7 +30,7 @@ public Plane( Vector xDir, Vector yDir, string units = Units.Meters, - string applicationId = null + string? applicationId = null ) { this.origin = origin; @@ -68,15 +68,18 @@ public Plane( public string units { get; set; } /// - public bool TransformTo(Transform transform, out Plane plane) + public bool TransformTo(Transform transform, out Plane transformed) { origin.TransformTo(transform, out Point transformedOrigin); - plane = new Plane + normal.TransformTo(transform, out Vector transformedNormal); + xdir.TransformTo(transform, out Vector transformedXdir); + ydir.TransformTo(transform, out Vector transformedYdir); + transformed = new Plane { origin = transformedOrigin, - normal = transform.ApplyToVector(normal), - xdir = transform.ApplyToVector(xdir), - ydir = transform.ApplyToVector(ydir), + normal = transformedNormal, + xdir = transformedXdir, + ydir = transformedYdir, applicationId = applicationId, units = units }; diff --git a/Objects/Objects/Geometry/Point.cs b/Objects/Objects/Geometry/Point.cs index cb294a817b..307741c8f2 100644 --- a/Objects/Objects/Geometry/Point.cs +++ b/Objects/Objects/Geometry/Point.cs @@ -13,7 +13,7 @@ namespace Objects.Geometry; /// /// TODO: The Point class does not override the Equality operator, which means that there may be cases where `Equals` is used instead of `==`, as the comparison will be done by reference, not value. /// -public class Point : Base, IHasBoundingBox, ITransformable +public class Point : Base, ITransformable { /// public Point() { } @@ -24,7 +24,7 @@ public Point() { } /// The x coordinate /// The y coordinate /// The z coordinate - /// The units the point's coordinates are in. + /// The units of the point's coordinates. Defaults to Meters. /// The object's unique application ID public Point(double x, double y, double z = 0d, string units = Units.Meters, string? applicationId = null) { @@ -73,26 +73,26 @@ public List value public double z { get; set; } /// - /// The unit's this is in. + /// The units this is in. /// This should be one of the units specified in /// - public string units { get; set; } + public string units { get; set; } = Units.None; - /// + [JsonIgnore, Obsolete("Bounding box no longer applicable to point as of 2.18", true)] public Box? bbox { get; set; } /// - public bool TransformTo(Transform transform, out Point point) + public bool TransformTo(Transform transform, out Point transformed) { var matrix = transform.matrix; - var unitFactor = units != null ? Units.GetConversionFactor(transform.units, units) : 1; // applied to translation vector + var unitFactor = Units.GetConversionFactor(transform.units, units); // applied to translation vector var divisor = matrix.M41 + matrix.M42 + matrix.M43 + unitFactor * matrix.M44; var x = (this.x * matrix.M11 + this.y * matrix.M12 + this.z * matrix.M13 + unitFactor * matrix.M14) / divisor; var y = (this.x * matrix.M21 + this.y * matrix.M22 + this.z * matrix.M23 + unitFactor * matrix.M24) / divisor; var z = (this.x * matrix.M31 + this.y * matrix.M32 + this.z * matrix.M33 + unitFactor * matrix.M34) / divisor; - point = new Point(x, y, z) { units = units, applicationId = applicationId }; + transformed = new Point(x, y, z) { units = units, applicationId = applicationId }; return true; } @@ -131,7 +131,7 @@ public static Point FromList(IList list, string units) /// The y coordinate /// The z coordinate /// The units the point's coordinates are in. - public void Deconstruct(out double x, out double y, out double z, out string units) + public void Deconstruct(out double x, out double y, out double z, out string? units) { Deconstruct(out x, out y, out z); units = this.units; @@ -150,30 +150,20 @@ public void Deconstruct(out double x, out double y, out double z) z = this.z; } - public static Point operator +(Point point1, Point point2) - { - return new Point(point1.x + point2.x, point1.y + point2.y, point1.z + point2.z, point1.units); - } + public static Point operator +(Point point1, Point point2) => + new(point1.x + point2.x, point1.y + point2.y, point1.z + point2.z, point1.units); - public static Point operator -(Point point1, Point point2) - { - return new Point(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z, point1.units); - } + public static Point operator -(Point point1, Point point2) => + new(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z, point1.units); - public static Point operator *(Point point1, Point point2) - { - return new Point(point1.x * point2.x, point1.y * point2.y, point1.z * point2.z, point1.units); - } + public static Point operator *(Point point1, Point point2) => + new(point1.x * point2.x, point1.y * point2.y, point1.z * point2.z, point1.units); - public static Point operator *(Point point, double val) - { - return new Point(point.x * val, point.y * val, point.z * val, point.units); - } + public static Point operator *(Point point, double val) => + new(point.x * val, point.y * val, point.z * val, point.units); - public static Point operator /(Point point, double val) - { - return new Point(point.x / val, point.y / val, point.z / val, point.units); - } + public static Point operator /(Point point, double val) => + new(point.x / val, point.y / val, point.z / val, point.units); public static bool operator ==(Point? point1, Point? point2) { @@ -181,8 +171,7 @@ public void Deconstruct(out double x, out double y, out double z) { return true; } - - if (point1 is null ^ point2 is null) + else if (point1 is null || point2 is null) { return false; } @@ -190,10 +179,7 @@ public void Deconstruct(out double x, out double y, out double z) return point1.units == point2.units && point1.x == point2.x && point1.y == point2.y && point1.z == point2.z; } - public static bool operator !=(Point? point1, Point? point2) - { - return !(point1 == point2); - } + public static bool operator !=(Point? point1, Point? point2) => !(point1 == point2); /// /// Computes a point equidistant from two points. diff --git a/Objects/Objects/Geometry/Pointcloud.cs b/Objects/Objects/Geometry/Pointcloud.cs index 57be11f182..9b894c0ffb 100644 --- a/Objects/Objects/Geometry/Pointcloud.cs +++ b/Objects/Objects/Geometry/Pointcloud.cs @@ -21,11 +21,11 @@ public Pointcloud() { } /// Optional list of colors /// Optional list of sizes [SchemaInfo(nameof(Pointcloud), "Create a point cloud object", "Objects", "Geometry")] - public Pointcloud(List points, List colors = null, List sizes = null) + public Pointcloud(List points, List? colors = null, List? sizes = null) { this.points = points; - this.colors = colors ?? new List(); - this.sizes = sizes ?? new List(); + this.colors = colors ?? new(); + this.sizes = sizes ?? new(); } /// @@ -56,7 +56,7 @@ public Pointcloud(List points, List colors = null, List siz public Box bbox { get; set; } /// - public bool TransformTo(Transform transform, out Pointcloud pointcloud) + public bool TransformTo(Transform transform, out Pointcloud transformed) { // transform points var transformedPoints = new List(); @@ -66,7 +66,7 @@ public bool TransformTo(Transform transform, out Pointcloud pointcloud) transformedPoints.Add(transformedPoint); } - pointcloud = new Pointcloud + transformed = new Pointcloud { units = units, points = transformedPoints.SelectMany(o => o.ToList()).ToList(), diff --git a/Objects/Objects/Geometry/Polycurve.cs b/Objects/Objects/Geometry/Polycurve.cs index 6082eceedd..21305c2935 100644 --- a/Objects/Objects/Geometry/Polycurve.cs +++ b/Objects/Objects/Geometry/Polycurve.cs @@ -22,7 +22,7 @@ public Polycurve() { } /// /// The units the Polycurve was modelled in. /// The unique ID of this polyline in a specific application - public Polycurve(string units = Units.Meters, string applicationId = null) + public Polycurve(string units = Units.Meters, string? applicationId = null) { this.applicationId = applicationId; this.units = units; @@ -48,7 +48,7 @@ public Polycurve(string units = Units.Meters, string applicationId = null) /// /// The internal domain of this curve. /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); /// public double length { get; set; } @@ -130,8 +130,8 @@ public List ToList() { var list = new List(); list.Add(closed ? 1 : 0); - list.Add(domain.start ?? 0); - list.Add(domain.end ?? 1); + list.Add(domain?.start ?? 0); + list.Add(domain?.end ?? 1); var crvs = CurveArrayEncodingExtensions.ToArray(segments); list.Add(crvs.Count); @@ -151,9 +151,7 @@ public List ToList() /// A new with the provided values. public static Polycurve FromList(List list) { - var polycurve = new Polycurve(); - polycurve.closed = list[2] == 1; - polycurve.domain = new Interval(list[3], list[4]); + var polycurve = new Polycurve { closed = list[2] == 1, domain = new Interval(list[3], list[4]) }; var temp = list.GetRange(6, (int)list[5]); polycurve.segments = CurveArrayEncodingExtensions.FromArray(temp); diff --git a/Objects/Objects/Geometry/Polyline.cs b/Objects/Objects/Geometry/Polyline.cs index 49b8bd3b83..6716fa142c 100644 --- a/Objects/Objects/Geometry/Polyline.cs +++ b/Objects/Objects/Geometry/Polyline.cs @@ -26,8 +26,8 @@ public Polyline() { } /// The array of 3-dimensional coordinates [x1,y1,z1,x2,y2,... /// The units the coordinates are in. /// The unique ID of this polyline in a specific application - [Obsolete("Use list constructor instead")] - public Polyline(IEnumerable coordinatesArray, string units = Units.Meters, string applicationId = null) + [Obsolete("Use list constructor instead", true)] + public Polyline(IEnumerable coordinatesArray, string units = Units.Meters, string? applicationId = null) : this(coordinatesArray.ToList(), units, applicationId) { } /// @@ -36,7 +36,7 @@ public Polyline(IEnumerable coordinatesArray, string units = Units.Meter /// The list of 3-dimensional coordinates [x1,y1,z1,x2,y2,... /// The units the coordinates are in. /// The unique ID of this polyline in a specific application - public Polyline(List coordinates, string units = Units.Meters, string applicationId = null) + public Polyline(List coordinates, string units = Units.Meters, string? applicationId = null) { value = coordinates; this.units = units; @@ -63,7 +63,7 @@ public Polyline(List coordinates, string units = Units.Meters, string ap /// /// Gets the list of points representing the vertices of this polyline. /// - [JsonIgnore, Obsolete("Use " + nameof(GetPoints) + " Instead")] + [JsonIgnore, Obsolete("Use " + nameof(GetPoints) + " Instead", true)] public List points => GetPoints(); /// @@ -176,7 +176,7 @@ public ulong ToUInt64(IFormatProvider provider) /// /// The internal domain of this curve. /// - public Interval domain { get; set; } + public Interval domain { get; set; } = new(0, 1); /// public double length { get; set; } @@ -188,7 +188,7 @@ public ulong ToUInt64(IFormatProvider provider) public Box bbox { get; set; } /// - public bool TransformTo(Transform transform, out ITransformable polyline) + public bool TransformTo(Transform transform, out ITransformable transformed) { // transform points var transformedPoints = new List(); @@ -198,7 +198,7 @@ public bool TransformTo(Transform transform, out ITransformable polyline) transformedPoints.Add(transformedPoint); } - polyline = new Polyline + transformed = new Polyline { value = transformedPoints.SelectMany(o => o.ToList()).ToList(), closed = closed, @@ -238,8 +238,8 @@ public List ToList() { var list = new List(); list.Add(closed ? 1 : 0); // 2 - list.Add(domain.start ?? 0); // 3 - list.Add(domain.end ?? 1); // 4 + list.Add(domain?.start ?? 0); // 3 + list.Add(domain?.end ?? 1); // 4 list.Add(value.Count); // 5 list.AddRange(value); // 6 onwards @@ -257,9 +257,7 @@ public List ToList() public static Polyline FromList(List list) { - var polyline = new Polyline(); - polyline.closed = list[2] == 1; - polyline.domain = new Interval(list[3], list[4]); + var polyline = new Polyline { closed = list[2] == 1, domain = new Interval(list[3], list[4]) }; var pointCount = (int)list[5]; polyline.value = list.GetRange(6, pointCount); polyline.units = Units.GetUnitFromEncoding(list[list.Count - 1]); diff --git a/Objects/Objects/Geometry/PolylineExtensions.cs b/Objects/Objects/Geometry/PolylineExtensions.cs index d02cc07d84..49d5677e2f 100644 --- a/Objects/Objects/Geometry/PolylineExtensions.cs +++ b/Objects/Objects/Geometry/PolylineExtensions.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; namespace Objects.Geometry; diff --git a/Objects/Objects/Geometry/Spiral.cs b/Objects/Objects/Geometry/Spiral.cs index 292c1210e0..89ef8aea1e 100644 --- a/Objects/Objects/Geometry/Spiral.cs +++ b/Objects/Objects/Geometry/Spiral.cs @@ -24,7 +24,7 @@ public class Spiral : Base, ICurve, IHasBoundingBox, IDisplayValue public Plane plane { get; set; } // plane with origin at spiral center public double turns { get; set; } // total angle of spiral. positive is counterclockwise, negative is clockwise public Vector pitchAxis { get; set; } = new(); - public double pitch { get; set; } = 0; + public double pitch { get; set; } public SpiralType spiralType { get; set; } public string units { get; set; } diff --git a/Objects/Objects/Geometry/Surface.cs b/Objects/Objects/Geometry/Surface.cs index a4b4c1597d..17e1a2c0cc 100644 --- a/Objects/Objects/Geometry/Surface.cs +++ b/Objects/Objects/Geometry/Surface.cs @@ -25,7 +25,7 @@ public Surface() /// /// The units this surface is modeled in /// This surface's unique identifier on a specific application - public Surface(string units = Units.Meters, string applicationId = null) + public Surface(string units = Units.Meters, string? applicationId = null) { this.applicationId = applicationId; this.units = units; @@ -104,7 +104,7 @@ public Surface(string units = Units.Meters, string applicationId = null) public Box bbox { get; set; } /// - public bool TransformTo(Transform transform, out Surface surface) + public bool TransformTo(Transform transform, out Surface transformed) { var ptMatrix = GetControlPoints(); foreach (var ctrlPts in ptMatrix) @@ -116,7 +116,7 @@ public bool TransformTo(Transform transform, out Surface surface) } } - surface = new Surface + transformed = new Surface { degreeU = degreeU, degreeV = degreeV, @@ -131,7 +131,7 @@ public bool TransformTo(Transform transform, out Surface surface) knotsV = knotsV, units = units }; - surface.SetControlPoints(ptMatrix); + transformed.SetControlPoints(ptMatrix); return true; } @@ -171,7 +171,7 @@ public List> GetControlPoints() /// Sets the control points of this . /// /// A 2-dimensional array of instances. - /// The must be ordered following directions "[u][v]" + /// The must be ordered following directions "[u][v]" public void SetControlPoints(List> value) { List data = new(); @@ -230,16 +230,18 @@ public List ToList() /// A new with the provided values. public static Surface FromList(List list) { - var srf = new Surface(); - srf.degreeU = (int)list[0]; - srf.degreeV = (int)list[1]; - srf.countU = (int)list[2]; - srf.countV = (int)list[3]; - srf.rational = list[4] == 1; - srf.closedU = list[5] == 1; - srf.closedV = list[6] == 1; - srf.domainU = new Interval { start = list[7], end = list[8] }; - srf.domainV = new Interval { start = list[9], end = list[10] }; + var srf = new Surface + { + degreeU = (int)list[0], + degreeV = (int)list[1], + countU = (int)list[2], + countV = (int)list[3], + rational = list[4] == 1, + closedU = list[5] == 1, + closedV = list[6] == 1, + domainU = new Interval { start = list[7], end = list[8] }, + domainV = new Interval { start = list[9], end = list[10] } + }; var pointCount = (int)list[11]; var knotsUCount = (int)list[12]; diff --git a/Objects/Objects/Geometry/Vector.cs b/Objects/Objects/Geometry/Vector.cs index 5c5a4aa4bf..ea3271ebef 100644 --- a/Objects/Objects/Geometry/Vector.cs +++ b/Objects/Objects/Geometry/Vector.cs @@ -54,7 +54,7 @@ public Vector(double x, double y, double z, string units = Units.Meters, string? /// The point whose coordinates will be used /// The unique application ID of the object. public Vector(Point point, string? applicationId = null) - : this(point.x, point.y, point.z, point.units, applicationId) { } + : this(point.x, point.y, point.z, point.units ?? Units.None, applicationId) { } /// /// Gets or sets the coordinates of the vector @@ -65,7 +65,9 @@ public Vector(Point point, string? applicationId = null) ] public List value { +#pragma warning disable CS8603 // Possible null reference return. get => null; +#pragma warning restore CS8603 // Possible null reference return. set { x = value[0]; @@ -78,7 +80,7 @@ public List value /// The unit's this is in. /// This should be one of /// - public string units { get; set; } + public string units { get; set; } = Units.None; /// /// The x coordinate of the vector. @@ -106,20 +108,20 @@ public List value public Box bbox { get; set; } /// - public bool TransformTo(Transform transform, out Vector vector) + public bool TransformTo(Transform transform, out Vector transformed) { var m = transform.matrix; var tX = x * m.M11 + y * m.M12 + z * m.M13; var tY = x * m.M21 + y * m.M22 + z * m.M23; var tZ = x * m.M31 + y * m.M32 + z * m.M33; - vector = new Vector(tX, tY, tZ, units, applicationId); + transformed = new Vector(tX, tY, tZ, units, applicationId); return true; } /// public bool TransformTo(Transform transform, out ITransformable transformed) { - var res = TransformTo(transform, out Vector vec); + _ = TransformTo(transform, out Vector vec); transformed = vec; return true; } @@ -150,10 +152,8 @@ public static Vector FromList(List list, string units) /// The vector to divide /// The value to divide by /// The resulting - public static Vector operator /(Vector vector, double val) - { - return new Vector(vector.x / val, vector.y / val, vector.z / val, vector.units); - } + public static Vector operator /(Vector vector, double val) => + new(vector.x / val, vector.y / val, vector.z / val, vector.units); /// /// Multiplies a vector by a numerical value. This will multiply each coordinate by the provided value. @@ -161,10 +161,8 @@ public static Vector FromList(List list, string units) /// The vector to multiply /// The value to multiply by /// The resulting - public static Vector operator *(Vector vector, double val) - { - return new Vector(vector.x * val, vector.y * val, vector.z * val, vector.units); - } + public static Vector operator *(Vector vector, double val) => + new(vector.x * val, vector.y * val, vector.z * val, vector.units); /// /// Adds two vectors by adding each of their coordinates. @@ -172,10 +170,8 @@ public static Vector FromList(List list, string units) /// The first vector /// The second vector /// The resulting - public static Vector operator +(Vector vector1, Vector vector2) - { - return new Vector(vector1.x + vector2.x, vector1.y + vector2.y, vector1.z + vector2.z, vector1.units); - } + public static Vector operator +(Vector vector1, Vector vector2) => + new(vector1.x + vector2.x, vector1.y + vector2.y, vector1.z + vector2.z, vector1.units); /// /// Subtracts two vectors by subtracting each of their coordinates. @@ -183,10 +179,8 @@ public static Vector FromList(List list, string units) /// The first vector /// The second vector /// The resulting - public static Vector operator -(Vector vector1, Vector vector2) - { - return new Vector(vector1.x - vector2.x, vector1.y - vector2.y, vector1.z - vector2.z, vector1.units); - } + public static Vector operator -(Vector vector1, Vector vector2) => + new(vector1.x - vector2.x, vector1.y - vector2.y, vector1.z - vector2.z, vector1.units); /// /// Gets the scalar product (dot product) of two given vectors @@ -221,7 +215,7 @@ public static double Angle(Vector u, Vector v) return Math.Acos(DotProduct(u, v) / (u.Length * v.Length)); } - [Obsolete("Renamed to " + nameof(Normalize))] + [Obsolete("Renamed to " + nameof(Normalize), true)] public void Unitize() { Normalize(); diff --git a/Objects/Objects/Objects.csproj b/Objects/Objects/Objects.csproj index 92216a78a2..77a9ad6bbd 100644 --- a/Objects/Objects/Objects.csproj +++ b/Objects/Objects/Objects.csproj @@ -13,8 +13,21 @@ enable + + true + + $(WarningsNotAsErrors); + CA1008; CA1024; CA1034; CA1065; + CA1708; CA1711; CA1716; CA1724; CA1725; + CA1819; + CA2201; CA2225; + CS0659; CS0661; CS0728; + IDE0041; IDE0060; IDE1006; + + + - + diff --git a/Objects/Objects/ObjectsKit.cs b/Objects/Objects/ObjectsKit.cs index a0cde7918b..81b4812a7d 100644 --- a/Objects/Objects/ObjectsKit.cs +++ b/Objects/Objects/ObjectsKit.cs @@ -1,4 +1,3 @@ -#nullable enable using System; using System.Collections.Generic; using System.IO; @@ -16,7 +15,7 @@ namespace Objects; /// public class ObjectsKit : ISpeckleKit { - private static string? _objectsFolder; + private static string? s_objectsFolder; private readonly Dictionary _loadedConverters = new(); @@ -28,9 +27,9 @@ public class ObjectsKit : ISpeckleKit /// public static string ObjectsFolder { - get => _objectsFolder ??= SpecklePathProvider.ObjectsFolderPath; + get => s_objectsFolder ??= SpecklePathProvider.ObjectsFolderPath; [Obsolete("Use " + nameof(SpecklePathProvider.OverrideObjectsFolderName), true)] - set => _objectsFolder = value; + set => s_objectsFolder = value; } /// @@ -128,12 +127,12 @@ private static ISpeckleConverter LoadConverterFromDisk(string app) public List GetAvailableConverters() { var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var allConverters = Directory.EnumerateFiles(basePath!, "Objects.Converter.*.dll"); + var allConverters = Directory.EnumerateFiles(basePath!, "Objects.Converter.*.dll").ToArray(); //fallback to the default folder, in case the Objects.dll was loaded in the app domain for other reasons - if (!allConverters.Any()) + if (allConverters.Length == 0) { - allConverters = Directory.EnumerateFiles(ObjectsFolder, "Objects.Converter.*.dll"); + allConverters = Directory.EnumerateFiles(ObjectsFolder, "Objects.Converter.*.dll").ToArray(); } //only get assemblies matching the Major and Minor version of Objects diff --git a/Objects/Objects/Organization/DataTable.cs b/Objects/Objects/Organization/DataTable.cs index 10d83f4b29..81721e90ac 100644 --- a/Objects/Objects/Organization/DataTable.cs +++ b/Objects/Objects/Organization/DataTable.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Speckle.Core.Models; -using Speckle.Newtonsoft.Json; namespace Objects.Organization; diff --git a/Objects/Objects/Organization/Model.cs b/Objects/Objects/Organization/Model.cs index a07f459046..0461f8447d 100644 --- a/Objects/Objects/Organization/Model.cs +++ b/Objects/Objects/Organization/Model.cs @@ -4,55 +4,8 @@ namespace Objects.Organization; -#region Removed Classes (2.15) -/* -// The Model class was only being used by the Revit conenctor as the base commit object -// With the new Collection class implementation, this class should be removed -// The only property in use `ModelInfo` will be dynamically attached to the `Collection` base commit object /// -/// Represents a model from an authoring application and can be used as the root commit object when sending. -/// It contains and objects -/// -public class Model : Collection -{ - public Model() { } - - public Model(ModelInfo info, List? settings = null) - { - this.info = info; - this.settings = settings; - } - - /// - /// General model-wide information stored in a object. - /// This may include anything from simply a project / file name to specific location information (eg with ) - /// - public ModelInfo info { get; set; } - - [System.Obsolete("These are not being used")] - public List? settings { get; set; } -} - -// This class had 0 references -public class Setting : Base -{ - /// - /// The name of the setting - /// - public string name { get; set; } - - /// - /// The objects selected in the setting - /// - public List selection { get; set; } -} - -*/ - -#endregion - -/// -/// Basic model info class to be attached to the field on a object. +/// Basic model info class /// It contains general information about the model and can be extended or subclassed to include more application-specific /// information. /// @@ -73,8 +26,7 @@ public class ModelInfo : Base // TODO: not quite sure about this name? /// -/// Extended to be attached to the field on a object. -/// This contains additional properties applicable to AEC projects. +/// Extended to contain additional properties applicable to AEC projects. /// public class BIMModelInfo : ModelInfo { diff --git a/Objects/Objects/Other/Block.cs b/Objects/Objects/Other/Block.cs index a4dd8adb70..fd455dd96a 100644 --- a/Objects/Objects/Other/Block.cs +++ b/Objects/Objects/Other/Block.cs @@ -13,10 +13,10 @@ public class BlockDefinition : Base public BlockDefinition() { } [SchemaInfo("Block Definition", "A Speckle Block definition")] - public BlockDefinition(string name, List geometry, Point basePoint = null) + public BlockDefinition(string name, List geometry, Point? basePoint = null) { this.name = name; - this.basePoint = basePoint ?? new Point(0, 0, 0, Units.None); + this.basePoint = basePoint ?? new() { units = Units.None }; this.geometry = geometry; } @@ -25,12 +25,12 @@ public BlockDefinition(string name, List geometry, Point basePoint = null) /// /// The definition base point of the block /// - public Point basePoint { get; set; } + public Point basePoint { get; set; } = new() { units = Units.None }; [DetachProperty] public List geometry { get; set; } - public string units { get; set; } + public string units { get; set; } = Units.None; /// /// Returns the translation transform of the base point to the internal origin [0,0,0] @@ -38,7 +38,7 @@ public BlockDefinition(string name, List geometry, Point basePoint = null) /// public Transform GetBasePointTransform() { - var translation = new Vector(-basePoint.x, -basePoint.y, -basePoint.z) { units = basePoint.units }; + var translation = new Vector(-basePoint.x, -basePoint.y, -basePoint.z) { units = basePoint.units ?? Units.None }; var transform = new Transform(new Vector(1, 0, 0), new Vector(0, 1, 0), new Vector(1, 0, 0), translation); return transform; } diff --git a/Objects/Objects/Other/Hatch.cs b/Objects/Objects/Other/Hatch.cs index f1bd2d00eb..c18b66f90b 100644 --- a/Objects/Objects/Other/Hatch.cs +++ b/Objects/Objects/Other/Hatch.cs @@ -12,7 +12,7 @@ public class Hatch : Base public List loops { get; set; } public string pattern { get; set; } public double scale { get; set; } = 1; - public double rotation { get; set; } = 0; // relative angle + public double rotation { get; set; } // relative angle } /// diff --git a/Objects/Objects/Other/Instance.cs b/Objects/Objects/Other/Instance.cs index 436a5d06b1..34d5bdd4ef 100644 --- a/Objects/Objects/Other/Instance.cs +++ b/Objects/Objects/Other/Instance.cs @@ -1,233 +1,164 @@ using System; using System.Collections.Generic; using System.Linq; -using Objects.BuiltElements; -using Objects.BuiltElements.Revit; using Objects.Geometry; using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; using Speckle.Newtonsoft.Json; -namespace Objects.Other +namespace Objects.Other; + +public abstract class Instance : Base { - public abstract class Instance : Base + protected Instance(Transform transform) { - protected Instance(Transform transform) - { - this.transform = transform ?? new Transform(); - } - - protected Instance() { } - - /// - /// The column-dominant 4x4 transform of this instance. - /// - /// - /// Indicates transform from internal origin [0,0,0] - /// - public Transform transform { get; set; } - - public abstract Base definition { get; internal set; } + this.transform = transform ?? new Transform(); + } - /// - /// The units of this Instance, should be the same as the instance transform units - /// - public string units { get; set; } + protected Instance() { } - // helper method that scans an Instance for all transformable geometry and nested instances - protected virtual IEnumerable GetTransformableGeometry() - { - var displayValueRule = TraversalRule - .NewTraversalRule() - .When(DefaultTraversal.HasDisplayValue) - .ContinueTraversing(_ => DefaultTraversal.displayValueAndElementsPropAliases); - - var instanceRule = TraversalRule - .NewTraversalRule() - .When(b => b is Instance instance && instance != null) - .ContinueTraversing(DefaultTraversal.None); - - var traversal = new GraphTraversal(instanceRule, displayValueRule, DefaultTraversal.DefaultRule); - - return traversal - .Traverse(definition) - .Select(tc => tc.current) - .Where(b => b is ITransformable || b is Instance) - .Where(b => b != null); - } + /// + /// The column-dominant 4x4 transform of this instance. + /// + /// + /// Indicates transform from internal origin [0,0,0] + /// + public Transform transform { get; set; } - [SchemaComputed("transformedGeometry")] - public virtual IEnumerable GetTransformedGeometry() - { - return GetTransformableGeometry() - .SelectMany(b => - { - switch (b) - { - case Instance i: - return i.GetTransformedGeometry() - .Select(b => - { - b.TransformTo(transform, out var tranformed); - return tranformed; - }); - case ITransformable bt: - var res = bt.TransformTo(transform, out var transformed); - return res ? new List { transformed } : new(); - default: - return new List(); - } - }) - .Where(b => b != null); - } - } + public abstract Base definition { get; internal set; } /// - /// Generic instance class + /// The units of this Instance, should be the same as the instance transform units /// - public abstract class Instance : Instance - where T : Base - { - protected Instance(T definition, Transform transform) - : base(transform) - { - typedDefinition = definition; - } + public string units { get; set; } - protected Instance() - : base(new Transform()) { } - - [JsonIgnore] - public T typedDefinition { get; set; } + // helper method that scans an Instance for all transformable geometry and nested instances + protected virtual IEnumerable GetTransformableGeometry() + { + var displayValueRule = TraversalRule + .NewTraversalRule() + .When(DefaultTraversal.HasDisplayValue) + .ContinueTraversing(_ => DefaultTraversal.DisplayValueAndElementsPropAliases); + + var instanceRule = TraversalRule + .NewTraversalRule() + .When(b => b is Instance instance && instance != null) + .ContinueTraversing(DefaultTraversal.None); + + var traversal = new GraphTraversal(instanceRule, displayValueRule, DefaultTraversal.DefaultRule); + + return traversal + .Traverse(definition) + .Select(tc => tc.Current) + .Where(b => b is ITransformable || b is Instance) + .Where(b => b != null); + } - [DetachProperty] - public override Base definition - { - get => typedDefinition; - internal set + [SchemaComputed("transformedGeometry")] + public virtual IEnumerable GetTransformedGeometry() + { + return GetTransformableGeometry() + .SelectMany(b => { - if (value is T type) + switch (b) { - typedDefinition = type; + case Instance i: + return i.GetTransformedGeometry() + .Select(b => + { + b.TransformTo(transform, out var tranformed); + return tranformed; + }); + case ITransformable bt: + var res = bt.TransformTo(transform, out var transformed); + return res ? new List { transformed } : new(); + default: + return new List(); } - } - } + }) + .Where(b => b != null); } +} - /// - /// Block instance class - /// - public class BlockInstance : Instance +/// +/// Generic instance class +/// +public abstract class Instance : Instance + where T : Base +{ + protected Instance(T definition, Transform transform) + : base(transform) { - public BlockInstance() { } - - [SchemaInfo("Block Instance", "A Speckle Block Instance")] - public BlockInstance(BlockDefinition blockDefinition, Transform transform) - : base(blockDefinition, transform) - { - // OLD: TODO: need to verify - // Add base translation to transform. This assumes the transform is based on the world origin, - // whereas the instance transform assumes it contains the basePoint translation already. - //this.transform = transform * blockDefinition.GetBasePointTransform(); - } + typedDefinition = definition; + } - [DetachProperty, Obsolete("Use definition property", true), JsonIgnore] - public BlockDefinition blockDefinition - { - get => typedDefinition; - set => typedDefinition = value; - } + protected Instance() + : base(new Transform()) { } - protected override IEnumerable GetTransformableGeometry() - { - return typedDefinition.geometry; - } + [JsonIgnore] + public T typedDefinition { get; set; } - /// - /// Returns a plane representing the insertion point and orientation of this Block instance. - /// - /// This method will skip scaling. If you need scaling, we recommend using the transform instead. - /// A Plane on the insertion point of this Block Instance, with the correct 3-axis rotations. - [SchemaComputed("insertionPlane")] - public Plane GetInsertionPlane() + [DetachProperty] + public override Base definition + { + get => typedDefinition; + internal set { - // TODO: UPDATE! - var plane = new Plane( - typedDefinition.basePoint ?? new Point(0, 0, 0, units), - new Vector(0, 0, 1, units), - new Vector(1, 0, 0, units), - new Vector(0, 1, 0, units), - units - ); - plane.TransformTo(transform, out Plane tPlane); - return tPlane; + if (value is T type) + { + typedDefinition = type; + } } } } -namespace Objects.Other.Revit +/// +/// Block instance class +/// +public class BlockInstance : Instance { - public class RevitInstance : Instance - { - public Level level { get; set; } - public bool facingFlipped { get; set; } - public bool handFlipped { get; set; } - public bool mirrored { get; set; } - public Base parameters { get; set; } - public string elementId { get; set; } - - protected override IEnumerable GetTransformableGeometry() - { - var allChildren = typedDefinition.elements ?? new List(); - if (typedDefinition.displayValue.Any()) - { - allChildren.AddRange(typedDefinition.displayValue); - } + public BlockInstance() { } - return allChildren; - } - - [SchemaComputed("transformedGeometry")] - public override IEnumerable GetTransformedGeometry() - { - var transformed = base.GetTransformedGeometry().ToList(); + [SchemaInfo("Block Instance", "A Speckle Block Instance")] + public BlockInstance(BlockDefinition blockDefinition, Transform transform) + : base(blockDefinition, transform) + { + // OLD: TODO: need to verify + // Add base translation to transform. This assumes the transform is based on the world origin, + // whereas the instance transform assumes it contains the basePoint translation already. + //this.transform = transform * blockDefinition.GetBasePointTransform(); + } - // add any dynamically attached elements on this instance - var elements = (this["elements"] ?? this["@elements"]) as List; - if (elements != null) - { - foreach (var element in elements) - { - var display = ((Base)element)["displayValue"] as List; - if (display != null) - { - transformed.AddRange(display.Cast()); - } - } - } + [DetachProperty, Obsolete("Use definition property", true), JsonIgnore] + public BlockDefinition blockDefinition + { + get => typedDefinition; + set => typedDefinition = value; + } - return transformed; - } + protected override IEnumerable GetTransformableGeometry() + { + return typedDefinition.geometry; + } - /// - /// Returns a plane representing the insertion point and orientation of this revit instance. - /// - /// This method will skip scaling. If you need scaling, we recommend using the transform instead. - /// A Plane on the insertion point of this Block Instance, with the correct 3-axis rotations. - [SchemaComputed("insertionPlane")] - public Plane GetInsertionPlane() - { - // TODO: Check for Revit in GH/DYN - var plane = new Plane( - new Point(0, 0, 0, units), - new Vector(0, 0, 1, units), - new Vector(1, 0, 0, units), - new Vector(0, 1, 0, units), - units - ); - plane.TransformTo(transform, out Plane tPlane); - return tPlane; - } + /// + /// Returns a plane representing the insertion point and orientation of this Block instance. + /// + /// This method will skip scaling. If you need scaling, we recommend using the transform instead. + /// A Plane on the insertion point of this Block Instance, with the correct 3-axis rotations. + [SchemaComputed("insertionPlane")] + public Plane GetInsertionPlane() + { + // TODO: UPDATE! + var plane = new Plane( + typedDefinition.basePoint ?? new Point(0, 0, 0, units), + new Vector(0, 0, 1, units), + new Vector(1, 0, 0, units), + new Vector(0, 1, 0, units), + units + ); + plane.TransformTo(transform, out Plane tPlane); + return tPlane; } } diff --git a/Objects/Objects/Other/Material.cs b/Objects/Objects/Other/Material.cs index b8497fc921..83a0e2e86e 100644 --- a/Objects/Objects/Other/Material.cs +++ b/Objects/Objects/Other/Material.cs @@ -1,64 +1,20 @@ -using System.Collections.Generic; -using Objects.BuiltElements.Revit; -using Objects.Utils; using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.Other -{ - /// - /// Generic class for materials containing generic parameters - /// - public class Material : Base - { - public Material() { } - - [SchemaInfo("RevitMaterial", "Creates a Speckle material", "BIM", "Architecture")] - public Material(string name) - { - this.name = name; - } - - public string name { get; set; } - } -} +namespace Objects.Other; -namespace Objects.Other.Revit +/// +/// Generic class for materials containing generic parameters +/// +public class Material : Base { - /// - /// Material in Revit defininf all revit properties from Autodesk.Revit.DB.Material - /// - public class RevitMaterial : Material - { - public RevitMaterial() { } - - [SchemaInfo("RevitMaterial", "Creates a Speckle material", "Revit", "Architecture")] - public RevitMaterial( - string name, - string category, - string materialclass, - int shiny, - int smooth, - int transparent, - List parameters = null - ) - { - this.parameters = parameters.ToBase(); - this.name = name; - materialCategory = category; - materialClass = materialclass; - shininess = shiny; - smoothness = smooth; - transparency = transparent; - } - - public string materialCategory { get; set; } - public string materialClass { get; set; } + public Material() { } - public int shininess { get; set; } - public int smoothness { get; set; } - public int transparency { get; set; } - - public Base parameters { get; set; } + [SchemaInfo("RevitMaterial", "Creates a Speckle material", "BIM", "Architecture")] + public Material(string name) + { + this.name = name; } + + public string name { get; set; } } diff --git a/Objects/Objects/Other/Revit/RevitInstance.cs b/Objects/Objects/Other/Revit/RevitInstance.cs new file mode 100644 index 0000000000..98614d7511 --- /dev/null +++ b/Objects/Objects/Other/Revit/RevitInstance.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using Objects.BuiltElements; +using Objects.BuiltElements.Revit; +using Objects.Geometry; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.Other.Revit; + +public class RevitInstance : Instance +{ + public Level level { get; set; } + public bool facingFlipped { get; set; } + public bool handFlipped { get; set; } + public bool mirrored { get; set; } + public Base parameters { get; set; } + public string elementId { get; set; } + + protected override IEnumerable GetTransformableGeometry() + { + var allChildren = typedDefinition.elements ?? new List(); + if (typedDefinition.displayValue.Count != 0) + { + allChildren.AddRange(typedDefinition.displayValue); + } + + return allChildren; + } + + [SchemaComputed("transformedGeometry")] + public override IEnumerable GetTransformedGeometry() + { + var transformed = base.GetTransformedGeometry().ToList(); + + // add any dynamically attached elements on this instance + if ((this["elements"] ?? this["@elements"]) is List elements) + { + foreach (var element in elements) + { + if (((Base)element)["displayValue"] is List display) + { + transformed.AddRange(display.Cast()); + } + } + } + + return transformed; + } + + /// + /// Returns a plane representing the insertion point and orientation of this revit instance. + /// + /// This method will skip scaling. If you need scaling, we recommend using the transform instead. + /// A Plane on the insertion point of this Block Instance, with the correct 3-axis rotations. + [SchemaComputed("insertionPlane")] + public Plane GetInsertionPlane() + { + // TODO: Check for Revit in GH/DYN + var plane = new Plane( + new Point(0, 0, 0, units), + new Vector(0, 0, 1, units), + new Vector(1, 0, 0, units), + new Vector(0, 1, 0, units), + units + ); + plane.TransformTo(transform, out Plane tPlane); + return tPlane; + } +} diff --git a/Objects/Objects/Other/Revit/RevitMaterial.cs b/Objects/Objects/Other/Revit/RevitMaterial.cs new file mode 100644 index 0000000000..943950fd85 --- /dev/null +++ b/Objects/Objects/Other/Revit/RevitMaterial.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using Objects.BuiltElements.Revit; +using Objects.Utils; +using Speckle.Core.Kits; +using Speckle.Core.Models; + +namespace Objects.Other.Revit; + +/// +/// Material in Revit defininf all revit properties from Autodesk.Revit.DB.Material +/// +public class RevitMaterial : Material +{ + public RevitMaterial() { } + + [SchemaInfo("RevitMaterial", "Creates a Speckle material", "Revit", "Architecture")] + public RevitMaterial( + string name, + string category, + string materialclass, + int shiny, + int smooth, + int transparent, + List? parameters = null + ) + { + this.parameters = parameters?.ToBase(); + this.name = name; + materialCategory = category; + materialClass = materialclass; + shininess = shiny; + smoothness = smooth; + transparency = transparent; + } + + public string materialCategory { get; set; } + public string materialClass { get; set; } + + public int shininess { get; set; } + public int smoothness { get; set; } + public int transparency { get; set; } + + public Base? parameters { get; set; } +} diff --git a/Objects/Objects/Other/Text.cs b/Objects/Objects/Other/Text.cs index 794f220040..22802b19de 100644 --- a/Objects/Objects/Other/Text.cs +++ b/Objects/Objects/Other/Text.cs @@ -10,7 +10,7 @@ namespace Objects.Other; public class Text : Base, IDisplayValue> { public Plane plane { get; set; } // origin should be center - public double rotation { get; set; } = 0; // using radians + public double rotation { get; set; } // using radians public string value { get; set; } // text without RTF public string richText { get; set; } public double height { get; set; } diff --git a/Objects/Objects/Other/Transform.cs b/Objects/Objects/Other/Transform.cs index 0d153a7902..d3a6484481 100644 --- a/Objects/Objects/Other/Transform.cs +++ b/Objects/Objects/Other/Transform.cs @@ -23,7 +23,7 @@ public Transform() { } /// /// /// - public Transform(double[] value, string units = null) + public Transform(double[] value, string units = Units.None) { if (value.Length != 16) { @@ -43,7 +43,7 @@ public Transform(double[] value, string units = null) /// /// /// - public Transform(float[] value, string units = null) + public Transform(float[] value, string units = Units.None) { if (value.Length != 16) { @@ -59,7 +59,7 @@ public Transform(float[] value, string units = null) /// /// /// - public Transform(Matrix4x4 matrix, string units = null) + public Transform(Matrix4x4 matrix, string units = Units.None) { this.matrix = matrix; this.units = units; @@ -107,7 +107,7 @@ public Transform(Vector x, Vector y, Vector z, Vector translation) /// /// Units for translation /// - public string units { get; set; } + public string units { get; set; } = Units.None; /// /// Decomposes matrix into its scaling, rotation, and translation components @@ -317,7 +317,12 @@ internal static Matrix4x4 CreateMatrix(float[] value) #region obsolete - [JsonIgnore, Obsolete("Use the matrix property")] + [JsonIgnore, Obsolete("Use the matrix property", true)] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Performance", + "CA1819:Properties should not return arrays", + Justification = "Obsolete" + )] public double[] value { get => ToArray(); @@ -376,7 +381,7 @@ public List ApplyToPoints(List points) /// Transform a single speckle Point /// [Obsolete("Use transform method in Point class", true)] - public Point ApplyToPoint(Point point) + public Point? ApplyToPoint(Point point) { if (point == null) { @@ -390,18 +395,18 @@ public Point ApplyToPoint(Point point) /// /// Transform a list of three doubles representing a point /// - [Obsolete("Use transform method in Point class")] + [Obsolete("Use transform method in Point class", true)] public List ApplyToPoint(List point) { - var _point = new Point(point[0], point[1], point[2]); - _point.TransformTo(this, out Point transformedPoint); - return transformedPoint.ToList(); + var newPoint = new Point(point[0], point[1], point[2]); + newPoint.TransformTo(this, out Point transformed); + return transformed.ToList(); } /// /// Transform a single speckle Vector /// - [Obsolete("Use transform method in Vector class")] + [Obsolete("Use transform method in Vector class", true)] public Vector ApplyToVector(Vector vector) { var newCoords = ApplyToVector(new List { vector.x, vector.y, vector.z }); @@ -412,7 +417,7 @@ public Vector ApplyToVector(Vector vector) /// /// Transform a list of three doubles representing a vector /// - [Obsolete("Use transform method in Vector class")] + [Obsolete("Use transform method in Vector class", true)] public List ApplyToVector(List vector) { var newPoint = new List(); @@ -429,7 +434,7 @@ public List ApplyToVector(List vector) /// Transform a flat list of ICurves. Note that if any of the ICurves does not implement `ITransformable`, /// it will not be returned. /// - [Obsolete("Use transform method in Curve class")] + [Obsolete("Use transform method in Curve class", true)] public List ApplyToCurves(List curves, out bool success) { // TODO: move to curve class diff --git a/Objects/Objects/Structural/Analysis/Model.cs b/Objects/Objects/Structural/Analysis/Model.cs index da14314256..4092ec7c5e 100644 --- a/Objects/Objects/Structural/Analysis/Model.cs +++ b/Objects/Objects/Structural/Analysis/Model.cs @@ -11,7 +11,6 @@ public Model() { } /// /// SchemaBuilder constructor for a structural model object /// - /// /// /// /// diff --git a/Objects/Objects/Structural/Enums/UnitTypes.cs b/Objects/Objects/Structural/Analysis/UnitTypes.cs similarity index 100% rename from Objects/Objects/Structural/Enums/UnitTypes.cs rename to Objects/Objects/Structural/Analysis/UnitTypes.cs diff --git a/Objects/Objects/Structural/Enums/Axis.cs b/Objects/Objects/Structural/Axis.cs similarity index 100% rename from Objects/Objects/Structural/Enums/Axis.cs rename to Objects/Objects/Structural/Axis.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIStories.cs b/Objects/Objects/Structural/CSI/Analysis/CSIStories.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIStories.cs rename to Objects/Objects/Structural/CSI/Analysis/CSIStories.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Analysis/ETABSAnalysis.cs b/Objects/Objects/Structural/CSI/Analysis/ETABSAnalysis.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Analysis/ETABSAnalysis.cs rename to Objects/Objects/Structural/CSI/Analysis/ETABSAnalysis.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSAreaType.cs b/Objects/Objects/Structural/CSI/Analysis/ETABSAreaType.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSAreaType.cs rename to Objects/Objects/Structural/CSI/Analysis/ETABSAreaType.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSLoadingType.cs b/Objects/Objects/Structural/CSI/Analysis/ETABSLoadingType.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSLoadingType.cs rename to Objects/Objects/Structural/CSI/Analysis/ETABSLoadingType.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement1D.cs b/Objects/Objects/Structural/CSI/Geometry/CSIElement1D.cs similarity index 99% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement1D.cs rename to Objects/Objects/Structural/CSI/Geometry/CSIElement1D.cs index 1698bb0caa..44d682b451 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement1D.cs +++ b/Objects/Objects/Structural/CSI/Geometry/CSIElement1D.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Objects.Geometry; using Objects.Structural.CSI.Properties; using Objects.Structural.Geometry; diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement2D.cs b/Objects/Objects/Structural/CSI/Geometry/CSIElement2D.cs similarity index 96% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement2D.cs rename to Objects/Objects/Structural/CSI/Geometry/CSIElement2D.cs index 0b13cf6cd9..cdf6a58659 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIElement2D.cs +++ b/Objects/Objects/Structural/CSI/Geometry/CSIElement2D.cs @@ -30,7 +30,7 @@ public CSIElement2D( this.property = property; this.offset = offset; this.orientationAngle = orientationAngle; - DiaphragmAssignment = CSIDiaphragm.name; + DiaphragmAssignment = CSIDiaphragm?.name; this.CSIAreaSpring = CSIAreaSpring; this.modifiers = modifiers; } diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIGridLines.cs b/Objects/Objects/Structural/CSI/Geometry/CSIGridLines.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIGridLines.cs rename to Objects/Objects/Structural/CSI/Geometry/CSIGridLines.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSINode.cs b/Objects/Objects/Structural/CSI/Geometry/CSINode.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSINode.cs rename to Objects/Objects/Structural/CSI/Geometry/CSINode.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIPier.cs b/Objects/Objects/Structural/CSI/Geometry/CSIPier.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSIPier.cs rename to Objects/Objects/Structural/CSI/Geometry/CSIPier.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSISpandrel.cs b/Objects/Objects/Structural/CSI/Geometry/CSISpandrel.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSISpandrel.cs rename to Objects/Objects/Structural/CSI/Geometry/CSISpandrel.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSITendon.cs b/Objects/Objects/Structural/CSI/Geometry/CSITendon.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Geometry/CSITendon.cs rename to Objects/Objects/Structural/CSI/Geometry/CSITendon.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Loading/CSIWindLoading.cs b/Objects/Objects/Structural/CSI/Loading/CSIWindLoading.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Loading/CSIWindLoading.cs rename to Objects/Objects/Structural/CSI/Loading/CSIWindLoading.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSIConcrete.cs b/Objects/Objects/Structural/CSI/Materials/CSIConcrete.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSIConcrete.cs rename to Objects/Objects/Structural/CSI/Materials/CSIConcrete.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSIRebar.cs b/Objects/Objects/Structural/CSI/Materials/CSIRebar.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSIRebar.cs rename to Objects/Objects/Structural/CSI/Materials/CSIRebar.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSISteel.cs b/Objects/Objects/Structural/CSI/Materials/CSISteel.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Materials/CSISteel.cs rename to Objects/Objects/Structural/CSI/Materials/CSISteel.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSIDiaphragm.cs b/Objects/Objects/Structural/CSI/Properties/CSIDiaphragm.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSIDiaphragm.cs rename to Objects/Objects/Structural/CSI/Properties/CSIDiaphragm.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSILinkProperty.cs b/Objects/Objects/Structural/CSI/Properties/CSILinkProperty.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSILinkProperty.cs rename to Objects/Objects/Structural/CSI/Properties/CSILinkProperty.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSIProperty2D.cs b/Objects/Objects/Structural/CSI/Properties/CSIProperty2D.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSIProperty2D.cs rename to Objects/Objects/Structural/CSI/Properties/CSIProperty2D.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSISpringProperty.cs b/Objects/Objects/Structural/CSI/Properties/CSISpringProperty.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSISpringProperty.cs rename to Objects/Objects/Structural/CSI/Properties/CSISpringProperty.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSITendonProperty.cs b/Objects/Objects/Structural/CSI/Properties/CSITendonProperty.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Properties/CSITendonProperty.cs rename to Objects/Objects/Structural/CSI/Properties/CSITendonProperty.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSProperty.cs b/Objects/Objects/Structural/CSI/Properties/ETABSProperty.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/ETABS/Enums/ETABSProperty.cs rename to Objects/Objects/Structural/CSI/Properties/ETABSProperty.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSAAnalysisCase.cs b/Objects/Objects/Structural/GSA/Analysis/GSAAnalysisCase.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSAAnalysisCase.cs rename to Objects/Objects/Structural/GSA/Analysis/GSAAnalysisCase.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSAStage.cs b/Objects/Objects/Structural/GSA/Analysis/GSAStage.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSAStage.cs rename to Objects/Objects/Structural/GSA/Analysis/GSAStage.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSATask.cs b/Objects/Objects/Structural/GSA/Analysis/GSATask.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Analysis/GSATask.cs rename to Objects/Objects/Structural/GSA/Analysis/GSATask.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAAlignment.cs b/Objects/Objects/Structural/GSA/Bridge/GSAAlignment.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAAlignment.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAAlignment.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluence.cs b/Objects/Objects/Structural/GSA/Bridge/GSAInfluence.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluence.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAInfluence.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluenceBeam.cs b/Objects/Objects/Structural/GSA/Bridge/GSAInfluenceBeam.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluenceBeam.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAInfluenceBeam.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluenceNode.cs b/Objects/Objects/Structural/GSA/Bridge/GSAInfluenceNode.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAInfluenceNode.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAInfluenceNode.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAPath.cs b/Objects/Objects/Structural/GSA/Bridge/GSAPath.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAPath.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAPath.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAUserVehicle.cs b/Objects/Objects/Structural/GSA/Bridge/GSAUserVehicle.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Bridge/GSAUserVehicle.cs rename to Objects/Objects/Structural/GSA/Bridge/GSAUserVehicle.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAAssembly.cs b/Objects/Objects/Structural/GSA/Geometry/GSAAssembly.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAAssembly.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAAssembly.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement1D.cs b/Objects/Objects/Structural/GSA/Geometry/GSAElement1D.cs similarity index 61% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement1D.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAElement1D.cs index 4be8ab5c9d..e59c1113cb 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement1D.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSAElement1D.cs @@ -21,22 +21,22 @@ public GSAElement1D( Property1D property, ElementType1D type, [SchemaParamInfo("If null, restraint condition defaults to unreleased (fully fixed translations and rotations)")] - Restraint end1Releases = null, + Restraint? end1Releases = null, [SchemaParamInfo("If null, restraint condition defaults to unreleased (fully fixed translations and rotations)")] - Restraint end2Releases = null, - [SchemaParamInfo("If null, defaults to no offsets")] Vector end1Offset = null, - [SchemaParamInfo("If null, defaults to no offsets")] Vector end2Offset = null, - Plane localAxis = null + Restraint? end2Releases = null, + [SchemaParamInfo("If null, defaults to no offsets")] Vector? end1Offset = null, + [SchemaParamInfo("If null, defaults to no offsets")] Vector? end2Offset = null, + Plane? localAxis = null ) { this.nativeId = nativeId; this.baseLine = baseLine; this.property = property; this.type = type; - this.end1Releases = end1Releases == null ? new Restraint("FFFFFF") : end1Releases; - this.end2Releases = end2Releases == null ? new Restraint("FFFFFF") : end2Releases; - this.end1Offset = end1Offset == null ? new Vector(0, 0, 0) : end1Offset; - this.end2Offset = end2Offset == null ? new Vector(0, 0, 0) : end2Offset; + this.end1Releases = end1Releases ?? new Restraint("FFFFFF"); + this.end2Releases = end2Releases ?? new Restraint("FFFFFF"); + this.end1Offset = end1Offset ?? new Vector(0, 0, 0); + this.end2Offset = end2Offset ?? new Vector(0, 0, 0); this.localAxis = localAxis; } @@ -52,12 +52,12 @@ public GSAElement1D( Property1D property, ElementType1D type, [SchemaParamInfo("If null, restraint condition defaults to unreleased (fully fixed translations and rotations)")] - Restraint end1Releases = null, + Restraint? end1Releases = null, [SchemaParamInfo("If null, restraint condition defaults to unreleased (fully fixed translations and rotations)")] - Restraint end2Releases = null, - [SchemaParamInfo("If null, defaults to no offsets")] Vector end1Offset = null, - [SchemaParamInfo("If null, defaults to no offsets")] Vector end2Offset = null, - Node orientationNode = null, + Restraint? end2Releases = null, + [SchemaParamInfo("If null, defaults to no offsets")] Vector? end1Offset = null, + [SchemaParamInfo("If null, defaults to no offsets")] Vector? end2Offset = null, + Node? orientationNode = null, double orientationAngle = 0 ) { @@ -65,10 +65,10 @@ public GSAElement1D( this.baseLine = baseLine; this.property = property; this.type = type; - this.end1Releases = end1Releases == null ? new Restraint("FFFFFF") : end1Releases; - this.end2Releases = end2Releases == null ? new Restraint("FFFFFF") : end2Releases; - this.end1Offset = end1Offset == null ? new Vector(0, 0, 0) : end1Offset; - this.end2Offset = end2Offset == null ? new Vector(0, 0, 0) : end2Offset; + this.end1Releases = end1Releases ?? new Restraint("FFFFFF"); + this.end2Releases = end2Releases ?? new Restraint("FFFFFF"); + this.end1Offset = end1Offset ?? new Vector(0, 0, 0); + this.end2Offset = end2Offset ?? new Vector(0, 0, 0); this.orientationNode = orientationNode; this.orientationAngle = orientationAngle; } diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement2D.cs b/Objects/Objects/Structural/GSA/Geometry/GSAElement2D.cs similarity index 95% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement2D.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAElement2D.cs index 61b20fffb5..06a921dd37 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement2D.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSAElement2D.cs @@ -15,7 +15,7 @@ public GSAElement2D( List nodes, Property2D property, ElementType2D type, - string name = null, + string? name = null, double offset = 0, double orientationAngle = 0, int group = 0, @@ -27,7 +27,7 @@ public GSAElement2D( topology = nodes; this.property = property; this.type = type; - this.name = name; + this.name = name ?? ""; this.nativeId = nativeId; this.offset = offset; this.orientationAngle = orientationAngle; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement3D.cs b/Objects/Objects/Structural/GSA/Geometry/GSAElement3D.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement3D.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAElement3D.cs index 042372cc98..ab9c97ad12 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAElement3D.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSAElement3D.cs @@ -15,7 +15,7 @@ public GSAElement3D( Mesh baseMesh, Property3D property, ElementType3D type, - string name = null, + string? name = null, double orientationAngle = 0, int group = 0, string colour = "NO_RGB", @@ -26,7 +26,7 @@ public GSAElement3D( this.baseMesh = baseMesh; this.property = property; this.type = type; - this.name = name; + this.name = name ?? ""; this.orientationAngle = orientationAngle; this.group = group; this.colour = colour; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGeneralisedRestraint.cs b/Objects/Objects/Structural/GSA/Geometry/GSAGeneralisedRestraint.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGeneralisedRestraint.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAGeneralisedRestraint.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridLine.cs b/Objects/Objects/Structural/GSA/Geometry/GSAGridLine.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridLine.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAGridLine.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridPlane.cs b/Objects/Objects/Structural/GSA/Geometry/GSAGridPlane.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridPlane.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAGridPlane.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridSurface.cs b/Objects/Objects/Structural/GSA/Geometry/GSAGridSurface.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAGridSurface.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAGridSurface.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember1D.cs b/Objects/Objects/Structural/GSA/Geometry/GSAMember1D.cs similarity index 97% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember1D.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAMember1D.cs index d4fbe7e6ff..0503a7a86c 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember1D.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSAMember1D.cs @@ -3,7 +3,7 @@ using Objects.Structural.Properties; using Speckle.Core.Kits; -namespace Objects.Structural.GSA.Geometry; //GSA.Geometry? +namespace Objects.Structural.GSA.Geometry; public class GSAMember1D : Element1D { diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember2D.cs b/Objects/Objects/Structural/GSA/Geometry/GSAMember2D.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember2D.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAMember2D.cs index 3e3d8543f5..2e1eccd8db 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAMember2D.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSAMember2D.cs @@ -20,7 +20,7 @@ public GSAMember2D( [SchemaParamInfo( "A list of ordered lists of nodes representing the voids within a member (ie. order of points should be based on valid polyline)" )] - List> voids = null, + List>? voids = null, double offset = 0, double orientationAngle = 0 ) @@ -39,5 +39,5 @@ public GSAMember2D( public bool isDummy { get; set; } public bool intersectsWithOthers { get; set; } public double targetMeshSize { get; set; } - public List> voids { get; set; } + public List>? voids { get; set; } } diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSANode.cs b/Objects/Objects/Structural/GSA/Geometry/GSANode.cs similarity index 90% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSANode.cs rename to Objects/Objects/Structural/GSA/Geometry/GSANode.cs index b541b03ece..4d86447634 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSANode.cs +++ b/Objects/Objects/Structural/GSA/Geometry/GSANode.cs @@ -24,10 +24,10 @@ public GSANode( int nativeId, Point basePoint, Restraint restraint, - Axis constraintAxis = null, - PropertySpring springProperty = null, - PropertyMass massProperty = null, - PropertyDamper damperProperty = null, + Axis? constraintAxis = null, + PropertySpring? springProperty = null, + PropertyMass? massProperty = null, + PropertyDamper? damperProperty = null, double localElementSize = 0, string colour = "NO_RGB" ) diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSARigidConstraint.cs b/Objects/Objects/Structural/GSA/Geometry/GSARigidConstraint.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSARigidConstraint.cs rename to Objects/Objects/Structural/GSA/Geometry/GSARigidConstraint.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAStorey.cs b/Objects/Objects/Structural/GSA/Geometry/GSAStorey.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAStorey.cs rename to Objects/Objects/Structural/GSA/Geometry/GSAStorey.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadBeam.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadBeam.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadBeam.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadBeam.cs index 5758ddca5f..1efc98da68 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadBeam.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadBeam.cs @@ -21,11 +21,11 @@ public GSALoadBeam( [SchemaParamInfo( "A list that represents load magnitude (number of values varies based on load type - Point: 1, Uniform: 1, Linear: 2, Patch: 2, Tri-linear:2)" )] - List values = null, + List? values = null, [SchemaParamInfo( "A list that represents load locations (number of values varies based on load type - Point: 1, Uniform: null, Linear: null, Patch: 2, Tri-linear: 2)" )] - List positions = null, + List? positions = null, bool isProjected = false ) { @@ -56,11 +56,11 @@ public GSALoadBeam( [SchemaParamInfo( "A list that represents load magnitude (number of values varies based on load type - Point: 1, Uniform: 1, Linear: 2, Patch: 2, Tri-linear:2)" )] - List values = null, + List? values = null, [SchemaParamInfo( "A list that represents load locations (number of values varies based on load type - Point: 1, Uniform: null, Linear: null, Patch: 2, Tri-linear: 2)" )] - List positions = null, + List? positions = null, bool isProjected = false ) { diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadCase.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadCase.cs similarity index 80% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadCase.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadCase.cs index 6773d01fec..7afb86c885 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadCase.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadCase.cs @@ -13,21 +13,21 @@ public GSALoadCase( string name, LoadType loadType, LoadDirection2D loadDirection, - string source = null, + string? source = null, ActionType actionType = ActionType.None, - string description = null, - string include = null, + string? description = null, + string? include = null, bool bridge = false ) { this.nativeId = nativeId; this.name = name; this.loadType = loadType; - group = source; + group = source ?? ""; this.actionType = actionType; - this.description = description; + this.description = description ?? ""; direction = loadDirection; - this.include = include; + this.include = include ?? ""; this.bridge = bridge; } diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadCombination.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadCombination.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadCombination.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadCombination.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadFace.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadFace.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadFace.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadFace.cs index e68118c8fb..28b49439db 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadFace.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadFace.cs @@ -20,11 +20,11 @@ public GSALoadFace( [SchemaParamInfo( "A list that represents load magnitude (number of values varies based on load type - Uniform: 1, Variable: 4 (corner nodes), Point: 1)" )] - List values = null, + List? values = null, [SchemaParamInfo( "A list that represents load locations (number of values varies based on load type - Uniform: null, Variable: null, Point: 2)" )] - List positions = null, + List? positions = null, bool isProjected = false ) { diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGravity.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadGravity.cs similarity index 73% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGravity.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadGravity.cs index bd665d5495..f820fa271f 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGravity.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadGravity.cs @@ -16,12 +16,12 @@ public GSALoadGravity() { } "GSA", "Loading" )] - public GSALoadGravity(int nativeId, string name, LoadCase loadCase, Vector gravityFactors = null) + public GSALoadGravity(int nativeId, string name, LoadCase loadCase, Vector? gravityFactors = null) { this.nativeId = nativeId; this.name = name; this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); } [SchemaInfo( @@ -30,13 +30,19 @@ public GSALoadGravity(int nativeId, string name, LoadCase loadCase, Vector gravi "GSA", "Loading" )] - public GSALoadGravity(int nativeId, string name, LoadCase loadCase, List elements, Vector gravityFactors = null) + public GSALoadGravity( + int nativeId, + string name, + LoadCase loadCase, + List elements, + Vector? gravityFactors = null + ) { this.nativeId = nativeId; this.name = name; this.elements = elements; this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); } [SchemaInfo( @@ -51,8 +57,8 @@ public GSALoadGravity( LoadCase loadCase, List elements, List nodes, - Vector gravityFactors = null, - string nativedId = null + Vector? gravityFactors = null, + string? nativedId = null ) { this.nativeId = nativeId; @@ -60,7 +66,7 @@ public GSALoadGravity( this.elements = elements; this.nodes = nodes; this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); } public int nativeId { get; set; } diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGrid.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadGrid.cs similarity index 93% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGrid.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadGrid.cs index 6b32edc775..d908b01c82 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGrid.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadGrid.cs @@ -11,8 +11,6 @@ protected GSALoadGrid() { } protected GSALoadGrid(int nativeId, GSAGridSurface gridSurface, Axis loadAxis, LoadDirection2D direction) { this.nativeId = nativeId; - name = name; - loadCase = loadCase; this.gridSurface = gridSurface; this.loadAxis = loadAxis; this.direction = direction; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridArea.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadGridArea.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridArea.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadGridArea.cs index 01d0b0833b..420c76468c 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridArea.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadGridArea.cs @@ -19,8 +19,6 @@ public GSALoadGridArea( double value ) { - name = name; - loadCase = loadCase; this.nativeId = nativeId; this.gridSurface = gridSurface; this.loadAxis = loadAxis; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridLine.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadGridLine.cs similarity index 95% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridLine.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadGridLine.cs index 9e3632bd53..3e5590c7be 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridLine.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadGridLine.cs @@ -21,8 +21,6 @@ List values ) { this.nativeId = nativeId; - name = name; - loadCase = loadCase; this.gridSurface = gridSurface; this.loadAxis = loadAxis; this.direction = direction; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridPoint.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadGridPoint.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridPoint.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadGridPoint.cs index fd507ed606..077322c210 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadGridPoint.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadGridPoint.cs @@ -19,8 +19,6 @@ double value ) { this.nativeId = nativeId; - name = name; - loadCase = loadCase; this.gridSurface = gridSurface; this.loadAxis = loadAxis; this.direction = direction; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadNode.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadNode.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadNode.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadNode.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadThermal2d.cs b/Objects/Objects/Structural/GSA/Loading/GSALoadThermal2d.cs similarity index 94% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadThermal2d.cs rename to Objects/Objects/Structural/GSA/Loading/GSALoadThermal2d.cs index 28ce4d2502..1b25a028bc 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Loading/GSALoadThermal2d.cs +++ b/Objects/Objects/Structural/GSA/Loading/GSALoadThermal2d.cs @@ -12,8 +12,6 @@ public GSALoadThermal2d() { } public GSALoadThermal2d(int nativeId, List elements, Thermal2dLoadType type, List values) { this.nativeId = nativeId; - name = name; - loadCase = loadCase; this.elements = elements; this.type = type; this.values = values; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAPolyline.cs b/Objects/Objects/Structural/GSA/Loading/GSAPolyline.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Geometry/GSAPolyline.cs rename to Objects/Objects/Structural/GSA/Loading/GSAPolyline.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAConcrete.cs b/Objects/Objects/Structural/GSA/Materials/GSAConcrete.cs similarity index 95% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAConcrete.cs rename to Objects/Objects/Structural/GSA/Materials/GSAConcrete.cs index 4e0aee0b9e..4773361d2f 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAConcrete.cs +++ b/Objects/Objects/Structural/GSA/Materials/GSAConcrete.cs @@ -11,9 +11,9 @@ public GSAConcrete() { } public GSAConcrete( int nativeId, string name, - string grade = null, - string designCode = null, - string codeYear = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double elasticModulus = 0, double compressiveStrength = 0, double tensileStrength = 0, @@ -48,7 +48,6 @@ public GSAConcrete( this.poissonsRatio = poissonsRatio; this.shearModulus = shearModulus; this.density = density; - thermalExpansivity = thermalExpansivity; this.dampingRatio = dampingRatio; this.cost = cost; this.colour = colour; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAMaterial.cs b/Objects/Objects/Structural/GSA/Materials/GSAMaterial.cs similarity index 92% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAMaterial.cs rename to Objects/Objects/Structural/GSA/Materials/GSAMaterial.cs index 209279f279..66d0a0c2f8 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSAMaterial.cs +++ b/Objects/Objects/Structural/GSA/Materials/GSAMaterial.cs @@ -12,9 +12,9 @@ public GSAMaterial( int nativeId, string name, MaterialType type, - string grade = null, - string designCode = null, - string codeYear = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double strength = 0, double elasticModulus = 0, double poissonsRatio = 0, diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSASteel.cs b/Objects/Objects/Structural/GSA/Materials/GSASteel.cs similarity index 92% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSASteel.cs rename to Objects/Objects/Structural/GSA/Materials/GSASteel.cs index 7da47e2580..b87a91c712 100644 --- a/Objects/Objects/Structural/ApplicationSpecific/GSA/Materials/GSASteel.cs +++ b/Objects/Objects/Structural/GSA/Materials/GSASteel.cs @@ -16,9 +16,9 @@ public GSASteel() { } public GSASteel( int nativeId, string name, - string grade = null, - string designCode = null, - string codeYear = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double elasticModulus = 0, double yieldStrength = 0, double ultimateStrength = 0, @@ -45,7 +45,6 @@ public GSASteel( this.poissonsRatio = poissonsRatio; this.shearModulus = shearModulus; this.density = density; - thermalExpansivity = thermalExpansivity; this.dampingRatio = dampingRatio; this.cost = cost; this.colour = colour; diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Properties/GSAProperty1D.cs b/Objects/Objects/Structural/GSA/Properties/GSAProperty1D.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Properties/GSAProperty1D.cs rename to Objects/Objects/Structural/GSA/Properties/GSAProperty1D.cs diff --git a/Objects/Objects/Structural/ApplicationSpecific/GSA/Properties/GSAProperty2D.cs b/Objects/Objects/Structural/GSA/Properties/GSAProperty2D.cs similarity index 100% rename from Objects/Objects/Structural/ApplicationSpecific/GSA/Properties/GSAProperty2D.cs rename to Objects/Objects/Structural/GSA/Properties/GSAProperty2D.cs diff --git a/Objects/Objects/Structural/Geometry/Axis.cs b/Objects/Objects/Structural/Geometry/Axis.cs index 780133c832..aaf7df8bc8 100644 --- a/Objects/Objects/Structural/Geometry/Axis.cs +++ b/Objects/Objects/Structural/Geometry/Axis.cs @@ -9,7 +9,7 @@ public class Axis : Base public Axis() { } [SchemaInfo("Axis", "Creates a Speckle structural axis (a user-defined axis)", "Structural", "Geometry")] - public Axis(string name, AxisType axisType = AxisType.Cartesian, Plane definition = null) + public Axis(string name, AxisType axisType = AxisType.Cartesian, Plane? definition = null) { this.name = name; this.axisType = axisType; @@ -18,5 +18,5 @@ public Axis(string name, AxisType axisType = AxisType.Cartesian, Plane definitio public string name { get; set; } public AxisType axisType { get; set; } - public Plane definition { get; set; } + public Plane? definition { get; set; } } diff --git a/Objects/Objects/Structural/Geometry/Element3D.cs b/Objects/Objects/Structural/Geometry/Element3D.cs index 8263054cc0..9b52f57b75 100644 --- a/Objects/Objects/Structural/Geometry/Element3D.cs +++ b/Objects/Objects/Structural/Geometry/Element3D.cs @@ -20,7 +20,7 @@ public Element3D( Mesh baseMesh, Property3D property, ElementType3D type, - string name = null, + string? name = null, double orientationAngle = 0 ) { @@ -31,7 +31,7 @@ public Element3D( this.orientationAngle = orientationAngle; } - public string name { get; set; } + public string? name { get; set; } public Mesh baseMesh { get; set; } //rhino - parent mesh? elements (including props/materias) explicitly defined in a list [DetachProperty] diff --git a/Objects/Objects/Structural/Enums/ElementType.cs b/Objects/Objects/Structural/Geometry/ElementType.cs similarity index 100% rename from Objects/Objects/Structural/Enums/ElementType.cs rename to Objects/Objects/Structural/Geometry/ElementType.cs diff --git a/Objects/Objects/Structural/Enums/MemberType.cs b/Objects/Objects/Structural/Geometry/MemberType.cs similarity index 100% rename from Objects/Objects/Structural/Enums/MemberType.cs rename to Objects/Objects/Structural/Geometry/MemberType.cs diff --git a/Objects/Objects/Structural/Enums/MemberType1D.cs b/Objects/Objects/Structural/Geometry/MemberType1D.cs similarity index 100% rename from Objects/Objects/Structural/Enums/MemberType1D.cs rename to Objects/Objects/Structural/Geometry/MemberType1D.cs diff --git a/Objects/Objects/Structural/Geometry/Node.cs b/Objects/Objects/Structural/Geometry/Node.cs index f77b4929f0..b1f4893f55 100644 --- a/Objects/Objects/Structural/Geometry/Node.cs +++ b/Objects/Objects/Structural/Geometry/Node.cs @@ -67,5 +67,5 @@ public Node( [DetachProperty] public PropertyDamper? damperProperty { get; set; } - public string? units { get; set; } + public string units { get; set; } = Units.None; } diff --git a/Objects/Objects/Structural/Enums/RestraintType.cs b/Objects/Objects/Structural/Geometry/RestraintType.cs similarity index 100% rename from Objects/Objects/Structural/Enums/RestraintType.cs rename to Objects/Objects/Structural/Geometry/RestraintType.cs diff --git a/Objects/Objects/Structural/Loading/LoadCase.cs b/Objects/Objects/Structural/Loading/LoadCase.cs index df2d4f0aec..8aa17e43df 100644 --- a/Objects/Objects/Structural/Loading/LoadCase.cs +++ b/Objects/Objects/Structural/Loading/LoadCase.cs @@ -19,21 +19,21 @@ public LoadCase() { } public LoadCase( string name, LoadType loadType, - string group = null, + string? group = null, ActionType actionType = ActionType.None, - string description = null + string? description = null ) { this.name = name; this.loadType = loadType; this.group = group; this.actionType = actionType; - this.description = description; + this.description = description ?? ""; } public string name { get; set; } //load case title, ex. "Dead load" public LoadType loadType { get; set; } //ex. Dead load - public string group { get; set; } //or load group, "A" + public string? group { get; set; } //or load group, "A" public ActionType actionType { get; set; } //ex. Permanent - public string description { get; set; } //category as alternative, ex. Offices – Cat.B, assembly area + public string description { get; set; } = ""; //category as alternative, ex. Offices – Cat.B, assembly area } diff --git a/Objects/Objects/Structural/Loading/LoadGravity.cs b/Objects/Objects/Structural/Loading/LoadGravity.cs index e72f8f1946..0fd0c63d0a 100644 --- a/Objects/Objects/Structural/Loading/LoadGravity.cs +++ b/Objects/Objects/Structural/Loading/LoadGravity.cs @@ -21,10 +21,10 @@ public LoadGravity() { } "Structural", "Loading" )] - public LoadGravity(LoadCase loadCase, Vector gravityFactors = null, string name = null) + public LoadGravity(LoadCase loadCase, Vector? gravityFactors = null, string? name = null) { this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); this.name = name; } @@ -41,11 +41,11 @@ public LoadGravity(LoadCase loadCase, Vector gravityFactors = null, string name "Structural", "Loading" )] - public LoadGravity(LoadCase loadCase, List elements, Vector gravityFactors = null, string name = null) + public LoadGravity(LoadCase loadCase, List elements, Vector? gravityFactors = null, string? name = null) { this.elements = elements; this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); this.name = name; } @@ -67,14 +67,14 @@ public LoadGravity( LoadCase loadCase, List elements, List nodes, - Vector gravityFactors = null, - string name = null + Vector? gravityFactors = null, + string? name = null ) { this.elements = elements; this.nodes = nodes; this.loadCase = loadCase; - this.gravityFactors = gravityFactors == null ? new Vector(0, 0, -1) : gravityFactors; + this.gravityFactors = gravityFactors ?? new Vector(0, 0, -1); this.name = name; } diff --git a/Objects/Objects/Structural/Enums/Loads.cs b/Objects/Objects/Structural/Loading/Loads.cs similarity index 100% rename from Objects/Objects/Structural/Enums/Loads.cs rename to Objects/Objects/Structural/Loading/Loads.cs diff --git a/Objects/Objects/Structural/Enums/MaterialType.cs b/Objects/Objects/Structural/MaterialType.cs similarity index 100% rename from Objects/Objects/Structural/Enums/MaterialType.cs rename to Objects/Objects/Structural/MaterialType.cs diff --git a/Objects/Objects/Structural/Material/Concrete.cs b/Objects/Objects/Structural/Materials/Concrete.cs similarity index 95% rename from Objects/Objects/Structural/Material/Concrete.cs rename to Objects/Objects/Structural/Materials/Concrete.cs index 84f57a010f..8266b7807a 100644 --- a/Objects/Objects/Structural/Material/Concrete.cs +++ b/Objects/Objects/Structural/Materials/Concrete.cs @@ -14,9 +14,9 @@ public Concrete() { } )] public Concrete( string name, - string grade = null, - string designCode = null, - string codeYear = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double elasticModulus = 0, double compressiveStrength = 0, double tensileStrength = 0, diff --git a/Objects/Objects/Structural/Material/Steel.cs b/Objects/Objects/Structural/Materials/Steel.cs similarity index 90% rename from Objects/Objects/Structural/Material/Steel.cs rename to Objects/Objects/Structural/Materials/Steel.cs index ffdfaa5c10..4523da1f90 100644 --- a/Objects/Objects/Structural/Material/Steel.cs +++ b/Objects/Objects/Structural/Materials/Steel.cs @@ -14,9 +14,9 @@ public Steel() { } )] public Steel( string name, - string grade = null, - string designCode = null, - string codeYear = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double elasticModulus = 0, double yieldStrength = 0, double ultimateStrength = 0, @@ -40,7 +40,6 @@ public Steel( this.poissonsRatio = poissonsRatio; this.shearModulus = shearModulus; this.density = density; - thermalExpansivity = thermalExpansivity; this.dampingRatio = dampingRatio; } diff --git a/Objects/Objects/Structural/Material/StructuralMaterial.cs b/Objects/Objects/Structural/Materials/StructuralMaterial.cs similarity index 100% rename from Objects/Objects/Structural/Material/StructuralMaterial.cs rename to Objects/Objects/Structural/Materials/StructuralMaterial.cs diff --git a/Objects/Objects/Structural/Material/Timber.cs b/Objects/Objects/Structural/Materials/Timber.cs similarity index 87% rename from Objects/Objects/Structural/Material/Timber.cs rename to Objects/Objects/Structural/Materials/Timber.cs index 59aedfbeef..d608ce03f0 100644 --- a/Objects/Objects/Structural/Material/Timber.cs +++ b/Objects/Objects/Structural/Materials/Timber.cs @@ -14,10 +14,10 @@ public Timber() { } )] public Timber( string name, - string species = null, - string grade = null, - string designCode = null, - string codeYear = null, + string? species = null, + string? grade = null, + string? designCode = null, + string? codeYear = null, double strength = 0, double elasticModulus = 0, double poissonsRatio = 0, @@ -43,5 +43,5 @@ public Timber( } //missing timber-specific properties? parallel to grain, perpendicular to grain - public string species { get; set; } + public string? species { get; set; } } diff --git a/Objects/Objects/Structural/Property/SectionProfile.cs b/Objects/Objects/Structural/Properties/Profiles/SectionProfile.cs similarity index 98% rename from Objects/Objects/Structural/Property/SectionProfile.cs rename to Objects/Objects/Structural/Properties/Profiles/SectionProfile.cs index 8b3d3a5962..cf933679fb 100644 --- a/Objects/Objects/Structural/Property/SectionProfile.cs +++ b/Objects/Objects/Structural/Properties/Profiles/SectionProfile.cs @@ -185,11 +185,11 @@ public Perimeter() { } "Structural", "Section Profile" )] - public Perimeter(string name, ICurve outline, List voids = null) + public Perimeter(string name, ICurve outline, List? voids = null) { this.name = name; this.outline = outline; - this.voids = voids; + this.voids = voids ?? new(); } public ICurve outline { get; set; } diff --git a/Objects/Objects/Structural/Property/Property.cs b/Objects/Objects/Structural/Properties/Property.cs similarity index 100% rename from Objects/Objects/Structural/Property/Property.cs rename to Objects/Objects/Structural/Properties/Property.cs diff --git a/Objects/Objects/Structural/Property/Property1D.cs b/Objects/Objects/Structural/Properties/Property1D.cs similarity index 87% rename from Objects/Objects/Structural/Property/Property1D.cs rename to Objects/Objects/Structural/Properties/Property1D.cs index 6f748eb95d..e289fce184 100644 --- a/Objects/Objects/Structural/Property/Property1D.cs +++ b/Objects/Objects/Structural/Properties/Property1D.cs @@ -33,6 +33,6 @@ public Property1D(string name, StructuralMaterial? material, SectionProfile prof public SectionProfile profile { get; set; } //section description public BaseReferencePoint referencePoint { get; set; } - public double offsetY { get; set; } = 0; //offset from reference point - public double offsetZ { get; set; } = 0; //offset from reference point + public double offsetY { get; set; } //offset from reference point + public double offsetZ { get; set; } //offset from reference point } diff --git a/Objects/Objects/Structural/Property/Property2D.cs b/Objects/Objects/Structural/Properties/Property2D.cs similarity index 100% rename from Objects/Objects/Structural/Property/Property2D.cs rename to Objects/Objects/Structural/Properties/Property2D.cs diff --git a/Objects/Objects/Structural/Property/Property3D.cs b/Objects/Objects/Structural/Properties/Property3D.cs similarity index 100% rename from Objects/Objects/Structural/Property/Property3D.cs rename to Objects/Objects/Structural/Properties/Property3D.cs diff --git a/Objects/Objects/Structural/Property/PropertyDamper.cs b/Objects/Objects/Structural/Properties/PropertyDamper.cs similarity index 100% rename from Objects/Objects/Structural/Property/PropertyDamper.cs rename to Objects/Objects/Structural/Properties/PropertyDamper.cs diff --git a/Objects/Objects/Structural/Property/PropertyMass.cs b/Objects/Objects/Structural/Properties/PropertyMass.cs similarity index 100% rename from Objects/Objects/Structural/Property/PropertyMass.cs rename to Objects/Objects/Structural/Properties/PropertyMass.cs diff --git a/Objects/Objects/Structural/Property/PropertySpring.cs b/Objects/Objects/Structural/Properties/PropertySpring.cs similarity index 100% rename from Objects/Objects/Structural/Property/PropertySpring.cs rename to Objects/Objects/Structural/Properties/PropertySpring.cs diff --git a/Objects/Objects/Structural/Enums/PropertyType.cs b/Objects/Objects/Structural/PropertyType.cs similarity index 100% rename from Objects/Objects/Structural/Enums/PropertyType.cs rename to Objects/Objects/Structural/PropertyType.cs diff --git a/Objects/Objects/Structural/Results/Result.cs b/Objects/Objects/Structural/Results/Result.cs index c108cd71b2..a117db5487 100644 --- a/Objects/Objects/Structural/Results/Result.cs +++ b/Objects/Objects/Structural/Results/Result.cs @@ -7,21 +7,21 @@ public class Result : Base { public Result() { } - public Result(LoadCase resultCase, string description = null) + public Result(LoadCase resultCase, string? description = null) { this.resultCase = resultCase; - this.description = description; + this.description = description ?? ""; } - public Result(LoadCombination resultCase, string description = null) + public Result(LoadCombination resultCase, string? description = null) { this.resultCase = resultCase; - this.description = description; + this.description = description ?? ""; } [DetachProperty] public Base resultCase { get; set; } //loadCase or loadCombination public string permutation { get; set; } //for enveloped cases? - public string description { get; set; } + public string description { get; set; } = ""; } diff --git a/Objects/Objects/Utils/MeshTriangulationHelper.cs b/Objects/Objects/Utils/MeshTriangulationHelper.cs index b95ad37e66..b553dc885c 100644 --- a/Objects/Objects/Utils/MeshTriangulationHelper.cs +++ b/Objects/Objects/Utils/MeshTriangulationHelper.cs @@ -11,7 +11,7 @@ namespace Objects.Utils; public static class MeshTriangulationHelper { /// - /// Triangulates all faces in . + /// Triangulates all faces in . /// /// The mesh to triangulate. /// If , will not triangulate quad faces. @@ -62,13 +62,13 @@ public static List TriangulateFace(int faceIndex, Mesh mesh, bool includeIn } /// - /// Calculates the triangulation of the face at in . + /// Calculates the triangulation of the face at in list. /// /// /// This implementation is based the ear clipping method /// Proposed by "Christer Ericson (2005) Real-Time Collision Detection". /// - /// The index of the face's cardinality indicator n in .. + /// The index of the face's cardinality indicator n in list. /// /// /// if , the returned list will include cardinality indicators for each triangle @@ -197,10 +197,10 @@ Vector3 V(int v) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TestPointTriangle(Vector3 v, Vector3 a, Vector3 b, Vector3 c) { - bool Test(Vector3 _v, Vector3 _a, Vector3 _b) + static bool Test(Vector3 v, Vector3 a, Vector3 b) { - Vector3 crossA = _v.Cross(_a); - Vector3 crossB = _v.Cross(_b); + Vector3 crossA = v.Cross(a); + Vector3 crossB = a.Cross(b); double dotWithEpsilon = double.Epsilon + crossA.Dot(crossB); return Math.Sign(dotWithEpsilon) != -1; } @@ -242,22 +242,16 @@ public Vector3(double x, double y, double z) public static readonly Vector3 Zero = new(0, 0, 0); - public static Vector3 operator +(Vector3 a, Vector3 b) - { - return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z); - } + public static Vector3 operator +(Vector3 a, Vector3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z); - public static Vector3 operator -(Vector3 a, Vector3 b) - { - return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z); - } + public static Vector3 operator -(Vector3 a, Vector3 b) => new(a.x - b.x, a.y - b.y, a.z - b.z); - public double Dot(Vector3 v) + public readonly double Dot(Vector3 v) { return x * v.x + y * v.y + z * v.z; } - public Vector3 Cross(Vector3 v) + public readonly Vector3 Cross(Vector3 v) { var x = this.y * v.z - this.z * v.y; var y = this.z * v.x - this.x * v.z; @@ -266,7 +260,7 @@ public Vector3 Cross(Vector3 v) return new Vector3(x, y, z); } - public double SquareSum => x * x + y * y + z * z; + public readonly double SquareSum => x * x + y * y + z * z; public void Normalize() { diff --git a/Objects/Objects/Utils/Parameters.cs b/Objects/Objects/Utils/Parameters.cs index 048ed18ca8..153bbbeaa4 100644 --- a/Objects/Objects/Utils/Parameters.cs +++ b/Objects/Objects/Utils/Parameters.cs @@ -11,7 +11,7 @@ public static class Parameters /// /// /// - public static Base ToBase(this List parameters) + public static Base? ToBase(this List parameters) { if (parameters == null) { diff --git a/Objects/Tests/Geometry/ArcTests.cs b/Objects/Tests/Geometry/ArcTests.cs deleted file mode 100644 index 558d21b1a4..0000000000 --- a/Objects/Tests/Geometry/ArcTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using NUnit.Framework; -using Objects.Geometry; - -namespace Objects.Tests.Geometry; - -[TestFixture, TestOf(typeof(Arc))] -public class ArcTests -{ - public Plane TestPlane => new(new Point(0, 0), new Vector(0, 0, 1), new Vector(1, 0, 0), new Vector(0, 1, 0)); - - [Test] - public void CanCreateArc_HalfCircle() - { - var arc = new Arc(TestPlane, new Point(-5, 5), new Point(5, 5), Math.PI); - - Assert.AreEqual(arc.startAngle, 0); - Assert.AreEqual(arc.endAngle, Math.PI); - - Assert.True(Point.Distance(arc.midPoint, new Point(0, 0)) <= 0.0001); - Assert.True(Point.Distance(arc.plane.origin, new Point(0, 5)) <= 0.0001); - } -} diff --git a/Objects/Tests/Geometry/PointTests.cs b/Objects/Tests/Geometry/PointTests.cs deleted file mode 100644 index 684e4bd11e..0000000000 --- a/Objects/Tests/Geometry/PointTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -using NUnit.Framework; -using Objects.Geometry; - -namespace Objects.Tests.Geometry; - -[TestFixture, TestOf(typeof(Point))] -public class PointTests -{ - [Test] - public void TestNull() - { - Point a = null; - Point b = null; - Point c = new(0, 0, 0, null); - - Assert.True(a == b); - Assert.False(a != b); - Assert.True(b == a); - Assert.False(b != a); - - Assert.False(a == c); - Assert.True(a != c); - Assert.False(c == a); - Assert.True(c != a); - } - - [ - Test, - TestCase(1, 1, 1, "m", 1, 1, 1, "m", true), - TestCase(1, 1, 1, "m", 0, 1, 1, "m", false), - TestCase(1, 1, 1, "m", 1, 0, 1, "m", false), - TestCase(1, 1, 1, "m", 1, 1, 0, "m", false), - TestCase(1, 1, 1, "", 1, 1, 1, "", true), - TestCase(1, 1, 1, null, 1, 1, 1, null, true), - TestCase(1, 1, 1, "m", 1, 1, 1, "meters", false), - TestCase(1, 1, 1, "m", 1, 1, 1, "M", false) - ] - // Units - public void TestNotEqual( - double x1, - double y1, - double z1, - string units1, - double x2, - double y2, - double z2, - string units2, - bool expectEquality - ) - { - Point p1 = new(x1, y1, z1, units1); - Point p2 = new(x2, y2, z2, units2); - - Assert.AreEqual(p1 == p2, expectEquality); - Assert.AreEqual(p2 == p1, expectEquality); - } -} diff --git a/Objects/Tests/GenericTests.cs b/Objects/Tests/Objects.Tests.Unit/GenericTests.cs similarity index 93% rename from Objects/Tests/GenericTests.cs rename to Objects/Tests/Objects.Tests.Unit/GenericTests.cs index bcc522b9b4..1252aa1ccd 100644 --- a/Objects/Tests/GenericTests.cs +++ b/Objects/Tests/Objects.Tests.Unit/GenericTests.cs @@ -6,7 +6,7 @@ using Speckle.Core.Kits; using Speckle.Core.Models; -namespace Objects.Tests; +namespace Objects.Tests.Unit; [TestFixture] public class GenericTests @@ -48,7 +48,7 @@ public void SchemaComputedMethod_CanBeCalledWithNoParameters(Type t) // Check if all parameters are optional. // This allows for other methods to be used as long as they can be called empty. // But also covers the basic case of having no parameters in the first place. - Assert.True(m.GetParameters().All(p => p.IsOptional)); + Assert.That(m.GetParameters().All(p => p.IsOptional), Is.True); }); } } diff --git a/Objects/Tests/Objects.Tests.Unit/Geometry/ArcTests.cs b/Objects/Tests/Objects.Tests.Unit/Geometry/ArcTests.cs new file mode 100644 index 0000000000..d5343edc7c --- /dev/null +++ b/Objects/Tests/Objects.Tests.Unit/Geometry/ArcTests.cs @@ -0,0 +1,23 @@ +using System; +using NUnit.Framework; +using Objects.Geometry; + +namespace Objects.Tests.Unit.Geometry; + +[TestFixture, TestOf(typeof(Arc))] +public class ArcTests +{ + private Plane TestPlane => new(new Point(0, 0), new Vector(0, 0, 1), new Vector(1, 0, 0), new Vector(0, 1, 0)); + + [Test] + public void CanCreateArc_HalfCircle() + { + var arc = new Arc(TestPlane, new Point(-5, 5), new Point(5, 5), Math.PI); + + Assert.That(arc.startAngle, Is.EqualTo(0)); + Assert.That(arc.endAngle, Is.EqualTo(Math.PI)); + + Assert.That(Point.Distance(arc.midPoint, new Point(0, 0)), Is.EqualTo(0).Within(0.0001)); + Assert.That(Point.Distance(arc.plane.origin, new Point(0, 5)), Is.EqualTo(0).Within(0.0001)); + } +} diff --git a/Objects/Tests/Geometry/MeshTests.cs b/Objects/Tests/Objects.Tests.Unit/Geometry/MeshTests.cs similarity index 78% rename from Objects/Tests/Geometry/MeshTests.cs rename to Objects/Tests/Objects.Tests.Unit/Geometry/MeshTests.cs index bd6285b2dc..f17f729b02 100644 --- a/Objects/Tests/Geometry/MeshTests.cs +++ b/Objects/Tests/Objects.Tests.Unit/Geometry/MeshTests.cs @@ -1,19 +1,19 @@ using NUnit.Framework; using Objects.Geometry; -namespace Objects.Tests.Geometry; +namespace Objects.Tests.Unit.Geometry; [TestFixture, TestOf(typeof(Mesh))] public class MeshTests { - private static Mesh[] _testCaseSource = { CreateBlenderStylePolygon(), CreateRhinoStylePolygon() }; + private static Mesh[] s_testCaseSource = { CreateBlenderStylePolygon(), CreateRhinoStylePolygon() }; - [Test, TestCaseSource(nameof(_testCaseSource))] + [Test, TestCaseSource(nameof(s_testCaseSource))] public void CanAlignVertices(Mesh inPolygon) { inPolygon.AlignVerticesWithTexCoordsByIndex(); - Assert.AreEqual(inPolygon.VerticesCount, inPolygon.TextureCoordinatesCount); + Assert.That(inPolygon.VerticesCount, Is.EqualTo(inPolygon.TextureCoordinatesCount)); var expectedPolygon = CreateRhinoStylePolygon(); diff --git a/Objects/Tests/Objects.Tests.Unit/Geometry/PointTests.cs b/Objects/Tests/Objects.Tests.Unit/Geometry/PointTests.cs new file mode 100644 index 0000000000..c66ab42c36 --- /dev/null +++ b/Objects/Tests/Objects.Tests.Unit/Geometry/PointTests.cs @@ -0,0 +1,53 @@ +using System.Diagnostics.CodeAnalysis; +using NUnit.Framework; +using Objects.Geometry; + +namespace Objects.Tests.Unit.Geometry; + +[TestFixture, TestOf(typeof(Point))] +public class PointTests +{ + [Test] + [SuppressMessage( + "Assertion", + "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", + Justification = "Need to explicitly test equality operator" + )] + public void TestNull() + { + Point a = null; + Point b = null; + Point c = new(0, 0, 0, null); + + Assert.Multiple(() => + { + Assert.That(a == b, Is.True); + Assert.That(a != b, Is.False); + Assert.That(b == a, Is.True); + Assert.That(b != a, Is.False); + + Assert.That(a == c, Is.False); + Assert.That(a != c, Is.True); + Assert.That(c == a, Is.False); + Assert.That(c != a, Is.True); + }); + } + + [Test] + [TestCase(1, 1, 1, "m", 1, 1, 1, "m", ExpectedResult = true)] + [TestCase(1, 1, 1, "m", 0, 1, 1, "m", ExpectedResult = false)] + [TestCase(1, 1, 1, "m", 1, 0, 1, "m", ExpectedResult = false)] + [TestCase(1, 1, 1, "m", 1, 1, 0, "m", ExpectedResult = false)] + [TestCase(1, 1, 1, "", 1, 1, 1, "", ExpectedResult = true)] + [TestCase(1, 1, 1, null, 1, 1, 1, null, ExpectedResult = true)] + [TestCase(1, 1, 1, "m", 1, 1, 1, "meters", ExpectedResult = false)] + [TestCase(1, 1, 1, "m", 1, 1, 1, "M", ExpectedResult = false)] + // Units + public bool TestEqual(double x1, double y1, double z1, string units1, double x2, double y2, double z2, string units2) + { + Point p1 = new(x1, y1, z1, units1); + Point p2 = new(x2, y2, z2, units2); + + return p1 == p2; + } +} diff --git a/Objects/Tests/Geometry/TransformTests.cs b/Objects/Tests/Objects.Tests.Unit/Geometry/TransformTests.cs similarity index 68% rename from Objects/Tests/Geometry/TransformTests.cs rename to Objects/Tests/Objects.Tests.Unit/Geometry/TransformTests.cs index b9c352e806..4a58004c26 100644 --- a/Objects/Tests/Geometry/TransformTests.cs +++ b/Objects/Tests/Objects.Tests.Unit/Geometry/TransformTests.cs @@ -4,12 +4,12 @@ using Objects.Other; using Speckle.Core.Kits; -namespace Objects.Tests.Geometry; +namespace Objects.Tests.Unit.Geometry; [TestFixture, TestOf(typeof(Transform))] public class TransformTests { - private const float FLOAT_TOLLERANCE = 1e-6f; + private const float FLOAT_TOLERANCE = 1e-6f; [Test, TestCaseSource(nameof(TransformTestCases))] public void ArrayBackAndForth(Matrix4x4 data) @@ -18,7 +18,7 @@ public void ArrayBackAndForth(Matrix4x4 data) var asArr = start.ToArray(); var end = new Transform(asArr); - Assert.AreEqual(data, end.matrix); + Assert.That(end.matrix, Is.EqualTo(data)); } [Test, TestCaseSource(nameof(TransformTestCases))] @@ -36,15 +36,15 @@ public void ConvertToUnits(Matrix4x4 data) Assert.Multiple(() => { - Assert.That(mms.X, Is.EqualTo(ms.X).Within(FLOAT_TOLLERANCE), "Expect scale x to be unchanged"); - Assert.That(mms.Y, Is.EqualTo(ms.Y).Within(FLOAT_TOLLERANCE), "Expect scale y to be unchanged"); - Assert.That(mms.Z, Is.EqualTo(ms.Z).Within(FLOAT_TOLLERANCE), "Expect scale z to be unchanged"); + Assert.That(mms.X, Is.EqualTo(ms.X).Within(FLOAT_TOLERANCE), "Expect scale x to be unchanged"); + Assert.That(mms.Y, Is.EqualTo(ms.Y).Within(FLOAT_TOLERANCE), "Expect scale y to be unchanged"); + Assert.That(mms.Z, Is.EqualTo(ms.Z).Within(FLOAT_TOLERANCE), "Expect scale z to be unchanged"); - Assert.That(Quaternion.Dot(mr, mmr), Is.LessThan(1).Within(FLOAT_TOLLERANCE), "Expect rot x to be equivalent"); + Assert.That(Quaternion.Dot(mr, mmr), Is.LessThan(1).Within(FLOAT_TOLERANCE), "Expect rot x to be equivalent"); - Assert.That(mmt.X, Is.EqualTo(mt.X * SF).Within(FLOAT_TOLLERANCE), $"Expect translation x to be scaled by {SF}"); - Assert.That(mmt.Y, Is.EqualTo(mt.Y * SF).Within(FLOAT_TOLLERANCE), $"Expect translation y to be scaled by {SF}"); - Assert.That(mmt.Z, Is.EqualTo(mt.Z * SF).Within(FLOAT_TOLLERANCE), $"Expect translation z to be scaled by {SF}"); + Assert.That(mmt.X, Is.EqualTo(mt.X * SF).Within(FLOAT_TOLERANCE), $"Expect translation x to be scaled by {SF}"); + Assert.That(mmt.Y, Is.EqualTo(mt.Y * SF).Within(FLOAT_TOLERANCE), $"Expect translation y to be scaled by {SF}"); + Assert.That(mmt.Z, Is.EqualTo(mt.Z * SF).Within(FLOAT_TOLERANCE), $"Expect translation z to be scaled by {SF}"); }); } @@ -57,26 +57,25 @@ public void Decompose(Matrix4x4 data) var transpose = Matrix4x4.Transpose(data); //NOTE: Transform expects matrices transposed (translation in column 4) var sut = new Transform(transpose); - var expected = data; - sut.Decompose(out var s, out var r, out var _t); - var t = new Vector3(_t.X, _t.Y, _t.Z); - Matrix4x4.Decompose(expected, out var expectedS, out var expectedR, out var expectedT); + sut.Decompose(out var s, out var r, out var t); + var actual = new Vector3(t.X, t.Y, t.Z); + Matrix4x4.Decompose(data, out var expectedS, out var expectedR, out var expectedT); Assert.Multiple(() => { - Assert.That(s.X, Is.EqualTo(expectedS.X).Within(FLOAT_TOLLERANCE), "Expect scale x to be unchanged"); - Assert.That(s.Y, Is.EqualTo(expectedS.Y).Within(FLOAT_TOLLERANCE), "Expect scale y to be unchanged"); - Assert.That(s.Z, Is.EqualTo(expectedS.Z).Within(FLOAT_TOLLERANCE), "Expect scale z to be unchanged"); + Assert.That(s.X, Is.EqualTo(expectedS.X).Within(FLOAT_TOLERANCE), "Expect scale x to be unchanged"); + Assert.That(s.Y, Is.EqualTo(expectedS.Y).Within(FLOAT_TOLERANCE), "Expect scale y to be unchanged"); + Assert.That(s.Z, Is.EqualTo(expectedS.Z).Within(FLOAT_TOLERANCE), "Expect scale z to be unchanged"); Assert.That( Quaternion.Dot(r, expectedR), - Is.LessThan(1).Within(FLOAT_TOLLERANCE), + Is.LessThan(1).Within(FLOAT_TOLERANCE), "Expect rot x to be equivalent" ); - Assert.That(t.X, Is.EqualTo(expectedT.X).Within(FLOAT_TOLLERANCE), "Expect translation x to be unchanged"); - Assert.That(t.Y, Is.EqualTo(expectedT.Y).Within(FLOAT_TOLLERANCE), "Expect translation y to be unchanged"); - Assert.That(t.Z, Is.EqualTo(expectedT.Z).Within(FLOAT_TOLLERANCE), "Expect translation z to be unchanged"); + Assert.That(actual.X, Is.EqualTo(expectedT.X).Within(FLOAT_TOLERANCE), "Expect translation x to be unchanged"); + Assert.That(actual.Y, Is.EqualTo(expectedT.Y).Within(FLOAT_TOLERANCE), "Expect translation y to be unchanged"); + Assert.That(actual.Z, Is.EqualTo(expectedT.Z).Within(FLOAT_TOLERANCE), "Expect translation z to be unchanged"); }); } diff --git a/Objects/Tests/NUnit_Fixtures.cs b/Objects/Tests/Objects.Tests.Unit/NUnit_Fixtures.cs similarity index 93% rename from Objects/Tests/NUnit_Fixtures.cs rename to Objects/Tests/Objects.Tests.Unit/NUnit_Fixtures.cs index ad5253ebff..cd01db24e7 100644 --- a/Objects/Tests/NUnit_Fixtures.cs +++ b/Objects/Tests/Objects.Tests.Unit/NUnit_Fixtures.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using Speckle.Core.Logging; -namespace Objects.Tests; +namespace Objects.Tests.Unit; [SetUpFixture] public class NUnitFixtures diff --git a/Core/Tests/TestsUnit.csproj b/Objects/Tests/Objects.Tests.Unit/Objects.Tests.Unit.csproj similarity index 76% rename from Core/Tests/TestsUnit.csproj rename to Objects/Tests/Objects.Tests.Unit/Objects.Tests.Unit.csproj index 10e03f8d25..808077f3d7 100644 --- a/Core/Tests/TestsUnit.csproj +++ b/Objects/Tests/Objects.Tests.Unit/Objects.Tests.Unit.csproj @@ -1,31 +1,40 @@ + net7.0 - enable - enable - false + true + + + true + + + - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + diff --git a/Objects/Tests/Utils/MeshTriangulationHelperTests.cs b/Objects/Tests/Objects.Tests.Unit/Utils/MeshTriangulationHelperTests.cs similarity index 98% rename from Objects/Tests/Utils/MeshTriangulationHelperTests.cs rename to Objects/Tests/Objects.Tests.Unit/Utils/MeshTriangulationHelperTests.cs index 0f4732547c..0a47c077f1 100644 --- a/Objects/Tests/Utils/MeshTriangulationHelperTests.cs +++ b/Objects/Tests/Objects.Tests.Unit/Utils/MeshTriangulationHelperTests.cs @@ -5,7 +5,7 @@ using Objects.Geometry; using Objects.Utils; -namespace Objects.Tests.Utils; +namespace Objects.Tests.Unit.Utils; [TestFixture, TestOf(typeof(MeshTriangulationHelper))] public class MeshTriangulationHelperTests diff --git a/Objects/Tests/Utils/ShallowCopyTests.cs b/Objects/Tests/Objects.Tests.Unit/Utils/ShallowCopyTests.cs similarity index 73% rename from Objects/Tests/Utils/ShallowCopyTests.cs rename to Objects/Tests/Objects.Tests.Unit/Utils/ShallowCopyTests.cs index 3db3855b82..20550a2abc 100644 --- a/Objects/Tests/Utils/ShallowCopyTests.cs +++ b/Objects/Tests/Objects.Tests.Unit/Utils/ShallowCopyTests.cs @@ -5,7 +5,7 @@ using Objects.Geometry; using Speckle.Core.Kits; -namespace Objects.Tests.Utils; +namespace Objects.Tests.Unit.Utils; [TestFixture] public class ShallowCopyTests @@ -20,7 +20,7 @@ public void CanShallowCopy_Wall() }; var shallow = wall.ShallowCopy(); - - Assert.AreEqual(wall.displayValue.Count, ((IList)shallow["displayValue"]).Count); + var displayValue = (IList)shallow["displayValue"]; + Assert.That(wall.displayValue, Has.Count.EqualTo(displayValue.Count)); } } diff --git a/Objects/Tests/Tests.csproj b/Objects/Tests/Tests.csproj deleted file mode 100644 index e750265e2c..0000000000 --- a/Objects/Tests/Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net7.0 - false - Objects.Tests - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - diff --git a/SDK.slnf b/SDK.slnf index 1240f840b8..cb717b1bcb 100644 --- a/SDK.slnf +++ b/SDK.slnf @@ -2,18 +2,19 @@ "solution": { "path": "All.sln", "projects": [ - "ConnectorCore\\BatchUploader.OperationDriver\\BatchUploader.OperationDriver.csproj", - "ConnectorCore\\BatchUploader.Sdk\\BatchUploader.Sdk.csproj", "Automate\\Speckle.Automate.Sdk\\Speckle.Automate.Sdk.csproj", "Automate\\Tests\\Speckle.Automate.Sdk.Tests.Integration\\Speckle.Automate.Sdk.Tests.Integration.csproj", + "ConnectorCore\\BatchUploader.OperationDriver\\BatchUploader.OperationDriver.csproj", + "ConnectorCore\\BatchUploader.Sdk\\BatchUploader.Sdk.csproj", "Core\\Core\\Core.csproj", - "Core\\IntegrationTests\\TestsIntegration.csproj", - "Core\\Tests\\TestsUnit.csproj", + "Core\\Tests\\Speckle.Core.Tests.Integration\\Speckle.Core.Tests.Integration.csproj", + "Core\\Tests\\Speckle.Core.Tests.Performance\\Speckle.Core.Tests.Performance.csproj", + "Core\\Tests\\Speckle.Core.Tests.Unit\\Speckle.Core.Tests.Unit.csproj", "Core\\Transports\\DiskTransport\\DiskTransport.csproj", "Core\\Transports\\MongoDBTransport\\MongoDBTransport.csproj", "DesktopUI2\\DesktopUI2\\DesktopUI2.csproj", "Objects\\Objects\\Objects.csproj", - "Objects\\Tests\\Tests.csproj" + "Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj", ] } -} +} \ No newline at end of file