├── .DS_Store ├── .dockerignore ├── .gitattributes ├── .github └── workflows │ ├── cipython-dev.yml │ ├── cipython-release.yml │ └── dotnet.yml ├── .gitignore ├── .nuke ├── build.schema.json └── parameters.json ├── APSToolkit.sln ├── APSToolkit ├── APSToolkit.csproj ├── Auth.cs ├── BIM360 │ ├── AecLevel.cs │ ├── AecLevelExtension.cs │ ├── BIM360.cs │ ├── BIMData.cs │ ├── BIMObject.cs │ ├── BIMProperty.cs │ ├── FileInfoInDocs.cs │ ├── Level.cs │ ├── ObjectField.cs │ └── ObjectInfo.cs ├── Database │ ├── BucketStorage.cs │ ├── DbReader.cs │ ├── DbReaderRevit.cs │ ├── PropDbReader.cs │ ├── PropDbReaderRevit.cs │ ├── RevitDataConfiguration.cs │ ├── _object_id.cs │ ├── _object_val.cs │ ├── _objects_attr.cs │ └── _objects_eav.cs ├── Derivatives.cs ├── DesignAutomation │ ├── Alias.cs │ ├── DAUtils.cs │ ├── DesignAutomateConfiguration.cs │ ├── DynamoRevitDesignAutomate.cs │ ├── Engine.cs │ ├── RevitDesignAutomate.cs │ └── RevitSetDataAutomate.cs ├── Dockerfile ├── ForgeToolkit.csproj.DotSettings ├── Fragments.cs ├── Geometries.cs ├── IMF.cs ├── InputStream.cs ├── ManifestItem.cs ├── Materials.cs ├── Meshes.cs ├── PackFileReader.cs ├── PathInfo.cs ├── Reader.cs ├── Resources │ └── units.json ├── Scene.cs ├── Schema │ ├── AssetType.cs │ ├── ForceDefaultConverter.cs │ ├── ISvfContent.cs │ ├── ISvfFragment.cs │ ├── ISvfGeometryMetadata.cs │ ├── ISvfLines.cs │ ├── ISvfManifest.cs │ ├── ISvfManifestAsset.cs │ ├── ISvfManifestType.cs │ ├── ISvfManifestTypeSet.cs │ ├── ISvfMaterial.cs │ ├── ISvfMaterialGroup.cs │ ├── ISvfMaterialMap.cs │ ├── ISvfMaterialMapScale.cs │ ├── ISvfMaterialMaps.cs │ ├── ISvfMaterialProperties.cs │ ├── ISvfMaterials.cs │ ├── ISvfMesh.cs │ ├── ISvfMetadata.cs │ ├── ISvfPoints.cs │ ├── ISvfRoot.cs │ ├── ISvfTransform.cs │ ├── ISvfUVMap.cs │ ├── IntValues.cs │ ├── RGBA.cs │ ├── RGBValuesAndStringConnections.cs │ ├── StringConnections.cs │ ├── StringValues.cs │ ├── UnitsAndNumberValues.cs │ ├── ValueObj.cs │ └── XYZArray.cs ├── SvfReader.cs ├── Token.cs ├── Utils │ ├── Base64Convert.cs │ ├── CsvHelper.cs │ ├── DataFrame.cs │ ├── DataTableUtils.cs │ ├── DiscordWebhook.cs │ ├── EnumRecords.cs │ ├── ExcelUtils.cs │ ├── GzipUtils.cs │ ├── LogUtils.cs │ ├── ParquetExport.cs │ ├── RecordUtils.cs │ └── UnitUtils.cs └── WaveFront.cs ├── APSToolkitApp ├── APSToolkitApp.csproj ├── AssemblyInfo.cs ├── Model │ └── ApsProject.cs ├── View │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainWindow.xaml │ └── MainWindow.xaml.cs └── ViewModel │ ├── APSToolkitViewModel.cs │ └── ProjectViewModel.cs ├── APSToolkitPython ├── .gitignore ├── Readme.md ├── Tutorials │ ├── 00. Jupyter Notebook And Python.ipynb │ ├── 00.01. Jupyter Notebook And Google Colab.ipynb │ ├── 01. Setup And Authentication.ipynb │ ├── 02. Explore Hubs - Projects - Items - URN.ipynb │ ├── 03. Explore Versions Item and Derivative Urn.ipynb │ ├── 04. Explore General Metdadata With APSToolkit.ipynb │ ├── 04.01. Explore Revit Data With APSToolkit.ipynb │ ├── 04.02. Explore Compare Revit Data Versions.ipynb │ ├── 04.03. Explore Acad Data With APSToolkit.ipynb │ ├── 04.04. Explore Navisworks Data With APSToolkit.ipynb │ ├── 05. Explore Access Database And Query Items.ipynb │ ├── 06. Data Visualization - Analyst BIM Model.ipynb │ ├── 07. Explore Big Data Format Storage.ipynb │ ├── 08. Explore URL ACC Extract.ipynb │ ├── 09. Explore SVF - Export SVF Viewer.ipynb │ └── 10. Chat With Your Data Use APSToolkit.ipynb ├── requirements-dev.txt ├── requirements.txt ├── setup.py └── src │ ├── aps_toolkit │ ├── AECDataModel.py │ ├── Auth.py │ ├── AuthGoogleColab.py │ ├── BIM360.py │ ├── Bucket.py │ ├── ConvertUtils.py │ ├── DbReader.py │ ├── Derivative.py │ ├── Fragments.py │ ├── InputStream.py │ ├── ManifestItem.py │ ├── MaterialProperties.py │ ├── Materials.py │ ├── PackFileReader.py │ ├── PathInfo.py │ ├── ProDbReaderCad.py │ ├── ProDbReaderNavis.py │ ├── ProDbReaderRevit.py │ ├── PropReader.py │ ├── Resource.py │ ├── SVFContent.py │ ├── SVFGeometries.py │ ├── SVFImage.py │ ├── SVFLines.py │ ├── SVFManifestType.py │ ├── SVFMaterialGroup.py │ ├── SVFMaterialMap.py │ ├── SVFMaterialMapScale.py │ ├── SVFMaterials.py │ ├── SVFMesh.py │ ├── SVFMetadata.py │ ├── SVFPoints.py │ ├── SVFReader.py │ ├── SVFTransform.py │ ├── SVFUVMap.py │ ├── Token.py │ ├── Webhooks.py │ ├── __init__.py │ └── units │ │ ├── DisplayUnits.py │ │ ├── __init__.py │ │ └── units.json │ └── test │ ├── __init__.py │ ├── _trial_temp │ └── _trial_marker │ ├── context.py │ ├── resources │ └── Test.dwg │ ├── test_Webhooks.py │ ├── test_aec_data_model.py │ ├── test_auth.py │ ├── test_auth_colab.py │ ├── test_bim360.py │ ├── test_bucket.py │ ├── test_db_reader.py │ ├── test_derivative.py │ ├── test_fragment.py │ ├── test_geometries.py │ ├── test_image.py │ ├── test_material.py │ ├── test_mesh.py │ ├── test_metadata.py │ ├── test_prop_reader.py │ ├── test_prop_reader_cad.py │ ├── test_prop_reader_navis.py │ ├── test_prop_reader_revit.py │ ├── test_svf_reader.py │ └── test_token.py ├── APSToolkitUnit ├── APSToolkitUnit.csproj ├── AuthTest.cs ├── BIM360Test.cs ├── Base64Test.cs ├── BucketTest.cs ├── CompareTest.cs ├── CsvTest.cs ├── DBReaderRevitTest.cs ├── DataFrameTest.cs ├── DbReaderTest.cs ├── DerivativeTest.cs ├── DesignAutomationTest.cs ├── ExcelTest.cs ├── FragmentsTest.cs ├── ProbDbReaderRevitTest.cs ├── ProbDbReaderTest.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── DataSetParameterAddIn.zip │ ├── model.rvt │ ├── model_ifc.sdb │ ├── model_nwc.sdb │ ├── model_rvt.sdb │ ├── objects_attrs.json.gz │ ├── objects_avs.json.gz │ ├── objects_ids.json.gz │ ├── objects_offs.json.gz │ ├── objects_vals.json.gz │ ├── objects_viewables.json.gz │ ├── result.parquet │ └── result.xlsx ├── Settings.cs ├── SvfReaderTest.cs ├── UnitsTest.cs └── VersionTest.cs ├── CONTRIBUTING.md ├── ExportUnitAddin ├── ExportUnitAddin.csproj └── ExportUnitCommand.cs ├── License.md ├── Readme.md ├── build.cmd ├── build.ps1 ├── build.sh ├── build ├── .editorconfig ├── Build.NugetPush.cs ├── Build.cs ├── Configuration.cs ├── Directory.Build.props ├── Directory.Build.targets ├── _build.csproj └── _build.csproj.DotSettings ├── docs ├── APSToolkit.png ├── Nuget.md └── Tutorials │ ├── 00. Jupyter Notebook And .NET Interactive.ipynb │ ├── 01. Setup And Authentication.ipynb │ ├── 02. Explore Hubs - Projects - Items - URN.ipynb │ ├── 03. Explore Versions Item and Derivative Urn.ipynb │ ├── 04. Explore General Metdadata With APSToolkit.ipynb │ ├── 04.01. Explore Revit Data With APSToolkit.ipynb │ ├── 05. Explore Access Database And Query Items.ipynb │ ├── 06. Explore SVF - Export SVF Viewer.ipynb │ ├── 07. Explore Update Revit Data Back To ACC.ipynb │ ├── 08. Explore Pull Data From ACC BIM360 API.ipynb │ ├── 09. Explore Data Knowledge Use LLM Agent.ipynb │ ├── 10. Build Pipeline Data Process with APSToolkit.ipynb │ ├── 11. Visualization Data - Data Analyst.ipynb │ ├── 12. Custom Python In .NET Interactive.ipynb │ └── 13. Custom Metadata Export.ipynb └── sql ├── GetElementId.sql ├── GetPrototype.sql ├── GetRevitCategories.sql ├── GetallData.sql ├── QueryByDbId.sql ├── QueryByElementId.sql ├── QueryInternalProperty.sql ├── QueryRevitFamily.sql ├── QueryRevitFamilyType.sql └── QueryRevitLikeCategory.sql /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/.DS_Store -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.dockerignore 2 | **/.env 3 | **/.git 4 | **/.gitignore 5 | **/.project 6 | **/.settings 7 | **/.toolstarget 8 | **/.vs 9 | **/.vscode 10 | **/.idea 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/cipython-dev.yml: -------------------------------------------------------------------------------- 1 | name: CI-Python-Development 2 | 3 | on: 4 | push: 5 | branches: 6 | - dev 7 | pull_request: 8 | branches: 9 | - dev 10 | release: 11 | types: [published] 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | python-version: [ 3.11 ] 19 | 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v2 23 | 24 | - name: Set up Python ${{ matrix.python-version }} 25 | uses: actions/setup-python@v2 26 | with: 27 | python-version: ${{ matrix.python-version }} 28 | 29 | - name: Install dependencies 30 | working-directory: APSToolkitPython 31 | run: | 32 | pip install . 33 | 34 | publish: 35 | runs-on: ubuntu-latest 36 | needs: build 37 | if: github.ref == 'refs/heads/main' && github.event_name == 'release' && github.event.action == 'published' 38 | steps: 39 | - name: Checkout repository 40 | uses: actions/checkout@v2 41 | 42 | - name: Set up Python 43 | uses: actions/setup-python@v2 44 | with: 45 | python-version: '3.11' 46 | 47 | - name: Install build tools 48 | working-directory: APSToolkitPython 49 | run: | 50 | python -m pip install --upgrade pip 51 | pip install build twine 52 | pip install setuptools 53 | pip install wheel 54 | 55 | - name: Build package 56 | working-directory: APSToolkitPython 57 | run: python setup.py sdist bdist_wheel 58 | 59 | - name: Publish package to PyPI 60 | working-directory: APSToolkitPython 61 | env: 62 | TWINE_USERNAME: __token__ 63 | TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} 64 | run: python -m twine upload dist/* 65 | -------------------------------------------------------------------------------- /.github/workflows/cipython-release.yml: -------------------------------------------------------------------------------- 1 | name: CI-Python-Production 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | # release: 11 | # types: [published] 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | python-version: [ 3.11 ] 19 | 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v2 23 | 24 | - name: Set up Python ${{ matrix.python-version }} 25 | uses: actions/setup-python@v2 26 | with: 27 | python-version: ${{ matrix.python-version }} 28 | 29 | - name: Install dependencies 30 | working-directory: APSToolkitPython 31 | run: | 32 | pip install . 33 | 34 | publish: 35 | runs-on: ubuntu-latest 36 | needs: build 37 | steps: 38 | - name: Checkout repository 39 | uses: actions/checkout@v2 40 | 41 | - name: Set up Python 42 | uses: actions/setup-python@v2 43 | with: 44 | python-version: '3.11' 45 | 46 | - name: Install build tools 47 | working-directory: APSToolkitPython 48 | run: | 49 | python -m pip install --upgrade pip 50 | pip install build twine 51 | pip install setuptools 52 | pip install wheel 53 | 54 | - name: Build package 55 | working-directory: APSToolkitPython 56 | run: python setup.py sdist bdist_wheel 57 | 58 | - name: Publish package to PyPI 59 | working-directory: APSToolkitPython 60 | env: 61 | TWINE_USERNAME: __token__ 62 | TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} 63 | run: python -m twine upload dist/* 64 | -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a .NET project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net 3 | 4 | name: .NET 5 | 6 | on: 7 | push: 8 | branches: [ "dev" ] 9 | pull_request: 10 | branches: [ "dev" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Setup .NET 20 | uses: actions/setup-dotnet@v3 21 | with: 22 | dotnet-version: 6.0.x 23 | - name: Restore dependencies 24 | run: dotnet restore 25 | - name: Build 26 | # run: dotnet build --no-restore 27 | run: dotnet build --configuration Debug --no-restore 28 | - name: Test 29 | run: 30 | # dotnet test --no-build --verbosity normal 31 | dotnet test --configuration Debug --no-build --verbosity normal 32 | env: 33 | APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }} 34 | APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }} 35 | -------------------------------------------------------------------------------- /.nuke/build.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "$ref": "#/definitions/build", 4 | "title": "Build Schema", 5 | "definitions": { 6 | "build": { 7 | "type": "object", 8 | "properties": { 9 | "Configuration": { 10 | "type": "string", 11 | "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)", 12 | "enum": [ 13 | "Debug", 14 | "Release" 15 | ] 16 | }, 17 | "Continue": { 18 | "type": "boolean", 19 | "description": "Indicates to continue a previously failed build attempt" 20 | }, 21 | "Help": { 22 | "type": "boolean", 23 | "description": "Shows the help text for this build assembly" 24 | }, 25 | "Host": { 26 | "type": "string", 27 | "description": "Host for execution. Default is 'automatic'", 28 | "enum": [ 29 | "AppVeyor", 30 | "AzurePipelines", 31 | "Bamboo", 32 | "Bitbucket", 33 | "Bitrise", 34 | "GitHubActions", 35 | "GitLab", 36 | "Jenkins", 37 | "Rider", 38 | "SpaceAutomation", 39 | "TeamCity", 40 | "Terminal", 41 | "TravisCI", 42 | "VisualStudio", 43 | "VSCode" 44 | ] 45 | }, 46 | "NoLogo": { 47 | "type": "boolean", 48 | "description": "Disables displaying the NUKE logo" 49 | }, 50 | "NugetApiKey": { 51 | "type": "string", 52 | "default": "Secrets must be entered via 'nuke :secrets [profile]'" 53 | }, 54 | "Partition": { 55 | "type": "string", 56 | "description": "Partition to use on CI" 57 | }, 58 | "Plan": { 59 | "type": "boolean", 60 | "description": "Shows the execution plan (HTML)" 61 | }, 62 | "Profile": { 63 | "type": "array", 64 | "description": "Defines the profiles to load", 65 | "items": { 66 | "type": "string" 67 | } 68 | }, 69 | "Root": { 70 | "type": "string", 71 | "description": "Root directory during build execution" 72 | }, 73 | "Skip": { 74 | "type": "array", 75 | "description": "List of targets to be skipped. Empty list skips all dependencies", 76 | "items": { 77 | "type": "string", 78 | "enum": [ 79 | "Clean", 80 | "NuGetPush", 81 | "Pack", 82 | "PublishNuget", 83 | "Restore" 84 | ] 85 | } 86 | }, 87 | "Solution": { 88 | "type": "string", 89 | "description": "Path to a solution file that is automatically loaded" 90 | }, 91 | "Target": { 92 | "type": "array", 93 | "description": "List of targets to be invoked. Default is '{default_target}'", 94 | "items": { 95 | "type": "string", 96 | "enum": [ 97 | "Clean", 98 | "NuGetPush", 99 | "Pack", 100 | "PublishNuget", 101 | "Restore" 102 | ] 103 | } 104 | }, 105 | "Verbosity": { 106 | "type": "string", 107 | "description": "Logging verbosity during build execution. Default is 'Normal'", 108 | "enum": [ 109 | "Minimal", 110 | "Normal", 111 | "Quiet", 112 | "Verbose" 113 | ] 114 | } 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /.nuke/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./build.schema.json", 3 | "Solution": "APSToolkit.sln" 4 | } 5 | -------------------------------------------------------------------------------- /APSToolkit/APSToolkit.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | enable 4 | enable 5 | APSToolkit 6 | net6 7 | latest 8 | chuongmep.com 9 | false 10 | true 11 | Dependency 12 | APSToolkit 13 | 1.2.0 14 | 1.2.0 15 | true 16 | false 17 | revit;bim360;acc;adsk;forgetoolkit;forge;autodesk;aps; 18 | The toolkit support imporve process Autodesk Forge Pipeline 19 | https://github.com/chuongmep/aps-toolkit 20 | License.md 21 | Readme.md 22 | 23 | CS8632;CS7035 24 | 25 | 26 | full 27 | 28 | 29 | 30 | .dockerignore 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /APSToolkit/BIM360/AecLevel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class AecLevel 6 | { 7 | public string Guid { get; set; } 8 | public string Name { get; set; } 9 | public double Elevation { get; set; } 10 | public double Height { get; set; } 11 | public AecLevelExtension Extension { get; set; } 12 | } -------------------------------------------------------------------------------- /APSToolkit/BIM360/AecLevelExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class AecLevelExtension 6 | { 7 | public bool BuildingStory { get; set; } 8 | public bool Structure { get; set; } 9 | public double ComputationHeight { get; set; } 10 | public bool GroundPlane { get; set; } 11 | public bool HasAssociatedViewPlans { get; set; } 12 | public double? ProjectElevation { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /APSToolkit/BIM360/BIMData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class BIMData 6 | { 7 | public int? DbId { get; set; } 8 | public string? externalId { get; set; } 9 | public System.Numerics.Vector3? bboxMin { get; set; } 10 | public System.Numerics.Vector3? bboxMax { get; set; } 11 | public BIMProperty[] properties { get; set; } 12 | 13 | } -------------------------------------------------------------------------------- /APSToolkit/BIM360/BIMObject.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using JObject = Newtonsoft.Json.Linq.JObject; 4 | 5 | namespace APSToolkit.BIM360; 6 | 7 | public class BIMObject 8 | { 9 | public int? svf2Id { get; set; } 10 | public int? otgId { get; set; } 11 | public string? lineageId { get; set; } 12 | public string? externalId { get; set; } 13 | public int? lmvId { get; set; } 14 | public string? databaseId { get; set; } 15 | public Dictionary props { get; set; } 16 | public string? propsHash { get; set; } 17 | public string? geomHash { get; set; } 18 | public JObject? bboxMin { get; set; } 19 | public JObject? bboxMax { get; set; } 20 | public List? views { get; set; } 21 | } 22 | -------------------------------------------------------------------------------- /APSToolkit/BIM360/BIMProperty.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class BIMProperty 6 | { 7 | public string? Name { get; set; } 8 | public string? Type { get; set; } 9 | public string? Category { get; set; } 10 | public string? Value { get; set; } 11 | public string? Unit { get; set; } 12 | } -------------------------------------------------------------------------------- /APSToolkit/BIM360/FileInfoInDocs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class FileInfoInDocs 6 | { 7 | public string ProjectId { get; set; } 8 | public string FolderUrn { get; set; } 9 | public string? ItemId { get; set; } 10 | public string VersionId { get; set; } 11 | } 12 | -------------------------------------------------------------------------------- /APSToolkit/BIM360/Level.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class Level 6 | { 7 | public int Index { get; set; } 8 | public string Guid { get; set; } 9 | public string Name { get; set; } 10 | public double ZMin { get; set; } 11 | public double ZMax { get; set; } 12 | } -------------------------------------------------------------------------------- /APSToolkit/BIM360/ObjectField.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Text.Json.Serialization; 4 | using Newtonsoft.Json.Serialization; 5 | 6 | namespace APSToolkit.BIM360; 7 | 8 | [JsonConverter(typeof(JsonStringContract))] 9 | public class BIMField 10 | { 11 | public string key { get; set; } 12 | public string category { get; set; } 13 | public string type { get; set; } 14 | public string name { get; set; } 15 | public string uom { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /APSToolkit/BIM360/ObjectInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.BIM360; 4 | 5 | public class ObjectInfo 6 | { 7 | public string BucketKey { get; set; } 8 | public string ObjectKey { get; set; } 9 | } -------------------------------------------------------------------------------- /APSToolkit/Database/RevitDataConfiguration.cs: -------------------------------------------------------------------------------- 1 | using APSToolkit.Schema; 2 | using APSToolkit.Utils; 3 | using OfficeOpenXml.Style; 4 | 5 | namespace APSToolkit.Database; 6 | 7 | public class RevitDataConfiguration 8 | { 9 | 10 | /// 11 | /// True to add units to the value of parameter object APS 12 | /// 13 | public bool IsAddUnits { get; set; } = true; 14 | 15 | /// 16 | /// True to get the parameter type of the object APS 17 | /// 18 | public bool IsGetParameterType { get; set; } = true; 19 | /// 20 | /// True to get the internal parameter of the object APS 21 | /// 22 | public bool IsGetInternalParameter { get; set; } = false; 23 | 24 | /// 25 | /// True to get the bounding box of the object 26 | /// 27 | public bool IsGetBBox { get; set; } = false; 28 | 29 | public string Urn { get; set; } 30 | 31 | public Token? Token { get; set; } 32 | 33 | public Dictionary Units = new Dictionary(); 34 | 35 | public Dictionary Fragments = new Dictionary(); 36 | public RevitDataConfiguration() 37 | { 38 | 39 | } 40 | public RevitDataConfiguration(string urn,Token? token) : this() 41 | { 42 | this.Urn = urn; 43 | this.Token = token; 44 | } 45 | public RevitDataConfiguration(string urn) : this() 46 | { 47 | this.Urn = urn; 48 | var auth = new Auth(); 49 | this.Token = auth.Get2LeggedToken().Result; 50 | } 51 | 52 | public void RebuildConfiguration() 53 | { 54 | if (IsAddUnits) 55 | { 56 | Units = UnitUtils.GetAllDictUnits(); 57 | } 58 | 59 | if (IsGetBBox) 60 | { 61 | Dictionary svfFragments = GetFragments(Token.AccessToken).Result; 62 | Fragments = svfFragments; 63 | } 64 | } 65 | 66 | private async Task> GetFragments(string accessToken) 67 | { 68 | Dictionary fragments = 69 | await Derivatives.ReadFragmentsRemoteAsync(Urn, accessToken).ConfigureAwait(false); 70 | // flatten the fragments to list of svf fragments 71 | List svfFragments = fragments.Values.SelectMany(x => x).ToList(); 72 | // save to location with unique dbid and value 73 | Dictionary locations = new Dictionary(); 74 | foreach (ISvfFragment svfFragment in svfFragments) 75 | { 76 | if (svfFragment.dbID == 0) continue; 77 | if (svfFragment.transform == null) continue; 78 | locations.TryAdd(svfFragment.dbID, svfFragment); 79 | } 80 | return locations; 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /APSToolkit/Database/_object_id.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Runtime.Serialization; 4 | 5 | namespace APSToolkit.Database; 6 | 7 | public class _object_id 8 | { 9 | [DataMember(Order = 1)] 10 | public int id { get; set; } 11 | 12 | /// 13 | /// guid of object 14 | /// 15 | [DataMember(Order = 2)] 16 | public string? external_id { get; set; } 17 | 18 | /// 19 | /// viewable id of object 20 | /// 21 | [DataMember(Order = 3)] 22 | public string viewable_id { get; set; } 23 | } -------------------------------------------------------------------------------- /APSToolkit/Database/_object_val.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Runtime.Serialization; 4 | 5 | namespace APSToolkit.Database; 6 | 7 | public class _object_val 8 | { 9 | /// 10 | /// index if of value table 11 | /// 12 | [DataMember(Order = 1)] 13 | public int id { get; set; } 14 | 15 | 16 | /// 17 | /// Value of parameterc 18 | /// 19 | [DataMember(Order = 2)] 20 | public string? value { get; set; } 21 | 22 | } -------------------------------------------------------------------------------- /APSToolkit/Database/_objects_attr.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Runtime.Serialization; 4 | 5 | namespace APSToolkit.Database; 6 | // Copyright (c) chuongmep.com. All rights reserved 7 | 8 | public class _objects_attr 9 | { 10 | [DataMember(Order = 1)] 11 | public int id { get; set; } 12 | [DataMember(Order = 2)] 13 | public string? name { get; set; } 14 | [DataMember(Order = 3)] 15 | public string? category { get; set; } 16 | [DataMember(Order = 4)] 17 | public int data_type { get; set; } 18 | [DataMember(Order = 5)] 19 | public string? data_type_context { get; set; } 20 | [DataMember(Order = 6)] 21 | public string? description { get; set; } 22 | [DataMember(Order = 7)] 23 | public string? display_name { get; set; } 24 | [DataMember(Order = 8)] 25 | public int flags { get; set; } 26 | [DataMember(Order = 9)] 27 | public int display_precision { get; set; } 28 | [DataMember(Order = 10)] 29 | public string? forge_parameter_id { get; set; } 30 | } -------------------------------------------------------------------------------- /APSToolkit/Database/_objects_eav.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Runtime.Serialization; 4 | 5 | namespace APSToolkit.Database; 6 | // Copyright (c) chuongmep.com. All rights reserved 7 | 8 | public class _objects_eav 9 | { 10 | [DataMember(Order = 1)] 11 | public int id { get; set; } 12 | [DataMember(Order = 2)] 13 | public int entity_id { get; set; } 14 | [DataMember(Order = 3)] 15 | public int attribute_id { get; set; } 16 | [DataMember(Order = 4)] 17 | public int value_id { get; set; } 18 | 19 | } -------------------------------------------------------------------------------- /APSToolkit/DesignAutomation/Alias.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.DesignAutomation; 2 | 3 | public enum Alias 4 | { 5 | DEV, 6 | STG, 7 | PROD 8 | } -------------------------------------------------------------------------------- /APSToolkit/DesignAutomation/DAUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using Autodesk.Forge; 4 | 5 | namespace APSToolkit.DesignAutomation; 6 | 7 | /// 8 | /// Design Automation Utils 9 | /// 10 | public static class DAUtils 11 | { 12 | /// 13 | /// Check if the version is a composite design 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | public static async Task IsCompositeDesign(string token, string projectId, string versionId) 20 | { 21 | VersionsApi versionApi = new VersionsApi(); 22 | versionApi.Configuration.AccessToken = token; 23 | dynamic version = await versionApi.GetVersionAsync(projectId, versionId).ConfigureAwait(false); 24 | bool isDesign = version.data.attributes.extension.data.isCompositeDesign; 25 | return isDesign; 26 | } 27 | 28 | /// 29 | /// Return the Revit version of the model 30 | /// 31 | /// 32 | /// project id 33 | /// e.g: b.ca790fb5-141d-4ad5-b411-0461af2e9748 34 | /// e.g: urn:adsk.wipprod:fs.file:vf.N4upIOvMRByQDt1u8va4Bw?version=2 35 | /// 36 | public static async Task GetRevitVersionByVersionId(string token, string projectId, string versionId) 37 | { 38 | VersionsApi versionApi = new VersionsApi(); 39 | versionApi.Configuration.AccessToken = token; 40 | dynamic version = await versionApi.GetVersionAsync(projectId, versionId).ConfigureAwait(false); 41 | long revitVersion = version.data.attributes.extension.data.revitProjectVersion; 42 | // return enum match with revitversion like v2020, v2021, v2022,... . Revitversion is 2020, 2021, 2022,... 43 | return (Version) Enum.Parse(typeof(Version), $"v{revitVersion}"); 44 | } 45 | 46 | /// 47 | /// Get Revit version by itemid 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | public static async Task GetRevitVersionByItem(string token, string projectId, dynamic item) 54 | { 55 | VersionsApi versionApi = new VersionsApi(); 56 | versionApi.Configuration.AccessToken = token; 57 | string versionId = item.relationships.tip.data.id; 58 | dynamic version = await versionApi.GetVersionAsync(projectId, versionId).ConfigureAwait(false); 59 | long revitVersion = version.data.attributes.extension.data.revitProjectVersion; 60 | // return enum match with revitversion like v2020, v2021, v2022,... . Revitversion is 2020, 2021, 2022,... 61 | return (Version) Enum.Parse(typeof(Version), $"v{revitVersion}"); 62 | } 63 | } -------------------------------------------------------------------------------- /APSToolkit/DesignAutomation/DesignAutomateConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using Autodesk.Forge; 4 | 5 | namespace APSToolkit.DesignAutomation; 6 | 7 | public class DesignAutomateConfiguration 8 | { 9 | /// 10 | /// Name of Application 11 | /// 12 | public string AppName { get; set; } = "AppNameDemo"; 13 | 14 | // public string AppBundleName { get; set; } = "AppNameDemo.zip"; 15 | public string PackageZipPath { get; set; } 16 | public string Script { get; set; } 17 | public Engine Engine { get; set; } 18 | public Version Version { get; set; } = Version.v2022; 19 | public string EngineName => GetEngineName(); 20 | 21 | /// 22 | /// Default NickName is admin 23 | /// 24 | public string NickName { get; set; } = "admin"; 25 | 26 | public string BundleDescription { get; set; } = "Description for Bundle Name"; 27 | public string ActivityDescription { get; set; } = "Description for Activity Name"; 28 | public string AppBundleFullName => $"{NickName}.{AppName}+{Alias.ToString().ToLower()}"; 29 | 30 | public string ActivityName { get; set; } = "ActivityDemo"; 31 | public string ActivityFullName => $"{NickName}.{ActivityName}+{Alias.ToString().ToLower()}"; 32 | public Alias Alias { get; set; } = Alias.DEV; 33 | public string BucketOutputName => $"{AppName}_output"; 34 | public string ResultFileName { get; set; } = "result"; 35 | public string ResultFileExt { get; set; } = ".json"; 36 | public string ClientId { get; } 37 | public string ClientSecret { get; } 38 | 39 | public DesignAutomateConfiguration() 40 | { 41 | // set client id and client secret from environment variables 42 | ClientId = new Auth().GetClientId(); 43 | ClientSecret = new Auth().GetClientSecret(); 44 | } 45 | 46 | public DesignAutomateConfiguration(string clientId, string clientSecret) 47 | { 48 | ClientId = clientId; 49 | ClientSecret = clientSecret; 50 | } 51 | 52 | private string GetEngineName() 53 | { 54 | string version = ((int) Version).ToString(); 55 | switch (Engine) 56 | { 57 | case Engine.AutoCAD: 58 | return $"Autodesk.AutoCAD+{version}"; 59 | case Engine.Inventor: 60 | return $"Autodesk.Inventor+{version}"; 61 | case Engine.Revit: 62 | return $"Autodesk.Revit+{version}"; 63 | } 64 | 65 | return string.Empty; 66 | } 67 | } -------------------------------------------------------------------------------- /APSToolkit/DesignAutomation/Engine.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.DesignAutomation; 4 | 5 | public enum Engine 6 | { 7 | AutoCAD = 1, 8 | Inventor = 2, 9 | Revit = 3, 10 | Fusion = 4, 11 | } 12 | public enum Version 13 | { 14 | v2020 = 2020, 15 | v2021 = 2021, 16 | v2022 = 2022, 17 | v2023 = 2023, 18 | v2024 = 2024, 19 | v2025 = 2025, 20 | } -------------------------------------------------------------------------------- /APSToolkit/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base 2 | WORKDIR /app 3 | 4 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build 5 | WORKDIR /src 6 | COPY ["APSToolkit/APSToolkit.csproj", "APSToolkit/"] 7 | RUN dotnet restore "APSToolkit/APSToolkit.csproj" 8 | COPY . . 9 | WORKDIR "/src/APSToolkit" 10 | RUN dotnet build "APSToolkit.csproj" -c Release -o /app/build 11 | 12 | FROM build AS publish 13 | RUN dotnet publish "APSToolkit.csproj" -c Release -o /app/publish /p:UseAppHost=false 14 | 15 | FROM base AS final 16 | WORKDIR /app 17 | COPY --from=publish /app/publish . 18 | ENTRYPOINT ["dotnet", "APSToolkit.dll"] 19 | -------------------------------------------------------------------------------- /APSToolkit/ForgeToolkit.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | Library -------------------------------------------------------------------------------- /APSToolkit/Fragments.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Piro - Piro CIE. All rights reserved 2 | 3 | using System.Diagnostics; 4 | using APSToolkit.Schema; 5 | 6 | namespace APSToolkit 7 | { 8 | public class Fragments 9 | { 10 | /// 11 | /// Parses fragments from a binary buffer, typically stored in a file called 'FragmentList.pf'. 12 | /// 13 | /// The binary buffer containing fragment information. 14 | /// An array of objects representing parsed SVF fragments. 15 | /// 16 | /// This method reads fragment information from a binary buffer, such as the one stored in a 'FragmentList.pf' file. 17 | /// - The buffer parameter should contain binary data representing SVF fragments. 18 | /// - The method parses the buffer to extract fragment details, including visibility, material ID, geometry ID, transform, bounding box, and database ID. 19 | /// - The parsed fragments are returned as an array of ISvfFragment objects. 20 | /// 21 | public static ISvfFragment[] ParseFragments(byte[] buffer) 22 | { 23 | List fragments = new List(); 24 | PackFileReader pfr = new PackFileReader(buffer); 25 | 26 | for (int i = 0, len = pfr.NumEntries(); i < len; i++) 27 | { 28 | ISvfManifestType? entryType = pfr.SeekEntry(i); 29 | Debug.Assert(entryType != null); 30 | Debug.Assert(entryType?.version > 4); 31 | 32 | byte flags = pfr.GetUint8(); 33 | bool visible = (flags & 0x01) != 0; 34 | int materialId = pfr.GetVarint(); 35 | int geometryId = pfr.GetVarint(); 36 | ISvfTransform? transform = pfr.GetTransform(); 37 | float[] bbox = new float[6] { 0, 0, 0, 0, 0, 0 }; 38 | float[] bboxOffset = new float[3] { 0, 0, 0 }; 39 | if (entryType?.version > 3) 40 | { 41 | if (transform != null && transform?.t != null) 42 | { 43 | bboxOffset[0] = (float)transform?.t.X; 44 | bboxOffset[1] = (float)transform?.t.Y; 45 | bboxOffset[2] = (float)transform?.t.Z; 46 | } 47 | } 48 | 49 | for (int j = 0; j < 6; j++) 50 | { 51 | bbox[j] = pfr.GetFloat32() + bboxOffset[j % 3]; 52 | } 53 | 54 | int dbId = pfr.GetVarint(); 55 | 56 | ISvfFragment fragment = new ISvfFragment() 57 | { 58 | visible = visible, 59 | materialID = materialId, 60 | geometryID = geometryId, 61 | dbID = dbId, 62 | transform = transform, 63 | bbox = bbox 64 | }; 65 | fragments.Add(fragment); 66 | } 67 | 68 | return fragments.ToArray(); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /APSToolkit/Geometries.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Piro - Piro CIE. All rights reserved 2 | 3 | using System.Diagnostics; 4 | using APSToolkit.Schema; 5 | 6 | namespace APSToolkit 7 | { 8 | public class Geometries 9 | { 10 | /// 11 | /// Parses geometries from a binary buffer, typically stored in a file called 'GeometryMetadata.pf', 12 | /// which is referenced in the SVF manifest as an asset of type 'Autodesk.CloudPlatform.GeometryMetadataList'. 13 | /// 14 | /// The binary buffer containing geometry metadata information. 15 | /// An array of objects representing parsed SVF geometry metadata. 16 | /// 17 | /// This method reads geometry metadata information from a binary buffer, such as the one stored in a 'GeometryMetadata.pf' file. 18 | /// - The buffer parameter should contain binary data representing SVF geometry metadata. 19 | /// - The method parses the buffer to extract geometry details, including fragment type, primitive count, pack ID, and entity ID. 20 | /// - The parsed geometries are returned as an array of ISvfGeometryMetadata objects. 21 | /// 22 | public static ISvfGeometryMetadata[] ParseGeometries(byte[] buffer) 23 | { 24 | List geometries = new List(); 25 | 26 | PackFileReader pfr = new PackFileReader(buffer); 27 | for (int i = 0, len = pfr.NumEntries(); i < len; i++) 28 | { 29 | ISvfManifestType? entry = pfr.SeekEntry(i); 30 | Debug.Assert(entry != null); 31 | Debug.Assert(entry?.version >= 3); 32 | 33 | byte fragType = pfr.GetUint8(); 34 | // Skip past object space bbox -- we don't use that 35 | pfr.Seek(pfr.Offset + 24); 36 | ushort primCount = pfr.GetUint16(); 37 | string pId = pfr.GetString(pfr.GetVarint()).Replace(".pf", ""); 38 | int packId = Int32.Parse(pId); 39 | int entityId = pfr.GetVarint(); 40 | 41 | ISvfGeometryMetadata geometry = new ISvfGeometryMetadata() 42 | { 43 | fragType = fragType, 44 | primCount = primCount, 45 | packID = packId, 46 | entityID = entityId 47 | }; 48 | 49 | geometries.Add(geometry); 50 | } 51 | 52 | return geometries.ToArray(); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /APSToolkit/InputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Piro - Piro CIE. All rights reserved 2 | // This code is made from the package Forge-Convert-Utils by Petr Broz (Autodesk) 3 | // Most parts of this code are Typescript -> C# adaptation 4 | 5 | namespace APSToolkit 6 | { 7 | public class InputStream 8 | { 9 | protected byte[] Buffer; 10 | protected int MOffset; 11 | protected int MLength; 12 | 13 | public int Offset 14 | { 15 | get { return MOffset; } 16 | set { MOffset = value; } 17 | } 18 | 19 | public int Length 20 | { 21 | get { return MLength; } 22 | set { MLength = value; } 23 | } 24 | 25 | public InputStream(byte[] buffer) 26 | { 27 | Buffer = buffer; 28 | Offset = 0; 29 | Length = Buffer.Length; 30 | } 31 | 32 | public void Seek(int offset) 33 | { 34 | Offset = offset; 35 | } 36 | 37 | public byte GetUint8() 38 | { 39 | var val = Buffer[Offset]; 40 | Offset += 1; 41 | return val; 42 | } 43 | 44 | public ushort GetUint16() 45 | { 46 | var val = BitConverter.ToUInt16(Buffer, Offset); 47 | Offset += 2; 48 | return val; 49 | } 50 | 51 | public short GetInt16() 52 | { 53 | var val = BitConverter.ToInt16(Buffer, Offset); 54 | Offset += 2; 55 | return val; 56 | } 57 | 58 | public uint GetUint32() 59 | { 60 | var val = BitConverter.ToUInt32(Buffer, Offset); 61 | Offset += 4; 62 | return val; 63 | } 64 | 65 | public int GetInt32() 66 | { 67 | var val = BitConverter.ToInt32(Buffer, Offset); 68 | Offset += 4; 69 | return val; 70 | } 71 | 72 | public float GetFloat32() 73 | { 74 | var val = BitConverter.ToSingle(Buffer, Offset); 75 | Offset += 4; 76 | return val; 77 | } 78 | 79 | public double GetFloat64() 80 | { 81 | var val = BitConverter.ToDouble(Buffer, Offset); 82 | Offset += 8; 83 | return val; 84 | } 85 | 86 | public int GetVarint() 87 | { 88 | byte @byte; 89 | int val = 0; 90 | int shift = 0; 91 | do 92 | { 93 | @byte = Buffer[Offset++]; 94 | val |= (@byte & 0x7f) << shift; 95 | shift += 7; 96 | } while ((@byte & 0x80) != 0); 97 | 98 | return val; 99 | } 100 | 101 | public string GetString(int len) 102 | { 103 | var val = System.Text.Encoding.UTF8.GetString(Buffer, Offset, len); 104 | Offset += len; 105 | return val; 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /APSToolkit/ManifestItem.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit; 2 | 3 | public class ManifestItem 4 | { 5 | public string Guid { get; set; } 6 | public string MIME { get; set; } 7 | public PathInfo Path { get; set; } 8 | } -------------------------------------------------------------------------------- /APSToolkit/PathInfo.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit; 2 | 3 | public class PathInfo 4 | { 5 | public string RootFileName { get; set; } 6 | public string LocalPath { get; set; } 7 | public string BasePath { get; set; } 8 | public string Urn { get; set; } 9 | public List Files { get; set; } 10 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/AssetType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Newtonsoft.Json; 3 | 4 | namespace APSToolkit.Schema; 5 | 6 | 7 | [JsonConverter(typeof(ForceDefaultConverter))] 8 | public enum AssetType 9 | { 10 | [EnumMember(Value = "Autodesk.CloudPlatform.Image")] 11 | Image, 12 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyViewables")] 13 | PropertyViewables, 14 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyOffsets")] 15 | PropertyOffsets, 16 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyAttributes")] 17 | PropertyAttributes, 18 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyValues")] 19 | PropertyValues, 20 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyIDs")] 21 | PropertyIDs, 22 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyAVs")] 23 | PropertyAVs, 24 | [EnumMember(Value = "Autodesk.CloudPlatform.PropertyRCVs")] 25 | PropertyRCVs, 26 | [EnumMember(Value = "ProteinMaterials")] 27 | ProteinMaterials, 28 | [EnumMember(Value = "Autodesk.CloudPlatform.PackFile")] 29 | PackFile, 30 | [EnumMember(Value = "Autodesk.CloudPlatform.FragmentList")] 31 | FragmentList, 32 | [EnumMember(Value = "Autodesk.CloudPlatform.GeometryMetadataList")] 33 | GeometryMetadataList, 34 | [EnumMember(Value = "Autodesk.CloudPlatform.InstanceTree")] 35 | InstanceTree, 36 | [EnumMember(Value = "Autodesk.CloudPlatform.ViewingMetadata")] 37 | ViewingMetadata, 38 | [EnumMember(Value = "Topology")] 39 | Topology 40 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ForceDefaultConverter.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | public class ForceDefaultConverter : JsonConverter 6 | { 7 | public override bool CanRead => false; 8 | public override bool CanWrite => false; 9 | 10 | public override bool CanConvert(Type objectType) 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | 15 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | 20 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfContent.cs: -------------------------------------------------------------------------------- 1 | using APSToolkit.Database; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | public struct ISvfContent 6 | { 7 | public ISvfMetadata metadata { get; set; } 8 | public ISvfFragment[] fragments { get; set; } 9 | public ISvfGeometryMetadata[] geometries { get; set; } 10 | public IMeshPack[][] meshpacks { get; set; } 11 | public ISvfMaterial?[] materials { get; set; } 12 | public PropDbReader properties { get; set; } 13 | public Dictionary images { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfFragment.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Fragment represents a single scene object, 5 | /// linking together material, geometry, and database IDs, 6 | /// and providing world transform and bounding box on top of that. 7 | /// 8 | public struct ISvfFragment 9 | { 10 | public bool visible { get; set; } 11 | public int materialID { get; set; } 12 | public int geometryID { get; set; } 13 | public int dbID { get; set; } 14 | public ISvfTransform? transform { get; set; } 15 | public float[] bbox { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfGeometryMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Lightweight data structure pointing to a mesh in a specific packfile and entry. 5 | /// Contains additional information about the type of mesh and its primitive count. 6 | /// 7 | public struct ISvfGeometryMetadata 8 | { 9 | public byte fragType { get; set; } 10 | public ushort primCount { get; set; } 11 | public int packID { get; set; } 12 | public int entityID { get; set; } 13 | public int topoID { get; set; } 14 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfLines.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Line segment data. 5 | /// 6 | public struct ISvfLines : IMeshPack 7 | { 8 | public bool isLines { get; set; } 9 | public int vcount { get; set; } 10 | public int lcount { get; set; } 11 | public float[] vertices { get; set; } 12 | public ushort[] indices { get; set; } 13 | public float[] colors { get; set; } 14 | public float lineWidth { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfManifest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | 6 | /// 7 | /// Top-level manifest containing URIs and types of all assets 8 | /// referenced by or embedded in a specific SVF file. 9 | /// The URIs are typically relative to the SVF file itself. 10 | /// 11 | public struct ISvfManifest 12 | { 13 | 14 | [JsonProperty("name")] 15 | public string name { get; set; } 16 | 17 | [JsonProperty("manifestversion")] 18 | public int manifestversion { get; set; } 19 | 20 | [JsonProperty("toolkitversion")] 21 | public string toolkitversion { get; set; } 22 | 23 | [JsonProperty("assets")] 24 | public List assets { get; set; } 25 | 26 | [JsonProperty("typesets")] 27 | public List typesets { get; set; } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfManifestAsset.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | 6 | /// 7 | /// Description of a specific asset referenced by or embedded in an SVF, 8 | /// including the URI, compressed and uncompressed size, type of the asset itself, 9 | /// and types of all entities inside the asset. 10 | /// 11 | public struct ISvfManifestAsset 12 | { 13 | [JsonProperty("id")] 14 | public string id { get; set; } 15 | 16 | [JsonProperty("type")] 17 | public AssetType type { get; set; } 18 | 19 | [JsonProperty("typeset")] 20 | public string typeset { get; set; } 21 | 22 | [JsonProperty("URI")] 23 | public string URI { get; set; } 24 | 25 | [JsonProperty("size")] 26 | public int size { get; set; } 27 | 28 | [JsonProperty("usize")] 29 | public int usize { get; set; } 30 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfManifestType.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | /// 6 | /// Single type definition 7 | /// 8 | public struct ISvfManifestType 9 | { 10 | [JsonProperty("class")] 11 | public string typeClass { get; set; } 12 | 13 | [JsonProperty("type")] 14 | public string type { get; set; } 15 | 16 | [JsonProperty("version")] 17 | public int version { get; set; } 18 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfManifestTypeSet.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | /// 6 | /// Collection of type definitions. 7 | /// 8 | public struct ISvfManifestTypeSet 9 | { 10 | [JsonProperty("id")] 11 | public string id { get; set; } 12 | 13 | [JsonProperty("types")] 14 | public List types { get; set; } 15 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterial.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterial 4 | { 5 | public float[] diffuse { get; set; } 6 | public float[] specular { get; set; } 7 | public float[] ambient { get; set; } 8 | public float[] emissive { get; set; } 9 | public float? glossiness { get; set; } 10 | public float? reflectivity { get; set; } 11 | public float? opacity { get; set; } 12 | public bool? metal { get; set; } 13 | 14 | public ISvfMaterialMaps? maps { get; set; } 15 | 16 | //second part of the material defined in the material class 17 | public string tag { get; set; } 18 | public string proteinType { get; set; } 19 | public string definition { get; set; } 20 | public bool transparent { get; set; } 21 | public string[] keywords { get; set; } 22 | public string[] categories { get; set; } 23 | public ISvfMaterialProperties properties { get; set; } 24 | public Dictionary textures { get; set; } 25 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterialGroup.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterialGroup 4 | { 5 | public int version { get; set; } 6 | public string[] userassets { get; set; } 7 | public Dictionary materials { get; set; } 8 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterialMap.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterialMap 4 | { 5 | public string uri { get; set; } 6 | public ISvfMaterialMapScale scale { get; set; } 7 | } 8 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterialMapScale.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterialMapScale 4 | { 5 | public float texture_UScale { get; set; } 6 | public float texture_VScale { get; set; } 7 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterialMaps.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterialMaps 4 | { 5 | public ISvfMaterialMap? diffuse { get; set; } 6 | public ISvfMaterialMap? specular { get; set; } 7 | public ISvfMaterialMap? normal { get; set; } 8 | public ISvfMaterialMap? bump { get; set; } 9 | public ISvfMaterialMap? alpha { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterialProperties.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterialProperties 4 | { 5 | public Dictionary integers { get; set; } 6 | public Dictionary booleans { get; set; } 7 | public Dictionary strings { get; set; } 8 | public Dictionary uris { get; set; } 9 | public Dictionary scalars { get; set; } 10 | public Dictionary colors { get; set; } 11 | public Dictionary choicelists { get; set; } 12 | public Dictionary uuids { get; set; } 13 | public string references { get; set; } //type TODO 14 | 15 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMaterials.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ISvfMaterials 4 | { 5 | public string name { get; set; } 6 | public string version { get; set; } 7 | public Dictionary scene { get; set; } 8 | public Dictionary materials { get; set; } 9 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMesh.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Interface to group ISvfMesh, ISvfLines and ISvfPoint 5 | /// 6 | public interface IMeshPack { } 7 | 8 | /// 9 | /// Triangular mesh data, including indices, vertices, optional normals and UVs. 10 | /// 11 | public struct ISvfMesh : IMeshPack 12 | { 13 | public int vcount { get; set; } 14 | public int tcount { get; set; } 15 | public int uvcount { get; set; } 16 | public int attrs { get; set; } 17 | public int flags { get; set; } 18 | public string comment { get; set; } 19 | public List uvmaps { get; set; } 20 | public uint[] indices { get; set; } 21 | public float[] vertices { get; set; } 22 | public float[] normals { get; set; } 23 | public float[] colors { get; set; } 24 | public System.Numerics.Vector3 min { get; set; } 25 | public System.Numerics.Vector3 max { get; set; } 26 | } 27 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfMetadata.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | 6 | /// 7 | /// Additional metadata for SVF such as the definition of "up" vector, 8 | /// default background, etc. 9 | /// 10 | public struct ISvfMetadata 11 | { 12 | [JsonProperty("version")] 13 | public string version { get; set; } 14 | 15 | [JsonProperty("metadata")] 16 | public Dictionary metadata { get; set; } 17 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfPoints.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Point cloud data. 5 | /// 6 | public struct ISvfPoints : IMeshPack 7 | { 8 | public bool isPoints { get; set; } 9 | public int vcount { get; set; } 10 | public float[] vertices { get; set; } 11 | public float[] colors { get; set; } 12 | public float pointSize { get; set; } 13 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfRoot.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Parsed content of an actual *.svf file. 5 | /// 6 | public struct ISvfRoot 7 | { 8 | public ISvfManifest manifest { get; set; } 9 | public ISvfMetadata metadata { get; set; } 10 | public Dictionary embedded { get; set; } 11 | } 12 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfTransform.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | namespace APSToolkit.Schema; 4 | 5 | public struct ISvfTransform 6 | { 7 | public System.Numerics.Vector3 t { get; set; } 8 | public System.Numerics.Vector3 s { get; set; } 9 | public Quaternion q { get; set; } 10 | public double[] matrix { get; set; } 11 | } 12 | -------------------------------------------------------------------------------- /APSToolkit/Schema/ISvfUVMap.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// Single UV channel. IMesh can have more of these. 5 | /// 6 | public struct ISvfUVMap 7 | { 8 | public string name { get; set; } 9 | public string file { get; set; } 10 | public float[] uvs { get; set; } 11 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/IntValues.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct IntValues 4 | { 5 | public int[] values { get; set; } 6 | } 7 | -------------------------------------------------------------------------------- /APSToolkit/Schema/RGBA.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct RGBA 4 | { 5 | public float r { get; set; } 6 | public float g { get; set; } 7 | public float b { get; set; } 8 | public float a { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /APSToolkit/Schema/RGBValuesAndStringConnections.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct RGBValuesAndStringConnections 4 | { 5 | public List values { get; set; } 6 | public string[] connections { get; set; } 7 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/StringConnections.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct StringConnections 4 | { 5 | public string[] connections { get; set; } 6 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/StringValues.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | /// 4 | /// A few predefined types to easily deserialize the json using classes 5 | /// 6 | 7 | public struct StringValues 8 | { 9 | public string[] values { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /APSToolkit/Schema/UnitsAndNumberValues.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct UnitsAndNumberValues 4 | { 5 | public string units { get; set; } 6 | public float[] values { get; set; } 7 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/ValueObj.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct ValueObj 4 | { 5 | public object value { get; set; } 6 | } -------------------------------------------------------------------------------- /APSToolkit/Schema/XYZArray.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkit.Schema; 2 | 3 | public struct XYZArray 4 | { 5 | public float[] XYZ { get; set; } 6 | } -------------------------------------------------------------------------------- /APSToolkit/SvfReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Piro - Piro CIE. All rights reserved 2 | 3 | using APSToolkit.Schema; 4 | 5 | namespace APSToolkit 6 | { 7 | public class SvfReader 8 | { 9 | /// 10 | /// Reads SVF (Simple Vector Format) from the local file system. 11 | /// 12 | /// The path to the main SVF file. 13 | /// A Reader instance for accessing SVF data. 14 | /// 15 | /// This method reads SVF data from the local file system, allowing for further processing or visualization. 16 | /// - The svfPath parameter should point to the main SVF file. 17 | /// - The method automatically resolves and reads additional SVF-related files from the same folder. 18 | /// - The returned Reader instance provides methods to access and process SVF data. 19 | /// 20 | private static Reader ReadFromFileSystem(string svfPath) 21 | { 22 | string? svfFolderPath = Path.GetDirectoryName(svfPath); 23 | 24 | System.Func resolve = (uri) => { 25 | var buffer = File.ReadAllBytes(Path.Combine(svfFolderPath, uri)); 26 | return buffer; 27 | }; 28 | return new Reader(svfPath, resolve); 29 | } 30 | 31 | 32 | /// 33 | /// Reads SVF (Simple Vector Format) content from a local file. 34 | /// 35 | /// The path to the main SVF file. 36 | /// An object representing the SVF content. 37 | /// 38 | /// This method reads SVF content from a local file, allowing for further processing or visualization. 39 | /// - The _svfModelPath parameter should point to the main SVF file. 40 | /// - The method uses a Reader to access and process SVF data from the specified file. 41 | /// - The returned ISvfContent object represents the parsed SVF content. 42 | /// 43 | public static ISvfContent ReadSvf(string _svfModelPath) 44 | { 45 | Reader reader = ReadFromFileSystem(_svfModelPath); 46 | return reader.read(); 47 | } 48 | 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /APSToolkit/Token.cs: -------------------------------------------------------------------------------- 1 | using Autodesk.Forge; 2 | 3 | namespace APSToolkit; 4 | 5 | public class Token 6 | { 7 | public Token(string? accessToken, string? tokenType, long expiresIn, string refreshToken) :this() 8 | { 9 | this.AccessToken = accessToken; 10 | this.TokenType = tokenType; 11 | this.ExpiresIn = expiresIn; 12 | this.RefreshToken = refreshToken; 13 | } 14 | 15 | public Token() 16 | { 17 | 18 | } 19 | // map with access_token 20 | [System.Text.Json.Serialization.JsonPropertyName("access_token")] 21 | public string? AccessToken { get; set; } 22 | [System.Text.Json.Serialization.JsonPropertyName("token_type")] 23 | public string? TokenType { get; set; } 24 | [System.Text.Json.Serialization.JsonPropertyName("expires_in")] 25 | public long? ExpiresIn { get; set; } 26 | 27 | [System.Text.Json.Serialization.JsonPropertyName("refresh_token")] 28 | public string? RefreshToken { get; set; } 29 | 30 | /// 31 | /// Retrieves a 2-legged access token from the Autodesk Forge API using client credentials. 32 | /// The retrieved token's access_token, token_type, and expires_in properties are then set to the corresponding properties of the Token instance. 33 | /// Returns the Token instance. 34 | /// 35 | public Token Refresh2LegToken() 36 | { 37 | var auth = new Auth(); 38 | Token? token = auth.Get2LeggedToken().Result; 39 | this.AccessToken = token.AccessToken; 40 | this.TokenType = token.TokenType; 41 | this.ExpiresIn = token.ExpiresIn; 42 | return this; 43 | } 44 | 45 | /// 46 | /// Refreshes a 3-legged access token from the Autodesk Forge API using the refresh token grant type. 47 | /// The method specifies an array of scopes for the refreshed token. 48 | /// The retrieved token's access_token, token_type, expires_in, and refresh_token properties are then set to the corresponding properties of the Token instance. 49 | /// Returns the Token instance. 50 | /// 51 | public Token Refresh3LegToken() 52 | { 53 | Scope[] scopes = new Scope[] 54 | { 55 | Scope.DataRead, Scope.DataWrite, Scope.DataCreate, Scope.DataSearch, Scope.BucketCreate, 56 | Scope.BucketRead, Scope.CodeAll, 57 | Scope.BucketUpdate, Scope.BucketDelete 58 | }; 59 | Token token = Auth.Refresh3LeggedToken(scopes).Result; 60 | this.AccessToken = token.AccessToken; 61 | this.TokenType = token.TokenType; 62 | this.ExpiresIn = token.ExpiresIn; 63 | this.RefreshToken = token.RefreshToken; 64 | return this; 65 | } 66 | /// 67 | /// Checks if the token has expired. 68 | /// 69 | /// 70 | /// 71 | public bool IsExpired(double bufferMinutes=0) 72 | { 73 | var currentUnixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); 74 | if (currentUnixTime + bufferMinutes*60 >= this.ExpiresIn) 75 | { 76 | return true; 77 | } 78 | return false; 79 | } 80 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/Base64Convert.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | namespace APSToolkit.Utils; 4 | 5 | public static class Base64Convert 6 | { 7 | public static string ToBase64String(string input) 8 | { 9 | var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(input); 10 | string base64String = System.Convert.ToBase64String(plainTextBytes); 11 | // replace the + and / characters with - and _ characters 12 | base64String = base64String.Replace('+', '-'); 13 | base64String = base64String.Replace('/', '_'); 14 | return base64String; 15 | } 16 | public static string FromBase64String(string input) 17 | { 18 | // replace the - and _ characters with + and / characters 19 | input = input.Replace('-', '+'); 20 | input = input.Replace('_', '/'); 21 | var base64EncodedBytes = System.Convert.FromBase64String(input); 22 | return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); 23 | } 24 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/DataFrame.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ChoETL; 3 | 4 | namespace APSToolkit.Utils; 5 | 6 | public static class DataFrame 7 | { 8 | 9 | /// 10 | /// Loads a DataFrame from a DataTable. 11 | /// 12 | /// The DataTable to be converted into a DataFrame. 13 | /// A DataFrame that represents the provided DataTable. 14 | public static Microsoft.Data.Analysis.DataFrame LoadFromDataTable(DataTable dataTable) 15 | { 16 | Microsoft.Data.Analysis.DataFrame dataFrame = dataTable.ToDataFrame(); 17 | return dataFrame; 18 | } 19 | 20 | /// 21 | /// Loads a DataFrame from a Parquet file. 22 | /// 23 | /// The path to the Parquet file. 24 | /// A DataFrame that represents the data in the Parquet file. 25 | public static Microsoft.Data.Analysis.DataFrame LoadFromParquet(string filePath) 26 | { 27 | using (var r = new ChoParquetReader(filePath)) 28 | { 29 | var dataFrame = r.AsDataTable(); 30 | return dataFrame.ToDataFrame(); 31 | } 32 | } 33 | 34 | /// 35 | /// Loads a DataFrame from a Parquet file represented as a byte array. 36 | /// 37 | /// The byte array representing the Parquet file. 38 | /// A DataFrame that represents the data in the Parquet file. 39 | public static Microsoft.Data.Analysis.DataFrame LoadFromParquet(byte[] stream) 40 | { 41 | Stream s = new MemoryStream(stream); 42 | using (var r = new ChoParquetReader(s)) 43 | { 44 | var dataFrame = r.AsDataTable(); 45 | return dataFrame.ToDataFrame(); 46 | } 47 | } 48 | 49 | /// 50 | /// Loads a DataFrame from an Excel file. 51 | /// 52 | /// The path to the Excel file. 53 | /// The name of the sheet in the Excel file to load. 54 | /// A DataFrame that represents the data in the specified sheet of the Excel file. 55 | public static Microsoft.Data.Analysis.DataFrame LoadFromExcel(string filePath, string sheetName) 56 | { 57 | DataTable dt = ExcelUtils.ReadDataFromExcelToDataTable(filePath, sheetName); 58 | return dt.ToDataFrame(); 59 | } 60 | 61 | public static void ExportToExcel(Microsoft.Data.Analysis.DataFrame dataFrame,string filePath, string sheetName) 62 | { 63 | DataTable dt = dataFrame.ToTable(); 64 | dt.ExportDataToExcel(filePath, sheetName); 65 | } 66 | public static void ExportToCsv(Microsoft.Data.Analysis.DataFrame dataFrame,string filePath) 67 | { 68 | DataTable dt = dataFrame.ToTable(); 69 | dt.ExportToCsv(filePath); 70 | } 71 | public static void ExportToParquet(Microsoft.Data.Analysis.DataFrame dataFrame,string filePath) 72 | { 73 | DataTable dt = dataFrame.ToTable(); 74 | dt.ExportToParquet(filePath); 75 | } 76 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/DiscordWebhook.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using RestSharp; 4 | 5 | namespace APSToolkit.Utils; 6 | 7 | public class DiscordWebhook 8 | { 9 | public string username { get; set; } 10 | public string avatar_url { get; set; } 11 | public string content { get; set; } 12 | 13 | public void SendReport(string webHookUrl,string title, string content) 14 | { 15 | var client = new RestClient(webHookUrl); 16 | var request = new RestRequest() {Method = Method.Post}; 17 | DiscordWebhook discordWebhook = new DiscordWebhook() 18 | { 19 | content = content, 20 | username = title 21 | }; 22 | // add raw content json with {content: "{content}"}' 23 | request.AddJsonBody(discordWebhook); 24 | client.ExecuteAsync(request); 25 | } 26 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/EnumRecords.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using APSToolkit.Database; 4 | 5 | namespace APSToolkit.Utils; 6 | 7 | public static class EnumRecords 8 | { 9 | /// 10 | /// Converts an integer value to the corresponding DataType enum value. 11 | /// 12 | /// The integer value representing the data type. 13 | /// The DataType enum value. 14 | /// 15 | /// If the provided integer value does not match any enum value, DataType.Unknown is returned. 16 | /// 17 | public static DataType GetDataType(int value) 18 | { 19 | if (Enum.IsDefined(typeof(DataType), value)) 20 | { 21 | return (DataType) value; 22 | } 23 | 24 | // Handle the case where the value does not match any enum value. 25 | return DataType.Unknown; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/GzipUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using OfficeOpenXml.Packaging.Ionic.Zlib; 4 | 5 | namespace APSToolkit.Utils; 6 | 7 | public static class GzipUtils 8 | { 9 | /// 10 | /// Unzips a Gzip-compressed file and returns the decompressed content as a string. 11 | /// 12 | /// The file path of the Gzip-compressed file. 13 | /// The decompressed content as a string. 14 | public static string UnzipGzip(string gzipPath) 15 | { 16 | using (FileStream fs = new FileStream(gzipPath, FileMode.Open)) 17 | { 18 | using (GZipStream gzipStream = new GZipStream(fs, CompressionMode.Decompress)) 19 | { 20 | using (StreamReader reader = new StreamReader(gzipStream)) 21 | { 22 | string json = reader.ReadToEnd(); 23 | return json; 24 | } 25 | } 26 | } 27 | } 28 | 29 | /// 30 | /// Compresses a file using Gzip and returns the path of the compressed file. 31 | /// 32 | /// The file path of the file to be compressed. 33 | /// The path of the compressed file. 34 | public static string ZipFile(string filePath) 35 | { 36 | string gzipPath = filePath + ".gz"; 37 | using (FileStream fs = new FileStream(filePath, FileMode.Open)) 38 | { 39 | using (FileStream gzipStream = File.Create(gzipPath)) 40 | { 41 | using (GZipStream gzip = new GZipStream(gzipStream, CompressionMode.Compress)) 42 | { 43 | fs.CopyTo(gzip); 44 | } 45 | } 46 | } 47 | 48 | return gzipPath; 49 | } 50 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/LogUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using RestSharp; 4 | using Serilog; 5 | using Serilog.Events; 6 | 7 | namespace APSToolkit.Utils; 8 | 9 | public static class LogUtils 10 | { 11 | private static string DirPath = Path.Combine(Path.GetTempPath(), "ForgeToolkit"); 12 | private static string LogName = "ForgeToolkit"+DateTime.Now.ToString("yyyyMMdd")+".log"; 13 | private static string LogPath 14 | { 15 | get 16 | { 17 | if (!Directory.Exists(DirPath)) 18 | { 19 | Directory.CreateDirectory(DirPath); 20 | } 21 | return Path.Combine(DirPath, LogName); 22 | } 23 | } 24 | public static void Info(string message) 25 | { 26 | // set log path 27 | using var log = new LoggerConfiguration() 28 | .WriteTo.Console() 29 | .WriteTo.File(LogPath,LogEventLevel.Information) 30 | .CreateLogger(); 31 | log.Information(message); 32 | } 33 | public static void Error(string message) 34 | { 35 | // set log path 36 | using var log = new LoggerConfiguration() 37 | .WriteTo.Console() 38 | .WriteTo.File(LogPath,LogEventLevel.Information) 39 | .CreateLogger(); 40 | log.Error(message); 41 | } 42 | /// 43 | /// Write report to console from report url 44 | /// 45 | /// 46 | public static string? WriteConsoleWorkItemReport(string reportUrl) 47 | { 48 | var client = new RestClient(reportUrl); 49 | var request = new RestRequest() {Method = Method.Get}; 50 | var response = client.Execute(request); 51 | if (response.IsSuccessful) 52 | { 53 | string? report = response.Content; 54 | Console.WriteLine(report); 55 | return report; 56 | } 57 | Console.WriteLine("Error: " + response.ErrorMessage); 58 | return string.Empty; 59 | } 60 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/RecordUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Data; 4 | using ConsoleTables; 5 | 6 | namespace APSToolkit.Utils; 7 | 8 | public static class RecordUtils 9 | { 10 | /// 11 | /// Writes records in CSV format to the console, including the title column. 12 | /// 13 | /// The type of the records. 14 | /// The IEnumerable collection of records to be written. 15 | /// 16 | /// This extension method utilizes ConsoleTable to format and display records in CSV format 17 | /// with the title column included. The records are written to the console using Markdown formatting. 18 | /// 19 | public static void WriteConsoleRecord(this IEnumerable record) where T : class 20 | { 21 | // write record like csv format to console include title column 22 | // query.ToList().WriteConsoleRecord(); 23 | ConsoleTable 24 | .From(record) 25 | .Configure(o => o.NumberAlignment = Alignment.Left) 26 | .Configure(o => o.EnableCount = true) 27 | .Configure(o => o.OutputTo = Console.Out) 28 | .Write(Format.MarkDown); 29 | } 30 | 31 | /// 32 | /// Writes a DataTable to the console in a tabular format with Markdown formatting. 33 | /// 34 | /// The DataTable to be written to the console. 35 | /// 36 | /// This extension method converts the DataTable to a ConsoleTable and formats it with Markdown 37 | /// before displaying it on the console. The formatting includes left-aligned numbers and enables 38 | /// counting rows. The resulting table is output to the console. 39 | /// 40 | public static void WriteConsoleRecord(this DataTable record) 41 | { 42 | // convert to list enumerable from datatable 43 | ConsoleTable consoleTable = From(record); 44 | consoleTable 45 | .Configure(o => o.NumberAlignment = Alignment.Left) 46 | .Configure(o => o.EnableCount = true) 47 | .Configure(o => o.OutputTo = Console.Out) 48 | .Write(Format.MarkDown); 49 | } 50 | 51 | /// 52 | /// Converts a DataTable to a ConsoleTable for tabular formatting. 53 | /// 54 | /// The DataTable to be converted to a ConsoleTable. 55 | /// A ConsoleTable representing the tabular structure of the DataTable. 56 | /// 57 | /// This method creates a ConsoleTable and populates it with columns from the DataTable's 58 | /// DataColumn collection. It then adds rows to the table, converting byte array columns to 59 | /// Base64 strings for display. The resulting ConsoleTable represents the tabular structure 60 | /// of the DataTable. 61 | /// 62 | private static ConsoleTable From(DataTable dataTable) 63 | { 64 | var table = new ConsoleTable(); 65 | 66 | var columns = dataTable.Columns 67 | .Cast() 68 | .Select(x => x.ColumnName) 69 | .ToList(); 70 | 71 | table.AddColumn(columns); 72 | 73 | foreach (DataRow row in dataTable.Rows) 74 | { 75 | var items = row.ItemArray.Select(x => x is byte[] data ? Convert.ToBase64String(data) : x.ToString()) 76 | .ToArray(); 77 | table.AddRow(items); 78 | } 79 | 80 | return table; 81 | } 82 | } -------------------------------------------------------------------------------- /APSToolkit/Utils/UnitUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) chuongmep.com. All rights reserved 2 | 3 | using System.Reflection; 4 | using System.Text.RegularExpressions; 5 | using Newtonsoft.Json; 6 | 7 | namespace APSToolkit.Utils; 8 | 9 | public static class UnitUtils 10 | { 11 | /// 12 | /// Get All Units from units.json 13 | /// 14 | /// 15 | /// 16 | public static List? GetAllUnits() 17 | { 18 | // read units.json from resources 19 | Assembly? assembly = Assembly.GetExecutingAssembly(); 20 | string resourceName = "APSToolkit.Resources.units.json"; 21 | string[] resourceNames = assembly.GetManifestResourceNames(); 22 | if(resourceNames.Length==0) throw new Exception("Resource not found!"); 23 | using (Stream? stream = assembly.GetManifestResourceStream(resourceName)) 24 | { 25 | if (stream == null) 26 | { 27 | return new List(); 28 | } 29 | // Read the JSON data from the stream 30 | using (StreamReader reader = new StreamReader(stream)) 31 | { 32 | var json = reader.ReadToEnd(); 33 | // deaserialize json to list object 34 | List? unitsDataList = JsonConvert.DeserializeObject>(json); 35 | return unitsDataList; 36 | } 37 | } 38 | } 39 | public static Dictionary GetAllDictUnits() 40 | { 41 | List? unitsDataList = GetAllUnits(); 42 | Dictionary dict = new Dictionary(); 43 | foreach (var unitsData in unitsDataList) 44 | { 45 | dict.Add(unitsData.TypeId, unitsData.UnitLabel); 46 | } 47 | return dict; 48 | } 49 | 50 | public static UnitsData? ParseUnitsData(string typeId) 51 | { 52 | if (string.IsNullOrEmpty(typeId)) return null; 53 | // e.g : autodesk.unit.unit:britishThermalUnits-1.0.1 => autodesk.unit.unit:britishThermalUnits-1.0.1 and 1.0.1 54 | var pattern = @"(.*)(-)(.*)"; 55 | var match = Regex.Match(typeId, pattern); 56 | UnitsData unitsData = new UnitsData(); 57 | unitsData.TypeId = match.Groups[1].Value; 58 | unitsData.Version = match.Groups[3].Value; 59 | return unitsData; 60 | } 61 | /// 62 | /// Get Label Symbol unit 63 | /// e.g :autodesk.unit.unit:millimeters-1.0.1 => mm 64 | /// 65 | /// 66 | /// 67 | public static string GetLabelForSymbol(string forgeTypeId) 68 | { 69 | List? units = GetAllUnits(); 70 | var pattern = @"(.*)(-)(.*)"; 71 | var match = Regex.Match(forgeTypeId, pattern); 72 | string typeId = match.Groups[1].Value; 73 | var label = units?.FirstOrDefault(x => x.TypeId == typeId)?.UnitLabel; 74 | return label ?? string.Empty; 75 | } 76 | } 77 | 78 | public class UnitsData 79 | { 80 | public string TypeId { get; set; } 81 | public string UnitLabel { get; set; } 82 | public string Version { get; set; } 83 | } -------------------------------------------------------------------------------- /APSToolkitApp/APSToolkitApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net8.0-windows 6 | true 7 | enable 8 | enable 9 | true 10 | 11 | 12 | 13 | 14 | MSBuild:Compile 15 | Wpf 16 | Designer 17 | 18 | 19 | 20 | 21 | 22 | MSBuild:Compile 23 | Wpf 24 | Designer 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /APSToolkitApp/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] -------------------------------------------------------------------------------- /APSToolkitApp/Model/ApsProject.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkitApp.Model; 2 | 3 | public class ApsProject 4 | { 5 | public string Name { get; set; } 6 | public string Id { get; set; } 7 | } -------------------------------------------------------------------------------- /APSToolkitApp/View/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /APSToolkitApp/View/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using System.Data; 3 | using System.Windows; 4 | 5 | namespace APSToolkitApp; 6 | 7 | /// 8 | /// Interaction logic for App.xaml 9 | /// 10 | public partial class App : Application 11 | { 12 | } -------------------------------------------------------------------------------- /APSToolkitApp/View/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /APSToolkitApp/View/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Data; 5 | using System.Windows.Documents; 6 | using System.Windows.Input; 7 | using System.Windows.Media; 8 | using System.Windows.Media.Imaging; 9 | using System.Windows.Navigation; 10 | using System.Windows.Shapes; 11 | 12 | namespace APSToolkitApp; 13 | 14 | /// 15 | /// Interaction logic for MainWindow.xaml 16 | /// 17 | public partial class MainWindow : Window 18 | { 19 | public MainWindow() 20 | { 21 | InitializeComponent(); 22 | } 23 | } -------------------------------------------------------------------------------- /APSToolkitApp/ViewModel/APSToolkitViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkitApp.ViewModel; 2 | 3 | public class APSToolkitViewModel 4 | { 5 | public APSToolkitViewModel() 6 | { 7 | 8 | } 9 | 10 | public void ExportParquet() 11 | { 12 | 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /APSToolkitApp/ViewModel/ProjectViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace APSToolkitApp.ViewModel; 2 | 3 | public class ProjectViewModel 4 | { 5 | public ProjectViewModel() 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /APSToolkitPython/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /APSToolkitPython/Readme.md: -------------------------------------------------------------------------------- 1 | APSToolkit 2 | 3 | ## Requirements 4 | 5 | - Python 3.9+ 6 | 7 | - Setting Environment Variables 8 | 9 | ```bash 10 | APS_CLIENT_PKCE_ID=your_client_id 11 | APS_CLIENT_ID=your_client_id 12 | APS_CLIENT_SECRET=your_client_secret 13 | ``` 14 | 15 | 16 | ## How to install the project 17 | 18 | ```bash 19 | pip install aps-toolkit 20 | ``` 21 | 22 | ## Get Started 23 | 24 | ```python 25 | from aps_toolkit import Auth 26 | auth = Auth() 27 | token = auth.auth2leg() 28 | ``` 29 | 30 | ## Tutorial 31 | 32 | Please refer to the github [tutorial](https://github.com/chuongmep/aps-toolkit) 33 | 34 | ## How to build the project 35 | 36 | Install package : pip install wheel 37 | 38 | ```bash 39 | python setup.py bdist_wheel 40 | python setup.py sdist 41 | python setup.py bdist_wheel sdist 42 | ``` 43 | 44 | ## Install the project at local 45 | 46 | - Remove the old package at site-packages folder 47 | - Install the new updated package 48 | ```bash 49 | pip install dist/.whl 50 | ``` 51 | 52 | ## Publish the project 53 | 54 | - Run the following command to build the package 55 | ```bash 56 | python setup.py bdist_wheel sdist 57 | ``` 58 | - Run the following command to check and upload the package to pypi 59 | ```bash 60 | python -m twine check dist/* 61 | python -m twine upload dist/* 62 | ``` 63 | 64 | ## Issue Known 65 | 66 | - [cannot import name 'appengine' from 'requests.packages.urllib3.contrib'](https://stackoverflow.com/questions/76175487/sudden-importerror-cannot-import-name-appengine-from-requests-packages-urlli) 67 | 68 | ```python 69 | pip install --upgrade twine requests-toolbelt 70 | ``` 71 | 72 | ## License 73 | 74 | This project is licensed under the GNU **General Public License V3 License** - see the [[LICENSE.md](https://en.wikipedia.org/wiki/GNU_General_Public_License)]( -------------------------------------------------------------------------------- /APSToolkitPython/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pylint 2 | build 3 | twine 4 | wheel 5 | setuptools 6 | pdoc3 -------------------------------------------------------------------------------- /APSToolkitPython/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | pandas 3 | -------------------------------------------------------------------------------- /APSToolkitPython/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("Readme.md") as f: 4 | if f is not None: 5 | readme = f.read() 6 | 7 | setuptools.setup( 8 | name="aps_toolkit", 9 | version="1.2.1", 10 | author="chuong mep", 11 | author_email="chuongpqvn@gmail.com", 12 | description="A Toolkit Autodesk Platform Services for Python", 13 | long_description=readme, 14 | long_description_content_type="text/markdown", 15 | url="https://github.com/chuongmep/aps-toolkit", 16 | project_urls={ 17 | "Bug Tracker": "https://github.com/chuongmep/aps-toolkit/issues", 18 | }, 19 | classifiers=[ 20 | "Programming Language :: Python :: 3", 21 | "License :: OSI Approved :: GNU Affero General Public License v3", 22 | "Operating System :: OS Independent", 23 | ], 24 | package_dir={"": "src"}, 25 | packages=setuptools.find_packages(where="src"), 26 | python_requires=">=3.9", 27 | install_requires=['requests', 'pandas'], 28 | include_package_data=True, 29 | data_files=[('aps_toolkit/units', ['src/aps_toolkit/units/units.json'])] 30 | ) 31 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/ConvertUtils.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import re 3 | import urllib.parse 4 | from urllib.parse import urlparse, parse_qs 5 | import pandas as pd 6 | 7 | class ConvertUtils: 8 | def __init__(self): 9 | pass 10 | @staticmethod 11 | def urn_to_item_version(urn): 12 | """ 13 | Convert URN to item_version 14 | e.g. dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0zNg to urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=36 15 | :param urn: 16 | :return: 17 | """ 18 | if not urn: 19 | return None 20 | if urn.find("_") == -1: 21 | raise Exception("Invalid URN") 22 | data = urn.split("_") 23 | item_id = data[0] 24 | versionid = data[1] 25 | item_id = base64.b64decode(item_id + "=").decode("utf-8") 26 | # Manually add padding to ensure the length is a multiple of 4 27 | padding = "=" * (4 - len(versionid) % 4) if len(versionid) % 4 != 0 else "" 28 | urn_padded = versionid + padding 29 | versionid = base64.b64decode(urn_padded).decode("utf-8") 30 | item_version = item_id + "?" + versionid 31 | return item_version 32 | 33 | @staticmethod 34 | def item_version_to_urn(item_version): 35 | """ 36 | Convert item_version to URN 37 | e.g. urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=36 to dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0zNg 38 | :param item_version: 39 | :return: 40 | """ 41 | data = item_version.split("?") 42 | item_id = data[0] 43 | versionid = data[1] 44 | item_id = base64.b64encode(item_id.encode("utf-8")).decode("utf-8") 45 | versionid = base64.b64encode(versionid.encode("utf-8")).decode("utf-8") 46 | urn = item_id + "_" + versionid 47 | urn = urn.replace("=", "") 48 | return urn 49 | 50 | @staticmethod 51 | def parse_acc_url(url: str) -> pd.Series: 52 | """ 53 | Parse url to get project_id, folder_urn, version_id, viewable_guid 54 | :param url: the url from bim360 or autodesk construction cloud (ACC) 55 | :return: :class:`dict` project_id, folder_urn, version_id, viewable_guid 56 | """ 57 | if url is None: 58 | raise Exception("url is required") 59 | if not str.__contains__(url, "autodesk.com"): 60 | raise Exception("url is not valid") 61 | project_id_match = re.search(r'projects/([^\/?#]+)', url) 62 | project_id = 'b.' + project_id_match.group(1) if project_id_match else '' 63 | query_params = parse_qs(urlparse(url).query) 64 | folder_urn = query_params.get('folderUrn', [''])[0] 65 | version_id = query_params.get('entityId', [''])[0] 66 | version_encoder = urllib.parse.quote(version_id) 67 | item_id = None 68 | if version_id is not None or version_id != '': 69 | item_id = version_id.split("?")[0] 70 | viewable_guid = query_params.get('viewable_guid', [''])[0] 71 | 72 | data = { 73 | 'project_id': project_id, 74 | 'folder_urn': folder_urn, 75 | 'item_id': item_id, 76 | 'version_id': version_id, 77 | 'version_encoder': version_encoder, 78 | 'viewable_guid': viewable_guid, 79 | } 80 | series = pd.Series(data) 81 | return series -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/DbReader.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | import os 18 | import requests 19 | from .Auth import Auth 20 | import pandas as pd 21 | import sqlite3 22 | from .Token import Token 23 | 24 | 25 | class DbReader: 26 | def __init__(self, urn: str, token: Token = None): 27 | self.urn = urn 28 | if token is None: 29 | auth = Auth() 30 | self.token = auth.auth2leg() 31 | else: 32 | self.token = token 33 | self.host = "https://developer.api.autodesk.com" 34 | url = f"{self.host}/modelderivative/v2/designdata/{self.urn}/manifest" 35 | headers = { 36 | "Authorization": f"Bearer {self.token.access_token}" 37 | } 38 | response = requests.get(url, headers=headers) 39 | if response.status_code != 200: 40 | raise Exception(response.content) 41 | json_response = response.json() 42 | if json_response["status"] != "success": 43 | raise Exception(json_response) 44 | childrens = json_response['derivatives'][0]["children"] 45 | self.path = "" 46 | for child in childrens: 47 | if child["type"] == "resource" and child["mime"] == "application/autodesk-db": 48 | self.path = child["urn"] 49 | break 50 | url = f"{self.host}/modelderivative/v2/designdata/{self.urn}/manifest/{self.path}" 51 | response = requests.get(url, headers=headers) 52 | temp_path = os.path.join(os.path.dirname(__file__), "database") 53 | extension = self.path.split(".")[-1] 54 | temp_path = os.path.join(temp_path, self.urn + "." + extension) 55 | self.db_path = temp_path 56 | if not os.path.exists(temp_path): 57 | os.makedirs(os.path.dirname(temp_path), exist_ok=True) 58 | with open(temp_path, "wb") as file: 59 | file.write(response.content) 60 | file.close() 61 | 62 | def execute_query(self, query: str): 63 | conn = sqlite3.connect(self.db_path) 64 | return pd.read_sql_query(query, conn) 65 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/InputStream.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | import struct 18 | 19 | 20 | class InputStream: 21 | def __init__(self, buffer): 22 | self.buffer = buffer 23 | self.offset = 0 24 | self.length = len(buffer) 25 | 26 | def seek(self, offset): 27 | self.offset = offset 28 | 29 | def get_uint8(self) -> int: 30 | val = self.buffer[self.offset] 31 | self.offset += 1 32 | return val 33 | 34 | def get_uint16(self) -> int: 35 | val = struct.unpack_from(' int: 40 | val = struct.unpack_from(' int: 45 | val = struct.unpack_from(' int: 50 | val = struct.unpack_from(' float: 55 | val = struct.unpack_from(' int: 65 | val = 0 66 | shift = 0 67 | while True: 68 | byte = self.buffer[self.offset] 69 | self.offset += 1 70 | val |= (byte & 0x7F) << shift 71 | if (byte & 0x80) == 0: 72 | break 73 | shift += 7 74 | return val 75 | 76 | def get_string(self, length) -> str: 77 | val = self.buffer[self.offset:self.offset + length].decode('utf-8') 78 | self.offset += length 79 | return val 80 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/ManifestItem.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | from .PathInfo import PathInfo 18 | 19 | 20 | class ManifestItem: 21 | def __init__(self, guid, mime, path_info: [PathInfo], urn): 22 | self.guid = guid 23 | self.mime = mime 24 | self.urn = urn 25 | self.path_info = path_info 26 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/MaterialProperties.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class MaterialProperties: 18 | def __init__(self, integers=None, booleans=None, strings=None, uris=None, scalars=None, colors=None, 19 | choicelists=None, uuids=None, references=None): 20 | self.integers = integers 21 | self.booleans = booleans 22 | self.strings = strings 23 | self.uris = uris 24 | self.scalars = scalars 25 | self.colors = colors 26 | self.choicelists = choicelists 27 | self.uuids = uuids 28 | self.references = references 29 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/Materials.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | from .MaterialProperties import MaterialProperties 18 | from .SVFMaterialMap import SVFMaterialMap 19 | 20 | 21 | class Materials: 22 | def __init__(self, diffuse=None, specular=None, ambient=None, emissive=None, glossiness=None, reflectivity=None, 23 | opacity=None, metal=None, map: [SVFMaterialMap] = None, tag=None, 24 | proteinType=None, definition=None, transparent=None, keywords=None, categories=None, 25 | properties: [MaterialProperties] = None, 26 | textures=None): 27 | self.diffuse = diffuse 28 | self.specular = specular 29 | self.ambient = ambient 30 | self.emissive = emissive 31 | self.glossiness = glossiness 32 | self.reflectivity = reflectivity 33 | self.opacity = opacity 34 | self.metal = metal 35 | self.map = map 36 | self.tag = tag 37 | self.proteinType = proteinType 38 | self.definition = definition 39 | self.transparent = transparent 40 | self.keywords = keywords 41 | self.categories = categories 42 | self.properties = properties 43 | self.textures = textures 44 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/PathInfo.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | 19 | class PathInfo: 20 | def __init__(self, root_file_name: str = None, base_path: str = None, local_path: str = None, urn: str = None): 21 | self.root_file_name = root_file_name 22 | self.local_path = local_path 23 | self.base_path = base_path 24 | self.urn = urn 25 | self.files = [] 26 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/Resource.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | from urllib.parse import urljoin, quote 18 | 19 | 20 | class Resource: 21 | def __init__(self, file_name, remote_path, local_path): 22 | self.host = "https://developer.api.autodesk.com" 23 | self.file_name = file_name 24 | self.remote_path = self._resolve_path_slashes(remote_path) 25 | self.url = self._resolve_url(remote_path) 26 | self.local_path = self._resolve_path_slashes(local_path) 27 | 28 | def _resolve_path_slashes(self, path): 29 | url_with_forward_slashes = path.replace('\\', '/') 30 | return url_with_forward_slashes 31 | 32 | def _resolve_url(self, remote_path): 33 | url_with_forward_slashes = remote_path.replace('\\', '/') 34 | return urljoin(self.host, quote(url_with_forward_slashes, safe=':/')) 35 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFContent.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | 19 | class SVFContent: 20 | def __init__(self, metadata=None, fragments=None, geometries=None, meshpacks=None, materials=None, properties=None, 21 | images=None): 22 | self.metadata = metadata 23 | self.fragments = fragments 24 | self.geometries = geometries 25 | self.meshpacks = meshpacks 26 | self.materials = materials 27 | self.properties = properties 28 | self.images = images 29 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFGeometries.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | from .Derivative import Derivative 18 | from .PackFileReader import PackFileReader 19 | from .ManifestItem import ManifestItem 20 | 21 | 22 | class SVFGeometries: 23 | def __init__(self, frag_type=None, prim_count=None, pack_id=None, entity_id=None, topo_id=None): 24 | self.fragment_type = frag_type 25 | self.primitive_count = prim_count 26 | self.pack_id = pack_id 27 | self.entity_id = entity_id 28 | self.topo_id = topo_id 29 | 30 | @staticmethod 31 | def parse_geometries_from_urn(urn, token, region="US") -> dict: 32 | """ 33 | Parse geometries from urn 34 | :param urn: the urn of the model 35 | :param token: the token authentication 36 | :param region: the region of hub (default is US) 37 | :return: a dictionary of geometries with key is the guid of the manifest item and value is the list of geometries 38 | """ 39 | geometries = {} 40 | derivative = Derivative(urn, token, region) 41 | manifest_items = derivative.read_svf_manifest_items() 42 | for manifest_item in manifest_items: 43 | geos = SVFGeometries.parse_geos_from_manifest_item(derivative, manifest_item) 44 | geometries[manifest_item.guid] = geos 45 | return geometries 46 | 47 | @staticmethod 48 | def parse_geos_from_manifest_item(derivative: [Derivative], manifest_item: [ManifestItem]) -> list: 49 | geometries = [] 50 | resources = derivative.read_svf_resource_item(manifest_item) 51 | for resource in resources: 52 | if resource.local_path.endswith("GeometryMetadata.pf"): 53 | bytes_io = derivative.download_stream_resource(resource) 54 | buffer = bytes_io.read() 55 | geos = SVFGeometries.parse_geometries(buffer) 56 | geometries.extend(geos) 57 | return geometries 58 | 59 | @staticmethod 60 | def parse_geometries(buffer) -> list: 61 | """ 62 | Parse geometries from buffer 63 | :param buffer: the buffer of the geometry metadata file 64 | :return: a list of geometries 65 | """ 66 | geometries = [] 67 | pfr = PackFileReader(buffer) 68 | for i in range(pfr.num_entries()): 69 | entry = pfr.seek_entry(i) 70 | if entry is not None and entry.version >= 3: 71 | frag_type = pfr.get_uint8() 72 | # Skip past object space bbox -- we don't use that 73 | pfr.seek(pfr.offset + 24) 74 | prim_count = pfr.get_uint16() 75 | p_id = pfr.get_string(pfr.get_varint()).replace(".pf", "") 76 | pack_id = int(p_id) 77 | entity_id = pfr.get_varint() 78 | geometry = SVFGeometries(frag_type, prim_count, pack_id, entity_id) 79 | geometries.append(geometry) 80 | 81 | return geometries 82 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFImage.py: -------------------------------------------------------------------------------- 1 | from .Derivative import Derivative 2 | from .ManifestItem import ManifestItem 3 | 4 | 5 | class SVFImage: 6 | def __init__(self, name, data: [bytes]): 7 | self.name = name 8 | self.data = data 9 | 10 | @staticmethod 11 | def parse_images_from_urn(urn, token, region="US") -> dict: 12 | images = {} 13 | derivative = Derivative(urn, token, region) 14 | manifest_items = derivative.read_svf_manifest_items() 15 | for manifest_item in manifest_items: 16 | list_bytes_images = SVFImage.parse_images_from_derivative(derivative, manifest_item) 17 | images[manifest_item.guid] = list_bytes_images 18 | return images 19 | 20 | @staticmethod 21 | def parse_images_from_derivative(derivative: [Derivative], manifest_item: [ManifestItem]) -> list: 22 | images = [] 23 | resources = derivative.read_svf_resource_item(manifest_item) 24 | for resource in resources: 25 | if resource.local_path.endswith(".png"): 26 | bytes_io = derivative.download_stream_resource(resource) 27 | buffer = bytes_io.read() 28 | bytes = SVFImage(resource.file_name, buffer) 29 | images.append(bytes) 30 | return images 31 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFLines.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFLines: 18 | def __init__(self, isLines=False, v_count=None, l_count=None, vertices=None, indices=None, colors=None, 19 | line_width=None): 20 | self.isLines = isLines 21 | self.v_count = v_count 22 | self.l_count = l_count 23 | self.vertices = vertices 24 | self.indices = indices 25 | self.colors = colors 26 | self.line_width = line_width 27 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFManifestType.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFManifestType: 18 | def __init__(self, type_class="", type="", version=0): 19 | self.type_class = type_class 20 | self.type = type 21 | self.version = version 22 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFMaterialGroup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | from .Materials import Materials 18 | 19 | 20 | class SVFMaterialGroup: 21 | def __init__(self, version, userassets, materials: [Materials]): 22 | self.version = version 23 | self.userassets = userassets 24 | self.materials = materials 25 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFMaterialMap.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFMaterialMap: 18 | def __init__(self, uri=None, scale=None): 19 | self.uri = uri 20 | self.scale = scale 21 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFMaterialMapScale.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFMaterialMapScale: 18 | def __init__(self, texture_u_scale, texture_v_scale): 19 | self.texture_u_scale = texture_u_scale 20 | self.texture_v_scale = texture_v_scale 21 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFMetadata.py: -------------------------------------------------------------------------------- 1 | from .Derivative import Derivative 2 | from .ManifestItem import ManifestItem 3 | 4 | 5 | class SVFMetadata: 6 | def __init__(self, version, metadata): 7 | self.version = version 8 | self.metadata = metadata 9 | 10 | @staticmethod 11 | def parse_metadata_from_urn(urn, token, region="US") -> dict: 12 | meta_datas = {} 13 | derivative = Derivative(urn, token, region) 14 | manifest_items = derivative.read_svf_manifest_items() 15 | for manifest_item in manifest_items: 16 | meta_data = SVFMetadata.parse_metadata_from_derivative(derivative, manifest_item) 17 | meta_datas[manifest_item.guid] = meta_data 18 | return meta_datas 19 | 20 | @staticmethod 21 | def parse_metadata_from_derivative(derivative: [Derivative], manifest_item: [ManifestItem]) -> str: 22 | metadata = derivative.read_svf_metadata(manifest_item.urn) 23 | return metadata 24 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFPoints.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFPoints: 18 | def __init__(self, is_points=None, v_vount=None, vertices=None, colors=None, point_size=None): 19 | self.is_points = is_points 20 | self.v_count = v_vount 21 | self.vertices = vertices 22 | self.colors = colors 23 | self.point_size = point_size 24 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFTransform.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | 19 | class SVFTransform: 20 | def __init__(self, t: tuple = None, q=None, s=None, matrix=None): 21 | self.t = t 22 | self.q = q 23 | self.s = s 24 | self.matrix = matrix 25 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/SVFUVMap.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2024 chuongmep.com 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | class SVFUVMap: 18 | def __init__(self, name=None, file=None, uvs=None): 19 | self.name = name 20 | self.file = file 21 | self.uvs = uvs -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/__init__.py: -------------------------------------------------------------------------------- 1 | from .units.DisplayUnits import DisplayUnits 2 | from .Auth import Auth 3 | from .AuthGoogleColab import AuthGoogleColab 4 | from .BIM360 import BIM360 5 | from .ProDbReaderRevit import PropDbReaderRevit 6 | from .ProDbReaderCad import PropDbReaderCad 7 | from .ProDbReaderNavis import PropDbReaderNavis 8 | from .PropReader import PropReader 9 | from .DbReader import DbReader 10 | from .Bucket import Bucket 11 | from .Token import Token 12 | from .Token import RevokeType, ClientType 13 | from .InputStream import InputStream 14 | from .PackFileReader import PackFileReader 15 | from .SVFReader import SVFReader 16 | from .SVFContent import SVFContent 17 | from .Derivative import Derivative 18 | from .Fragments import Fragments 19 | from .SVFGeometries import SVFGeometries 20 | from .SVFMesh import SVFMesh 21 | from .SVFMaterials import SVFMaterials 22 | from .SVFImage import SVFImage 23 | from .SVFMetadata import SVFMetadata 24 | from .Webhooks import Webhooks 25 | from .AECDataModel import AECDataModel 26 | from .ConvertUtils import ConvertUtils -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/units/DisplayUnits.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | import os 4 | 5 | 6 | class DisplayUnits: 7 | def __init__(self): 8 | self._read_units_local() 9 | 10 | def _read_units_stream(self): 11 | url = "https://gist.githubusercontent.com/chuongmep/497dea0ead458b52d001f2c806f32f9d/raw/a149bc1ee805485303e32122d8ccb8714231992e/units.json" 12 | try: 13 | response = requests.get(url) 14 | if response.status_code == 200: 15 | self.units = response.json() 16 | print("Units loaded") 17 | else: 18 | print(f"Error: Failed to retrieve units data. Status code: {response.status_code}") 19 | except Exception as e: 20 | print(f"Error: {e}") 21 | 22 | def _read_units_local(self): 23 | # get relative path 24 | dir_path = os.path.dirname(os.path.realpath(__file__)) 25 | file_name = "units.json" 26 | file_path = os.path.join(dir_path, file_name) 27 | try: 28 | with open(file_path, "r", encoding="utf-8") as file: 29 | self.units = json.load(file) 30 | # convert to dict 31 | self.units = {unit["TypeId"]: unit["UnitLabel"] for unit in self.units} 32 | except FileNotFoundError: 33 | print(f"Error: File '{file_path}' not found.") 34 | except json.JSONDecodeError as e: 35 | print(f"Error decoding JSON file: {e}") 36 | 37 | def parse_symbol(self, type_id: str): 38 | if type_id is None: 39 | return "" 40 | if "-" in type_id: 41 | type_id = type_id.split("-")[0] 42 | return self.units.get(type_id, "") 43 | else: 44 | return "" 45 | -------------------------------------------------------------------------------- /APSToolkitPython/src/aps_toolkit/units/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitPython/src/aps_toolkit/units/__init__.py -------------------------------------------------------------------------------- /APSToolkitPython/src/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitPython/src/test/__init__.py -------------------------------------------------------------------------------- /APSToolkitPython/src/test/_trial_temp/_trial_marker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitPython/src/test/_trial_temp/_trial_marker -------------------------------------------------------------------------------- /APSToolkitPython/src/test/context.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | # Assuming the src folder is at the same level as the test folder 5 | src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 6 | print(src_dir) 7 | sys.path.append(src_dir) 8 | # Now you can import modules from the project folder 9 | from aps_toolkit import PropReader 10 | from aps_toolkit import PropDbReaderRevit 11 | from aps_toolkit import PropDbReaderCad 12 | from aps_toolkit import PropDbReaderNavis 13 | from aps_toolkit import DbReader 14 | from aps_toolkit import Auth 15 | from aps_toolkit import AuthGoogleColab 16 | from aps_toolkit import Token 17 | from aps_toolkit import RevokeType, ClientType 18 | from aps_toolkit import BIM360 19 | from aps_toolkit import Fragments 20 | from aps_toolkit import SVFGeometries 21 | from aps_toolkit import SVFMesh 22 | from aps_toolkit import Derivative 23 | from aps_toolkit import SVFReader 24 | from aps_toolkit import SVFMaterials 25 | from aps_toolkit import SVFImage 26 | from aps_toolkit import SVFMetadata 27 | from aps_toolkit import Bucket 28 | from aps_toolkit.units import DisplayUnits 29 | from aps_toolkit import Webhooks 30 | from aps_toolkit import AECDataModel 31 | 32 | APS_CLIENT_ID = os.environ["APS_CLIENT_ID"] 33 | APS_CLIENT_SECRET = os.environ["APS_CLIENT_SECRET"] 34 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/resources/Test.dwg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitPython/src/test/resources/Test.dwg -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_Webhooks.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import Webhooks 4 | from .context import Auth 5 | 6 | class TestWebhooks(TestCase): 7 | 8 | def setUp(self): 9 | token = Auth().auth2leg() 10 | self.hooks = Webhooks(token) 11 | 12 | def test_get_all_hooks(self): 13 | result = self.hooks.get_all_hooks() 14 | self.assertIsNotNone(result) 15 | 16 | def test_batch_report_all_hooks(self): 17 | result = self.hooks.batch_report_all_hooks() 18 | self.assertIsNotNone(result) 19 | 20 | def test_get_all_app_hooks(self): 21 | result = self.hooks.get_all_app_hooks() 22 | self.assertIsNotNone(result) 23 | 24 | def test_batch_report_all_app_hooks(self): 25 | result = self.hooks.batch_report_all_app_hooks() 26 | self.assertIsNotNone(result) 27 | 28 | def test_get_hook_by_id(self): 29 | hook_id = "1c7844f5-adcd-4225-b8a6-d7a47cca05e4" 30 | result = self.hooks.get_hook_by_id(hook_id,"dm.version.added","data") 31 | self.assertIsNotNone(result) 32 | 33 | def test_delete_hook_by_id(self): 34 | hook_id = '00677529-badb-4c6e-af6b-e63241ffd752' 35 | event = 'dm.version.added' 36 | result = self.hooks.delete_hook_by_id(hook_id, event,"data") 37 | print(result) 38 | 39 | def test_create_system_event_hook(self): 40 | scope = {"folder": "urn:adsk.wipprod:fs.folder:co.stvP5WhOSWGMFPPINBxwcA"} # changed to a dictionary 41 | callback_url = "http://localhost:8080/api/webhooks/callback" 42 | hookAttribute = { 43 | "callbackUrl": callback_url, 44 | "scope": scope, 45 | "name": "foo", 46 | "special_data": "hello world", 47 | } 48 | result = self.hooks.create_system_event_hook(scope, callback_url, hookAttribute=hookAttribute) 49 | self.assertIsNotNone(result) 50 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_auth.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import Auth 4 | 5 | 6 | class TestAuth(TestCase): 7 | def test_auth(self): 8 | client_id = os.environ['APS_CLIENT_ID'] 9 | client_secret = os.environ['APS_CLIENT_SECRET'] 10 | auth = Auth(client_id, client_secret) 11 | token = auth.auth2leg() 12 | self.assertNotEqual(token.access_token, "") 13 | 14 | def test_auth2(self): 15 | auth = Auth() 16 | token = auth.auth2leg() 17 | self.assertNotEqual(token.access_token, "") 18 | 19 | def test_auth3leg(self): 20 | auth = Auth() 21 | redirect_uri = "http://localhost:8080/api/auth/callback" 22 | # https://aps.autodesk.com/en/docs/oauth/v2/developers_guide/scopes 23 | scopes = 'data:read viewables:read' 24 | token = auth.auth3leg(redirect_uri, scopes) 25 | print(token.refresh_token) 26 | self.assertNotEqual(token.access_token, "") 27 | 28 | def test_auth3legPkce(self): 29 | auth = Auth() 30 | redirect_uri = "http://localhost:8080/api/auth/callback" 31 | # https://aps.autodesk.com/en/docs/oauth/v2/developers_guide/scopes 32 | scopes = 'data:read viewables:read' 33 | client_id = os.environ['APS_CLIENT_PKCE_ID'] 34 | token = auth.auth3legPkce(client_id, redirect_uri, scopes) 35 | print(token.refresh_token) 36 | self.assertNotEqual(token.access_token, "") 37 | 38 | def test_refresh_token(self): 39 | auth = Auth() 40 | token = auth.auth3leg() 41 | self.assertNotEqual(token.access_token, "") 42 | print("Refresh token: ", token.refresh_token) 43 | print("Start refresh token") 44 | new_token = auth.refresh_new_token(token.refresh_token) 45 | print("New Fresh Token", new_token.refresh_token) 46 | self.assertNotEqual(token.access_token, "") 47 | self.assertNotEqual(token.refresh_token, "") 48 | 49 | def test_refresh_token_from_env(self): 50 | token = Auth.refresh_token_from_env() 51 | self.assertNotEqual(token.access_token, "") 52 | 53 | def test_get_user_info(self): 54 | auth = Auth() 55 | token = auth.auth3leg() 56 | user_info = auth.get_user_info() 57 | self.assertNotEqual(user_info, "") 58 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_auth_colab.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import AuthGoogleColab 4 | 5 | 6 | class TestAuth(TestCase): 7 | def test_auth(self): 8 | client_id = os.environ['APS_CLIENT_ID'] 9 | client_secret = os.environ['APS_CLIENT_SECRET'] 10 | auth = AuthGoogleColab(client_id, client_secret) 11 | token = auth.auth2leg() 12 | self.assertNotEqual(token.access_token, "") 13 | 14 | def test_auth2leg(self): 15 | auth = AuthGoogleColab() 16 | token = auth.auth2leg() 17 | self.assertNotEqual(token.access_token, "") 18 | 19 | def test_auth3leg(self): 20 | auth = AuthGoogleColab() 21 | redirect_uri = "http://localhost:8080/api/auth/callback" 22 | # https://aps.autodesk.com/en/docs/oauth/v2/developers_guide/scopes 23 | scopes = 'data:read viewables:read' 24 | token = auth.auth3leg(redirect_uri, scopes) 25 | print(token.refresh_token) 26 | self.assertNotEqual(token.access_token, "") 27 | 28 | def test_auth3legPkce(self): 29 | auth = AuthGoogleColab() 30 | redirect_uri = "http://localhost:8080/api/auth/callback" 31 | # https://aps.autodesk.com/en/docs/oauth/v2/developers_guide/scopes 32 | scopes = 'data:read viewables:read' 33 | client_id = os.environ['APS_CLIENT_PKCE_ID'] 34 | token = auth.auth3legPkce(client_id, redirect_uri, scopes) 35 | print("Refresh Token:", token.refresh_token) 36 | self.assertNotEqual(token.access_token, "") 37 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_bucket.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from aps_toolkit.Bucket import PublicKey 4 | from .context import Bucket 5 | from .context import Auth 6 | 7 | 8 | class TestBucket(unittest.TestCase): 9 | def setUp(self): 10 | self.token = Auth().auth2leg() 11 | 12 | def test_get_all_buckets(self): 13 | bucket = Bucket(self.token) 14 | buckets = bucket.get_all_buckets() 15 | self.assertNotEqual(len(buckets), 0) 16 | 17 | def test_create_bucket(self): 18 | bucket = Bucket(self.token) 19 | bucket_name = "hello_world_22222" 20 | policy_key = PublicKey.transient 21 | response = bucket.create_bucket(bucket_name, policy_key) 22 | self.assertEqual(response["bucketKey"], bucket_name) 23 | 24 | def test_delete_bucket(self): 25 | bucket = Bucket(self.token) 26 | bucket_name = "hello_world_22222" 27 | result = bucket.delete_bucket(bucket_name) 28 | self.assertEqual(result, b'') 29 | 30 | def test_get_objects(self): 31 | bucket = Bucket(self.token) 32 | bucket_name = "hello_world_22222" 33 | objects = bucket.get_objects(bucket_name) 34 | self.assertNotEqual(len(objects), 0) 35 | 36 | def test_upload_object(self): 37 | bucket = Bucket(self.token) 38 | bucket_name = "hello_world_22222" 39 | file_path = "./test/resources/Test.dwg" 40 | object_name = "Test.dwg" 41 | response = bucket.upload_object(bucket_name, file_path, object_name) 42 | self.assertEqual(response["bucketKey"], bucket_name) 43 | 44 | def test_delete_object(self): 45 | bucket = Bucket(self.token) 46 | bucket_name = "hello_world_22222" 47 | object_name = "Test.dwg" 48 | result = bucket.delete_object(bucket_name, object_name) 49 | self.assertEqual(result, b'') 50 | 51 | def test_download_object(self): 52 | bucket = Bucket(self.token) 53 | bucket_name = "hello_world_22222" 54 | object_name = "Test.dwg" 55 | file_path = "./test/resources/Test2.dwg" 56 | bucket.download_object(bucket_name, object_name, file_path) 57 | self.assertTrue(True) 58 | 59 | def test_download_stream_object(self): 60 | bucket = Bucket(self.token) 61 | bucket_name = "hello_world_23232" 62 | object_name = "chuong.pdf" 63 | stream = bucket.download_stream_object(bucket_name, object_name) 64 | self.assertIsNotNone(stream) 65 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_db_reader.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import Auth 4 | from .context import DbReader 5 | 6 | 7 | class TestDbReader(TestCase): 8 | def setUp(self): 9 | self.client_id = os.environ['APS_CLIENT_ID'] 10 | self.client_secret = os.environ['APS_CLIENT_SECRET'] 11 | self.auth = Auth(self.client_id, self.client_secret) 12 | self.token = self.auth.auth2leg() 13 | self.urn = "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6Y2h1b25nX2J1Y2tldC9NeUhvdXNlLm53Yw" 14 | 15 | def test_reader(self): 16 | db_reader = DbReader(self.urn, self.token) 17 | self.assertNotEqual(db_reader, "") 18 | 19 | def test_execute_query(self): 20 | db_reader = DbReader(self.urn, self.token) 21 | print(db_reader.db_path) 22 | query = "SELECT * FROM _objects_id" 23 | df = db_reader.execute_query(query) 24 | self.assertNotEqual(df.empty, True) 25 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_derivative.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import Derivative 3 | from .context import Auth 4 | import os 5 | 6 | 7 | class TestDerivative(TestCase): 8 | def setUp(self): 9 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 10 | self.token = Auth().auth2leg() 11 | 12 | def test_translate_job(self): 13 | self.urn = "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6Y2h1b25nX2J1Y2tldC9NeUhvdXNlLm53Yw" 14 | derivative = Derivative(self.urn, self.token) 15 | response = derivative.translate_job("Project Completion.ifc") 16 | self.assertNotEqual(response, "") 17 | 18 | def test_translate_to_ifc(self): 19 | ## Wrong Urn 20 | #self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLktXNWVBZ25oUjNpRVJaVnh1bEVrb3c_dmVyc2lvbj0x" 21 | ## Right Urn 22 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmRnRkswLXZqVFlLRS1tUDA3Z3o3WUE_dmVyc2lvbj0z" 23 | derivative = Derivative(self.urn, self.token) 24 | response = derivative.translate_to_ifc("IFC 2x3 GSA Concept Design BIM 2010") 25 | status_code = response.status_code 26 | self.assertEqual(status_code, 200) 27 | def test_download_ifc(self): 28 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmRnRkswLXZqVFlLRS1tUDA3Z3o3WUE_dmVyc2lvbj0z" 29 | derivative = Derivative(self.urn, self.token) 30 | filepath = derivative.download_ifc("gsa_report.ifc") 31 | # check size 32 | self.assertNotEqual(os.path.getsize(filepath), 0) 33 | 34 | 35 | def test_check_job_status(self): 36 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmRnRkswLXZqVFlLRS1tUDA3Z3o3WUE_dmVyc2lvbj0z" 37 | derivative = Derivative(self.urn, self.token) 38 | response = derivative.check_job_status() 39 | self.assertNotEqual(response, "") 40 | 41 | def test_read_svf_manifest_items(self): 42 | derivative = Derivative(self.urn, self.token) 43 | manifest_items = derivative.read_svf_manifest_items() 44 | self.assertNotEqual(len(manifest_items), 0) 45 | 46 | def test_read_svf_resource(self): 47 | derivative = Derivative(self.urn, self.token) 48 | svf_resources = derivative.read_svf_resource() 49 | self.assertNotEqual(len(svf_resources), 0) 50 | 51 | def test_read_svf_resource_item(self): 52 | derivative = Derivative(self.urn, self.token) 53 | manifest_items = derivative.read_svf_manifest_items() 54 | svf_resources = derivative.read_svf_resource_item(manifest_items[0]) 55 | self.assertNotEqual(len(svf_resources), 0) 56 | 57 | def test_read_metadata(self): 58 | derivative = Derivative(self.urn, self.token) 59 | manifest_items = derivative.read_svf_manifest_items() 60 | for manifest_item in manifest_items: 61 | metadata = derivative.read_svf_metadata(manifest_item.urn) 62 | self.assertNotEqual(metadata, "") 63 | 64 | def test_get_metadata(self): 65 | derivative = Derivative(self.urn, self.token) 66 | df = derivative.get_metadata() 67 | self.assertNotEqual(df, "") 68 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_fragment.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import Fragments 3 | from .context import Auth 4 | from .context import PropDbReaderRevit 5 | 6 | 7 | class TestFragment(TestCase): 8 | def setUp(self): 9 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yOA" 10 | self.token = Auth().auth2leg() 11 | self.file_path = (r".\output\svfs\Resource\3D View\08f99ae5-b8be-4f8d-881b-128675723c10\Project " 12 | r"Completion\FragmentList.pack") 13 | 14 | def test_parse_fragments(self): 15 | with open(self.file_path, 'rb') as f: 16 | buffer = f.read() 17 | fragment = Fragments.parse_fragments(buffer) 18 | self.assertNotEqual(len(fragment), 0) 19 | 20 | def test_parse_fragments_from_file(self): 21 | fragment = Fragments.parse_fragments_from_file(self.file_path) 22 | self.assertNotEqual(len(fragment), 0) 23 | 24 | def test_parse_fragments_from_urn(self): 25 | fragment = Fragments.parse_fragments_from_urn(self.urn, self.token) 26 | self.assertNotEqual(len(fragment), 0) 27 | 28 | def test_bbox_fragments(self): 29 | fragments = Fragments.parse_fragments_from_urn(self.urn, self.token) 30 | external_id = "5bb069ca-e4fe-4e63-be31-f8ac44e80d30-00046bfe" 31 | propReader = PropDbReaderRevit(self.urn, self.token) 32 | dbid = propReader.get_db_id(external_id) 33 | dbid = 97 34 | bboxs = [] 35 | for index, frags in fragments.items(): 36 | for frag in frags: 37 | if frag.dbID == dbid: 38 | bboxs.append(frag.bbox) 39 | self.assertNotEqual(len(bboxs), 0) 40 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_geometries.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import Auth 3 | from .context import SVFGeometries 4 | 5 | 6 | class TestGeometries(TestCase): 7 | def setUp(self): 8 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 9 | self.token = Auth().auth2leg() 10 | self.file_path = (r".\output\svfs\Resource\3D View\08f99ae5-b8be-4f8d-881b-128675723c10\Project " 11 | r"Completion\GeometryMetadata.pf") 12 | 13 | def test_parse_geometries(self): 14 | with open(self.file_path, 'rb') as f: 15 | buffer = f.read() 16 | geometries = SVFGeometries.parse_geometries(buffer) 17 | self.assertNotEqual(len(geometries), 0) 18 | 19 | def test_parse_geometries_from_urn(self): 20 | geometries = SVFGeometries.parse_geometries_from_urn(self.urn, self.token) 21 | self.assertNotEqual(len(geometries), 0) 22 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_image.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import SVFImage 3 | from .context import Auth 4 | from .context import Derivative 5 | 6 | 7 | class TestImage(TestCase): 8 | def setUp(self): 9 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 10 | self.token = Auth().auth2leg() 11 | 12 | def test_parse_images_from_urn(self): 13 | images = SVFImage.parse_images_from_urn(self.urn, self.token) 14 | self.assertNotEqual(len(images), 0) 15 | 16 | def test_parse_images_from_derivative(self): 17 | derivative = Derivative(self.urn, self.token) 18 | manifest_items = derivative.read_svf_manifest_items() 19 | images = SVFImage.parse_images_from_derivative(derivative, manifest_items[0]) 20 | self.assertNotEqual(len(images), 0) 21 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_material.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from .context import SVFReader 4 | from .context import Auth 5 | from .context import SVFMaterials 6 | import os 7 | from .context import Derivative 8 | 9 | 10 | class TestMaterial(TestCase): 11 | def setUp(self): 12 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 13 | self.token = Auth().auth2leg() 14 | self.file_path = (r"./output/svfs/Resource/3D View/08f99ae5-b8be-4f8d-881b-128675723c10/Project " 15 | r"Completion/Materials.json.gz") 16 | 17 | def test_parse_materials_from_urn(self): 18 | materials = SVFMaterials.parse_materials_from_urn(self.urn, self.token) 19 | self.assertNotEqual(len(materials), 0) 20 | 21 | def test_parse_materials_from_manifest_item(self): 22 | derivative = Derivative(self.urn, self.token) 23 | manifest_items = derivative.read_svf_manifest_items() 24 | materials = SVFMaterials.parse_materials_from_manifest_item(derivative, manifest_items[0]) 25 | self.assertNotEqual(len(materials), 0) 26 | 27 | def test_read_from_file(self): 28 | self.assertTrue(os.path.exists(self.file_path)) 29 | materials = SVFMaterials.parse_materials_from_file(self.file_path) 30 | self.assertNotEqual(len(materials), 0) 31 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_mesh.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import SVFMesh 3 | from .context import Auth 4 | 5 | 6 | class TestMesh(TestCase): 7 | def setUp(self): 8 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 9 | self.token = Auth().auth2leg() 10 | self.file_path = r".\output\svfs\Resource\3D View\08f99ae5-b8be-4f8d-881b-128675723c10\Project Completion\0.pf" 11 | 12 | def test_parse_mesh_from_file(self): 13 | mesh = SVFMesh.parse_mesh_from_file(self.file_path) 14 | self.assertNotEqual(len(mesh), 0) 15 | 16 | def test_parse_mesh_from_urn(self): 17 | mesh = SVFMesh.parse_mesh_from_urn(self.urn, self.token) 18 | self.assertNotEqual(len(mesh), 0) 19 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_metadata.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from .context import Derivative 4 | from .context import SVFMetadata 5 | from .context import Auth 6 | 7 | 8 | class TestSVFMetadata(TestCase): 9 | def setUp(self): 10 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNA" 11 | self.token = Auth().auth2leg() 12 | 13 | def test_parse_metadata_from_urn(self): 14 | meta_datas = SVFMetadata.parse_metadata_from_urn(self.urn, self.token) 15 | self.assertNotEqual(len(meta_datas), 0) 16 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_prop_reader.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import PropReader 4 | from .context import Auth 5 | 6 | 7 | class TestPropDbReader(TestCase): 8 | def setUp(self): 9 | pass 10 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLkotQ2laSHpGVEd5LUEwLVJmaEVVTVE_dmVyc2lvbj04" 11 | self.token = Auth().auth2leg() 12 | self.prop_reader = PropReader(self.urn, self.token) 13 | 14 | def test_read_from_svf(self): 15 | path = r"C:\Users\vho2\AppData\Local\Temp\output\output\Resource\3D View\{3D} 960621\{3D}.svf" 16 | prop = PropReader.read_from_resource(path) 17 | child = prop.get_properties(1) 18 | self.assertNotEqual(prop, 0) 19 | 20 | def test_read_from_resource(self): 21 | path = r"C:\Users\vho2\AppData\Local\Temp\output\output\Resource" 22 | prop = PropReader.read_from_resource(path) 23 | self.assertNotEqual(prop.ids, 0) 24 | def test_enumerate_properties(self): 25 | properties = self.prop_reader.enumerate_properties(14) 26 | self.assertNotEqual(properties, 0) 27 | 28 | def test_get_recursive_ids(self): 29 | ids = self.prop_reader.get_recursive_ids([14, 15]) 30 | self.assertNotEqual(len(ids), 0) 31 | 32 | def test_get_all_properties_names(self): 33 | properties = self.prop_reader.get_all_properties_names() 34 | self.assertNotEqual(len(properties), 0) 35 | 36 | def test_get_properties(self): 37 | properties = self.prop_reader.get_properties(14) 38 | self.assertNotEqual(properties, 0) 39 | 40 | def test_get_all_properties(self): 41 | properties = self.prop_reader.get_all_properties(1) 42 | self.assertNotEqual(properties, 0) 43 | 44 | def test_get_entities_table(self): 45 | df = self.prop_reader.get_entities_table() 46 | self.assertNotEqual(df.empty, True) 47 | 48 | def test_get_values_table(self): 49 | df = self.prop_reader.get_values_table() 50 | self.assertNotEqual(df.empty, True) 51 | 52 | def test_get_attributes_table(self): 53 | df = self.prop_reader.get_attributes_table() 54 | self.assertNotEqual(df.empty, True) 55 | 56 | def test_get_avs_table(self): 57 | # TODO 58 | df = self.prop_reader.get_avs_table() 59 | self.assertNotEqual(df.empty, True) 60 | 61 | def test_get_offsets_table(self): 62 | df = self.prop_reader.get_offsets_table() 63 | self.assertNotEqual(df.empty, True) 64 | 65 | def test_get_property_values_by_names(self): 66 | values = self.prop_reader.get_property_values_by_names(["Comments", "name"]) 67 | self.assertNotEqual(len(values), 0) 68 | 69 | def test_get_property_values_by_display_names(self): 70 | values = self.prop_reader.get_property_values_by_display_names(["Category", "Name"]) 71 | self.assertNotEqual(len(values), 0) 72 | 73 | def test_get_instance(self): 74 | instance = self.prop_reader.get_instance(1) 75 | self.assertEquals(len(instance), 0) 76 | 77 | def test_get_children(self): 78 | children = self.prop_reader.get_children(1) 79 | self.assertNotEqual(len(children), 0) 80 | 81 | def test_get_parent(self): 82 | parent = self.prop_reader.get_parent(1) 83 | self.assertEquals(len(parent), 0) 84 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_prop_reader_cad.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import PropDbReaderCad 4 | from .context import Auth 5 | 6 | 7 | class TestPropDbReader(TestCase): 8 | def setUp(self): 9 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLm5KaEpjQkQ1UXd1bjlIV1ktNWViQmc_dmVyc2lvbj0x" 10 | self.token = Auth().auth2leg() 11 | self.prop_reader = PropDbReaderCad(self.urn, self.token) 12 | 13 | def test_get_document_info(self): 14 | document_info = self.prop_reader.get_document_info() 15 | self.assertIsNotNone(document_info) 16 | 17 | def test_get_all_layers(self): 18 | layers = self.prop_reader.get_all_layers() 19 | self.assertNotEqual(len(layers), 0) 20 | 21 | def test_get_all_categories(self): 22 | categories = self.prop_reader.get_all_categories() 23 | self.assertNotEqual(len(categories), 0) 24 | 25 | def test_get_all_data(self): 26 | data = self.prop_reader.get_all_data() 27 | self.assertIsNotNone(data) 28 | 29 | def test_get_data_by_category(self): 30 | df = self.prop_reader.get_data_by_category("Lines") 31 | self.assertNotEqual(df.empty, True) 32 | 33 | def test_get_data_by_categories(self): 34 | df = self.prop_reader.get_data_by_categories(["Lines", "Circles"]) 35 | self.assertNotEqual(df.empty, True) 36 | 37 | def test_get_data_by_categories_and_params(self): 38 | df = self.prop_reader.get_data_by_categories_and_params(["Lines", "Circles"], ["Name", "Layer", "Color", "type"]) 39 | self.assertNotEqual(df.empty, True) 40 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_prop_reader_navis.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | from .context import PropDbReaderNavis 3 | from .context import Auth 4 | 5 | 6 | class TestPropDbReaderNavis(TestCase): 7 | def setUp(self): 8 | self.token = Auth().auth2leg() 9 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk5Vd2lWVHljVDJ5N3RydVhSSGM0R3c_dmVyc2lvbj0x" 10 | self.prop_reader = PropDbReaderNavis(self.urn, self.token) 11 | 12 | def test_get_document_info(self): 13 | document_info = self.prop_reader.get_document_info() 14 | self.assertIsNotNone(document_info) 15 | 16 | def test_get_all_data(self): 17 | data = self.prop_reader.get_all_data() 18 | self.assertIsNotNone(data) 19 | 20 | def test_get_all_categories(self): 21 | categories = self.prop_reader.get_all_categories() 22 | self.assertIsNotNone(categories) 23 | 24 | def test_get_all_parameters(self): 25 | parameters = self.prop_reader.get_all_parameters() 26 | self.assertIsNotNone(parameters) 27 | 28 | def test_get_data_by_categories(self): 29 | df = self.prop_reader.get_data_by_categories(["Item", "Element"]) 30 | self.assertIsNotNone(df) 31 | 32 | def test_get_all_sources_files(self): 33 | sources = self.prop_reader.get_all_sources_files() 34 | self.assertIsNotNone(sources) 35 | 36 | def test_get_all_data_by_resources(self): 37 | data = self.prop_reader.get_all_data_resources() 38 | self.assertIsNotNone(data) 39 | 40 | def test_get_data_by_resources_categories(self): 41 | data = self.prop_reader.get_data_resources_by_categories(["Element"]) 42 | self.assertIsNotNone(data) 43 | 44 | def test_get_data_by_category(self): 45 | data = self.prop_reader.get_data_by_category("Element") 46 | self.assertIsNotNone(data) 47 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_svf_reader.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from .context import SVFReader 4 | from .context import Auth 5 | import os 6 | 7 | 8 | class TestSVFReader(TestCase): 9 | def setUp(self): 10 | self.urn = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLm5KaEpjQkQ1UXd1bjlIV1ktNWViQmc_dmVyc2lvbj0x" 11 | self.token = Auth().auth2leg() 12 | self.reader = SVFReader(self.urn, self.token) 13 | 14 | def test_read_contents(self): 15 | contents = self.reader.read_contents() 16 | self.assertTrue(len(contents) > 0) 17 | 18 | def test_read_contents_manifest(self): 19 | manifest_items = self.reader.read_svf_manifest_items() 20 | contents = self.reader.read_contents(manifest_items[0]) 21 | self.assertTrue(len(contents) > 0) 22 | 23 | def test_read_svf(self): 24 | resources = self.reader.read_sources() 25 | self.assertTrue(len(resources) > 0) 26 | 27 | def test_read_fragment(self): 28 | fragments = self.reader.read_fragments() 29 | self.assertTrue(len(fragments) > 0) 30 | 31 | def test_read_fragment_item(self): 32 | manifest_items = self.reader.read_svf_manifest_items() 33 | fragments = self.reader.read_fragments(manifest_items[0]) 34 | self.assertTrue(len(fragments) > 0) 35 | 36 | def test_read_geometries(self): 37 | geometries = self.reader.read_geometries() 38 | self.assertTrue(len(geometries) > 0) 39 | 40 | def test_read_geometries_item(self): 41 | manifest_items = self.reader.read_svf_manifest_items() 42 | geometries = self.reader.read_geometries(manifest_items[0]) 43 | self.assertTrue(len(geometries) > 0) 44 | 45 | def test_read_meshes(self): 46 | meshes = self.reader.read_meshes() 47 | self.assertTrue(len(meshes) > 0) 48 | 49 | def test_read_meshes_item(self): 50 | manifest_items = self.reader.read_svf_manifest_items() 51 | meshes = self.reader.read_meshes(manifest_items[0]) 52 | self.assertTrue(len(meshes) > 0) 53 | 54 | def test_read_properties(self): 55 | prop_reader = self.reader.read_properties() 56 | self.assertTrue(len(prop_reader.attrs) > 0) 57 | self.assertTrue(len(prop_reader.vals) > 0) 58 | 59 | def test_read_materials(self): 60 | materials = self.reader.read_materials() 61 | self.assertTrue(len(materials) > 0) 62 | 63 | def test_read_images(self): 64 | images = self.reader.read_images() 65 | self.assertTrue(len(images) > 0) 66 | 67 | def test_read_meta_data(self): 68 | meta_data = self.reader.read_meta_data() 69 | self.assertTrue(len(meta_data) > 0) 70 | 71 | def test_read_materials_item(self): 72 | manifest_items = self.reader.read_svf_manifest_items() 73 | materials = self.reader.read_materials(manifest_items[0]) 74 | self.assertTrue(len(materials) > 0) 75 | 76 | def test_download_svf(self): 77 | folder = r"./output/svfs/" 78 | self.reader.download(folder) 79 | self.assertTrue(len(os.listdir(folder)) > 0) 80 | 81 | def test_read_svf_manifest_items(self): 82 | manifest_items = self.reader.read_svf_manifest_items() 83 | self.assertTrue(len(manifest_items) > 0) 84 | -------------------------------------------------------------------------------- /APSToolkitPython/src/test/test_token.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import os 3 | from .context import Token 4 | from .context import RevokeType 5 | from .context import ClientType 6 | from .context import Auth 7 | import datetime 8 | import time 9 | 10 | 11 | class TestAuth(TestCase): 12 | 13 | def test_revoke_token_private(self): 14 | token = Auth().auth2leg() 15 | os.environ['APS_ACCESS_TOKEN'] = token.access_token 16 | token = Token.revoke(RevokeType.TOKEN_PRIVATE) 17 | self.assertNotEqual(token.access_token, "") 18 | 19 | def test_revoke_refresh_token_private(self): 20 | token = Token.revoke(RevokeType.REFRESH_TOKEN_PRIVATE) 21 | self.assertNotEqual(token.access_token, "") 22 | 23 | def test_introspect(self): 24 | token = Auth().auth2leg() 25 | token.set_env() 26 | result = token.introspect(ClientType.PRIVATE) 27 | self.assertNotEqual(result, "") 28 | 29 | def test_is_expired(self): 30 | token = Auth().auth2leg() 31 | # downtime to 1 minutes 32 | token.expires_in = time.time() - 1 * 60 33 | self.assertTrue(token.is_expired()) 34 | token.expires_in = time.time() + 1 * 60 35 | self.assertFalse(token.is_expired()) 36 | 37 | def test_refresh_token(self): 38 | token = Auth().auth3leg() 39 | token.refresh() 40 | token.refresh() 41 | self.assertNotEqual(token.access_token, "") 42 | -------------------------------------------------------------------------------- /APSToolkitUnit/APSToolkitUnit.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | ForgeToolkitUnit 5 | ForgeToolkitUnit 6 | chuongmep.com 7 | Copyright © 2023 8 | 1.0.0.0 9 | 1.0.0.0 10 | true 11 | net6 12 | ForgeToolkitUnit 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | PreserveNewest 30 | 31 | 32 | PreserveNewest 33 | 34 | 35 | PreserveNewest 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | PreserveNewest 42 | 43 | 44 | PreserveNewest 45 | 46 | 47 | PreserveNewest 48 | 49 | 50 | PreserveNewest 51 | 52 | 53 | PreserveNewest 54 | 55 | 56 | PreserveNewest 57 | 58 | 59 | PreserveNewest 60 | 61 | 62 | PreserveNewest 63 | 64 | 65 | PreserveNewest 66 | 67 | 68 | -------------------------------------------------------------------------------- /APSToolkitUnit/AuthTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using APSToolkit; 4 | using Autodesk.Forge; 5 | using NUnit.Framework; 6 | 7 | namespace ForgeToolkitUnit; 8 | 9 | public class AuthTest 10 | { 11 | private static Token Token { get; set; } 12 | private Auth Auth { get; set; } 13 | [SetUp] 14 | public void Setup() 15 | { 16 | Auth = new Auth(); 17 | } 18 | 19 | [Test] 20 | public void TestAuthentication2Leg() 21 | { 22 | Token = Auth.Get2LeggedToken().Result; 23 | Assert.IsNotEmpty(Token.AccessToken); 24 | } 25 | [Test] 26 | public void TestExpireTime() 27 | { 28 | Token = Auth.Get2LeggedToken().Result; 29 | bool isExpired = Token.IsExpired(); 30 | Assert.IsFalse(isExpired); 31 | isExpired = Token.IsExpired(70); 32 | Assert.IsTrue(isExpired); 33 | } 34 | [Test] 35 | public void TestAuthentication3Leg() 36 | { 37 | Token = Auth.Get3LeggedToken().Result; 38 | Assert.IsNotNull(Token.AccessToken); 39 | Assert.IsNotEmpty(Token.AccessToken); 40 | } 41 | [Test] 42 | public Task TestAuthentication3LegPkce() 43 | { 44 | string clientId = Environment.GetEnvironmentVariable("APS_CLIENT_ID_PKCE", EnvironmentVariableTarget.User); 45 | Auth = new Auth(clientId); 46 | Token = Auth.Get3LeggedTokenPkce().Result; 47 | Assert.IsNotNull(Token.AccessToken); 48 | Assert.IsNotEmpty(Token.RefreshToken); 49 | return Task.CompletedTask; 50 | } 51 | [Test] 52 | public Task TestRefresh3LegToken() 53 | { 54 | var clientID = Environment.GetEnvironmentVariable("APS_CLIENT_ID", EnvironmentVariableTarget.User); 55 | var clientSecret = Environment.GetEnvironmentVariable("APS_CLIENT_SECRET", EnvironmentVariableTarget.User); 56 | var refreshToken = Environment.GetEnvironmentVariable("APS_REFRESH_TOKEN", EnvironmentVariableTarget.User); 57 | if (string.IsNullOrEmpty(clientID)) Assert.Fail("Missing APS_CLIENT_ID environment variable."); 58 | if (string.IsNullOrEmpty(clientSecret)) Assert.Fail("Missing APS_CLIENT_SECRET environment variable."); 59 | if (string.IsNullOrEmpty(refreshToken)) Assert.Fail("Missing APS_REFRESH_TOKEN environment variable."); 60 | Scope[] scope = new Scope[] 61 | {Scope.DataRead, Scope.DataWrite, Scope.DataCreate, Scope.BucketRead, Scope.BucketCreate}; 62 | var Leg3Token = Auth.Refresh3LeggedToken(clientID, clientSecret, scope).Result; 63 | Assert.IsNotNull(Leg3Token); 64 | return Task.CompletedTask; 65 | } 66 | 67 | [Test] 68 | public void TestTokenExpired() 69 | { 70 | Token = Auth.Get2LeggedToken().Result; 71 | Assert.IsFalse(Token.IsExpired()); 72 | } 73 | } -------------------------------------------------------------------------------- /APSToolkitUnit/Base64Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using APSToolkit.Utils; 3 | using NUnit.Framework; 4 | 5 | namespace ForgeToolkitUnit; 6 | 7 | public class Base64Test 8 | { 9 | [Test] 10 | [TestCase("urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=17")] 11 | public void ToBase64StringTest(string versionId) 12 | { 13 | string expected = "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0xNw=="; 14 | string actual = Base64Convert.ToBase64String(versionId); 15 | Assert.AreEqual(expected, actual); 16 | } 17 | [Test] 18 | [TestCase("dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0xNw==")] 19 | public void FromBase64StringTest(string base64String) 20 | { 21 | string expected = "urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=17"; 22 | string actual = Base64Convert.FromBase64String(base64String); 23 | Assert.AreEqual(expected, actual); 24 | } 25 | [Test] 26 | [TestCase("urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=26","dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNg")] 27 | [TestCase("urn:adsk.wipprod:fs.file:vf.DjXtlXoJQyS6D1R-gRhI8A?version=5","dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLkRqWHRsWG9KUXlTNkQxUi1nUmhJOEE_dmVyc2lvbj01")] 28 | public void VersionIdToUrnTest(string versionId,string expectation) 29 | { 30 | string actual = Base64Convert.ToBase64String(versionId); 31 | // just get 82 characters 32 | actual = actual.Substring(0, 82); 33 | Assert.AreEqual(expectation, actual); 34 | } 35 | 36 | [Test] 37 | [TestCase("dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLk9kOHR4RGJLU1NlbFRvVmcxb2MxVkE_dmVyc2lvbj0yNg","urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=26")] 38 | public void UrnToVersionIdTest(string urn,string expectation) 39 | { 40 | // add 2 characters to make it 84 characters 41 | urn += "=="; 42 | string actual = Base64Convert.FromBase64String(urn); 43 | Console.WriteLine(actual); 44 | Assert.AreEqual(expectation, actual); 45 | } 46 | } -------------------------------------------------------------------------------- /APSToolkitUnit/BucketTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using APSToolkit; 4 | using APSToolkit.Database; 5 | using Autodesk.Forge.Model; 6 | using NUnit.Framework; 7 | 8 | namespace ForgeToolkitUnit; 9 | 10 | public class BucketTest 11 | { 12 | [SetUp] 13 | public void Setup() 14 | { 15 | var auth = new Auth(); 16 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 17 | } 18 | [Test] 19 | [TestCase("test_data")] 20 | public void CreateBucketTest(string bucketName) 21 | { 22 | BucketStorage bucketStorage = new BucketStorage(Settings.Token2Leg); 23 | var bucket = bucketStorage.CreateBucket(bucketName,"US",PostBucketsPayload.PolicyKeyEnum.Temporary); 24 | Assert.IsNotNull(bucket); 25 | } 26 | [Test] 27 | [TestCase("test_data","Resources/model.rvt")] 28 | public void UploadFileToBucket(string bucketName,string filePath) 29 | { 30 | BucketStorage bucketStorage = new BucketStorage(Settings.Token2Leg); 31 | var bucket = bucketStorage.UploadFileToBucket(bucketName,filePath); 32 | Assert.IsNotNull(bucket); 33 | } 34 | [Test] 35 | [TestCase("test_data","model_rvt.sdb")] 36 | public void GetFile(string bucketName,string filePath) 37 | { 38 | BucketStorage bucketStorage = new BucketStorage(); 39 | var bucket = bucketStorage.GetFileFromBucket(bucketName,filePath); 40 | Assert.IsNotNull(bucket); 41 | } 42 | [Test] 43 | [TestCase("test_data","model.rvt")] 44 | public void GetFileSignedUrl(string bucketName,string filePath) 45 | { 46 | BucketStorage bucketStorage = new BucketStorage(); 47 | var url = bucketStorage.GetFileSignedUrl(bucketName,filePath); 48 | Console.WriteLine(url); 49 | Assert.IsNotNull(url); 50 | } 51 | [Test] 52 | [TestCase("test_data","model_rvt.sdb")] 53 | public void DeleteFile(string bucketName,string filePath) 54 | { 55 | BucketStorage bucketStorage = new BucketStorage(); 56 | bucketStorage.DeleteFile(bucketName,filePath); 57 | } 58 | [Test] 59 | [TestCase("test_data")] 60 | public void Delete(string bucketName) 61 | { 62 | BucketStorage bucketStorage = new BucketStorage(); 63 | bucketStorage.DeleteBucket( bucketName); 64 | } 65 | } -------------------------------------------------------------------------------- /APSToolkitUnit/CompareTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text.Json.JsonDiffPatch; 5 | using System.Text.Json.Nodes; 6 | using APSToolkit; 7 | using Newtonsoft.Json; 8 | using NUnit.Framework; 9 | 10 | namespace ForgeToolkitUnit; 11 | 12 | public class CompareTest 13 | { 14 | [SetUp] 15 | public void SetUp() 16 | { 17 | var auth = new Auth(); 18 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 19 | } 20 | 21 | [Test] 22 | public void CompareExecute() 23 | { 24 | string path1 = @"D:\API\Forge\ExploreForgeGeometry\APSToolkitUnit\bin\Debug\net6\version9.json"; 25 | string path2 = @"D:\API\Forge\ExploreForgeGeometry\APSToolkitUnit\bin\Debug\net6\version10.json"; 26 | // get string json path1 27 | var stringJsonPath1 = System.IO.File.ReadAllText(path1); 28 | // get string json path2 29 | var stringJsonPath2 = System.IO.File.ReadAllText(path2); 30 | List roomDatas = JsonConvert.DeserializeObject>(stringJsonPath1); 31 | RoomData enumerable = roomDatas.FirstOrDefault(x => x.Id == "3026299"); 32 | List roomDatas2 = JsonConvert.DeserializeObject>(stringJsonPath2); 33 | JsonNode node1 = JsonNode.Parse(stringJsonPath1); 34 | JsonNode node2 = JsonNode.Parse(stringJsonPath2); 35 | JsonNode diff = node1.Diff(node2); 36 | Console.WriteLine(diff); 37 | } 38 | } 39 | public class RoomData 40 | { 41 | public string Id { get; set; } 42 | public string UniqueId { get; set; } 43 | public Dictionary Parameters { get; set; } 44 | public List Boundaries { get; set; } 45 | } 46 | public class RoomPoint 47 | { 48 | public double X { get; set; } 49 | public double Y { get; set; } 50 | public double Z { get; set; } 51 | 52 | public RoomPoint(double x, double y, double z) 53 | { 54 | this.X = x; 55 | this.Y = y; 56 | this.Z = z; 57 | } 58 | } -------------------------------------------------------------------------------- /APSToolkitUnit/CsvTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using NUnit.Framework; 3 | 4 | namespace ForgeToolkitUnit; 5 | 6 | public class CsvTest 7 | { 8 | public void Setup() 9 | { 10 | } 11 | 12 | [Test] 13 | public void ExportFromObjectTest() 14 | { 15 | List data = new List(); 16 | // try add data 17 | data.Add(new { Name = "Chuong", Age = 30 }); 18 | data.Add(new { Name = "Chuong1", Age = 31 }); 19 | data.Add(new { Name = "Chuong2", Age = 32 }); 20 | data.Add(new { Name = "Chuong3", Age = 34 }); 21 | APSToolkit.Utils.CsvHelper.ExportToCsv(data,"result.csv"); 22 | } 23 | 24 | [Test] 25 | public void ExportFromDatatableTest() 26 | { 27 | var dataTable = new System.Data.DataTable(); 28 | dataTable.Columns.Add("Name", typeof(string)); 29 | dataTable.Columns.Add("Age", typeof(int)); 30 | dataTable.Rows.Add("Chuong", 30); 31 | dataTable.Rows.Add("Chuong1", 31); 32 | dataTable.Rows.Add("Chuong2", 32); 33 | dataTable.Rows.Add("Chuong3", 34); 34 | APSToolkit.Utils.CsvHelper.ExportToCsv(dataTable,"result.csv"); 35 | } 36 | [Test] 37 | public void ReadFromCsvTest() 38 | { 39 | var data = APSToolkit.Utils.CsvHelper.ReadFromCsv("result.csv"); 40 | Assert.IsNotNull(data); 41 | } 42 | } -------------------------------------------------------------------------------- /APSToolkitUnit/DataFrameTest.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using System.Data.Common; 3 | using APSToolkit.Utils; 4 | using Microsoft.Data.Analysis; 5 | using NUnit.Framework; 6 | using DataFrame = Microsoft.Data.Analysis.DataFrame; 7 | 8 | namespace ForgeToolkitUnit; 9 | 10 | public class DataFrameTest 11 | { 12 | [SetUp] 13 | public void SetUp() 14 | { 15 | 16 | } 17 | [Test] 18 | public void DataTableToDataFrame() 19 | { 20 | DataTable dt = new DataTable(); 21 | dt.Columns.Add("Id", typeof(int)); 22 | dt.Columns.Add("Name", typeof(string)); 23 | dt.Columns.Add("Data", typeof(byte[])); 24 | dt.Rows.Add(1, "Name1", new byte[] { 1, 2, 3 }); 25 | dt.Rows.Add(2, "Name2", new byte[] { 4, 5, 6 }); 26 | dt.Rows.Add(3, "Name3", new byte[] { 7, 8, 9 }); 27 | DataFrame dataFrame = dt.ToDataFrame(); 28 | Assert.AreEqual(3, dataFrame.Rows.Count); 29 | Assert.AreEqual(3, dataFrame.Columns.Count); 30 | } 31 | 32 | [Test] 33 | public void LoadFromDataTableTest() 34 | { 35 | DataTable dt = new DataTable(); 36 | dt.Columns.Add("Id", typeof(int)); 37 | dt.Columns.Add("Name", typeof(string)); 38 | dt.Columns.Add("Data", typeof(byte[])); 39 | dt.Rows.Add(1, "Name1", new byte[] { 1, 2, 3 }); 40 | dt.Rows.Add(2, "Name2", new byte[] { 4, 5, 6 }); 41 | dt.Rows.Add(3, "Name3", new byte[] { 7, 8, 9 }); 42 | DataFrame dataFrame = APSToolkit.Utils.DataFrame.LoadFromDataTable(dt); 43 | Assert.AreEqual(3, dataFrame.Rows.Count); 44 | Assert.AreEqual(3, dataFrame.Columns.Count); 45 | } 46 | [Test] 47 | [TestCase("./Resources/result.parquet")] 48 | public void LoadFromParquetTest(string parquet) 49 | { 50 | DataFrame dataFrame = APSToolkit.Utils.DataFrame.LoadFromParquet(parquet); 51 | Assert.AreEqual(3, dataFrame.Rows.Count); 52 | } 53 | 54 | [Test] 55 | [TestCase("./Resources/result.xlsx","Walls")] 56 | public void LoadFromExcelTest(string excelPath,string sheetName) 57 | { 58 | DataFrame dataFrame = APSToolkit.Utils.DataFrame.LoadFromExcel(excelPath,sheetName); 59 | Assert.AreNotEqual(0, dataFrame.Rows.Count); 60 | Assert.AreNotEqual(0, dataFrame.Columns.Count); 61 | } 62 | } -------------------------------------------------------------------------------- /APSToolkitUnit/DerivativeTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using APSToolkit; 4 | using NUnit.Framework; 5 | 6 | namespace ForgeToolkitUnit 7 | { 8 | [TestFixture] 9 | public class DerivativeTest 10 | { 11 | [SetUp] 12 | public void SetUp() 13 | { 14 | var auth = new Auth(); 15 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 16 | } 17 | 18 | /// 19 | /// Test Download Full SVF Data Model 20 | /// 21 | /// URN Model 22 | /// folder to dowload 23 | [Test] 24 | [TestCase("dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjEzLVdVN2NBU2kyQThVdUNqQVFmUkE_dmVyc2lvbj0x", "result")] 25 | public async Task TestDownloadSVF(string urn, string folder) 26 | { 27 | if (!System.IO.Directory.Exists(folder)) 28 | { 29 | System.IO.Directory.CreateDirectory(folder); 30 | } 31 | 32 | Console.WriteLine("Start check data process export svf"); 33 | await Derivatives.SaveFileSvfAsync(folder, urn, Settings.Token2Leg.AccessToken); 34 | Console.WriteLine("Done process save data svf"); 35 | // check size fodler > 0 36 | Assert.IsTrue(System.IO.Directory.GetFiles(folder).Length > 0); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /APSToolkitUnit/ExcelTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using APSToolkit.DesignAutomation; 3 | using APSToolkit.Utils; 4 | using NUnit.Framework; 5 | 6 | namespace ForgeToolkitUnit; 7 | 8 | public class ExcelTest 9 | { 10 | [Test] 11 | public void Setup() 12 | { 13 | 14 | } 15 | [Test] 16 | public void ReadExcelTest() 17 | { 18 | string excelPath = @"./Resources/Result.xlsx"; 19 | object[][] data = ExcelUtils.ReadDataFromExcel(excelPath,"Walls"); 20 | Assert.IsNotEmpty(data); 21 | } 22 | [Test] 23 | public void ReadExcelByColumnNameTest() 24 | { 25 | string excelPath = @"./Resources/Result.xlsx"; 26 | List data = ExcelUtils.ReadDataByColumnName(excelPath,"Walls","Assembly Code"); 27 | Assert.IsNotEmpty(data); 28 | } 29 | [Test] 30 | public void ReadParamsTest() 31 | { 32 | string excelPath = @"./Resources/Result.xlsx"; 33 | List data = ExcelUtils.ReadParams(excelPath,"Walls","Assembly Code"); 34 | Assert.IsNotEmpty(data); 35 | } 36 | } -------------------------------------------------------------------------------- /APSToolkitUnit/FragmentsTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using APSToolkit; 5 | using APSToolkit.Schema; 6 | using Newtonsoft.Json; 7 | using NUnit.Framework; 8 | 9 | namespace ForgeToolkitUnit; 10 | 11 | public class FragmentsTest 12 | { 13 | [SetUp] 14 | public void Setup() 15 | { 16 | var auth = new Auth(); 17 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 18 | } 19 | 20 | /// 21 | /// str 22 | /// 23 | /// 24 | [Test] 25 | [TestCase(Settings._RevitTestUrn)] 26 | public async Task TestGetFragments(string urn) 27 | { 28 | var fragments = await Derivatives.ReadFragmentsRemoteAsync(urn, Settings.Token2Leg.AccessToken); 29 | Assert.AreNotEqual(0, fragments.Count); 30 | } 31 | 32 | [Test] 33 | [TestCase(Settings._RevitTestUrn)] 34 | public async Task GetElementLocation(string urn) 35 | { 36 | Dictionary fragments = await Derivatives.ReadFragmentsRemoteAsync(urn, Settings.Token2Leg.AccessToken); 37 | // flatten the fragments to list of svf fragments 38 | List svfFragments = fragments.Values.SelectMany(x => x).ToList(); 39 | // save to location with unique dbid and value 40 | Dictionary locations = new Dictionary(); 41 | foreach (ISvfFragment svfFragment in svfFragments) 42 | { 43 | if (svfFragment.dbID == 0) continue; 44 | if(svfFragment.transform==null) continue; 45 | locations.TryAdd(svfFragment.dbID, svfFragment); 46 | } 47 | // sort by dbid 48 | locations = locations.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); 49 | // save to json string 50 | string json = JsonConvert.SerializeObject(locations); 51 | Assert.AreNotEqual(0, json.Length); 52 | } 53 | [Test] 54 | [TestCase(Settings._RevitTestUrn)] 55 | public async Task GetElementGeometry(string urn) 56 | { 57 | Dictionary fragments = await Derivatives.ReadGeometriesRemoteAsync(urn, Settings.Token2Leg.AccessToken); 58 | // flatten the fragments to list of svf fragments 59 | List svfFragments = fragments.Values.SelectMany(x => x).ToList(); 60 | // save to location with unique dbid and value 61 | Dictionary locations = new Dictionary(); 62 | foreach (ISvfGeometryMetadata svfFragment in svfFragments) 63 | { 64 | if (svfFragment.entityID == 0) continue; 65 | locations.TryAdd(svfFragment.entityID, svfFragment); 66 | } 67 | // sort by dbid 68 | locations = locations.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); 69 | // save to json string 70 | string json = JsonConvert.SerializeObject(locations); 71 | Assert.AreNotEqual(0, json.Length); 72 | } 73 | 74 | [Test] 75 | [TestCase("dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLm84d0tfSUNjUlphcHlhbUp5MmtFVmc_dmVyc2lvbj03")] 76 | public async Task TestGetBoundingBoxByFragment(string urn) 77 | { 78 | Dictionary fragments = await Derivatives.ReadFragmentsRemoteAsync(urn,Settings. Token2Leg.AccessToken); 79 | string phase = fragments.Keys.FirstOrDefault(x => x.Contains("New Construction")); 80 | ISvfFragment[] svfFragments = fragments[phase]; 81 | ISvfFragment[] array = svfFragments.Where(x => x.dbID == 17778).ToArray(); 82 | Assert.AreNotEqual(0, array.Length); 83 | // save to json string 84 | string json = JsonConvert.SerializeObject(array); 85 | Assert.AreNotEqual(0, json.Length); 86 | } 87 | 88 | 89 | } -------------------------------------------------------------------------------- /APSToolkitUnit/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | [assembly: AssemblyTrademark("")] 4 | [assembly: AssemblyCulture("")] 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("44176454-3674-4C4B-8147-F7FE661E20D9")] 13 | -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/DataSetParameterAddIn.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/DataSetParameterAddIn.zip -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/model.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/model.rvt -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/model_ifc.sdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/model_ifc.sdb -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/model_nwc.sdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/model_nwc.sdb -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/model_rvt.sdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/model_rvt.sdb -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_attrs.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_attrs.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_avs.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_avs.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_ids.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_ids.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_offs.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_offs.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_vals.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_vals.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/objects_viewables.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/objects_viewables.json.gz -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/result.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/result.parquet -------------------------------------------------------------------------------- /APSToolkitUnit/Resources/result.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/APSToolkitUnit/Resources/result.xlsx -------------------------------------------------------------------------------- /APSToolkitUnit/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using APSToolkit; 4 | 5 | namespace ForgeToolkitUnit; 6 | 7 | public static class Settings 8 | { 9 | public const string _NavisUrn = 10 | "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmZqSkFRUUx6U3BxLTR3eWRPdG9DMGc_dmVyc2lvbj0x"; 11 | 12 | public const string _RevitTestUrn = 13 | "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLkotQ2laSHpGVEd5LUEwLVJmaEVVTVE_dmVyc2lvbj04"; 14 | 15 | public const string _IfcUrn = 16 | "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjEzLVdVN2NBU2kyQThVdUNqQVFmUkE_dmVyc2lvbj0x"; 17 | 18 | // real model 19 | public const string _RevitRealUrn = 20 | "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLm84d0tfSUNjUlphcHlhbUp5MmtFVmc_dmVyc2lvbj03"; 21 | 22 | public const string HubId = "b.1715cf2b-cc12-46fd-9279-11bbc47e72f6"; 23 | 24 | // public const string ProjectId = "b.ec0f8261-aeca-4ab9-a1a5-5845f952b17d"; 25 | public const string ProjectId = "b.ca790fb5-141d-4ad5-b411-0461af2e9748"; 26 | 27 | public const string ModelGuid = "de840e8a-ab89-4833-ae8e-c47bc6ca94d8"; 28 | 29 | public const string ProjectGuid = "de37dbf5-20d5-46be-b488-fec29e3b436e"; 30 | // for real :SG_Meta: b.ca790fb5-141d-4ad5-b411-0461af2e9748 31 | 32 | public const string FolderId = "urn:adsk.wipprod:fs.folder:co.2yCTHGmWSvSCzlaIzdrFKA"; 33 | 34 | // Cloud Model Urn Myhouse.Rvt 35 | public const string ItemId = "urn:adsk.wipprod:dm.lineage:Od8txDbKSSelToVg1oc1VA"; 36 | public const string VersionId = "urn:adsk.wipprod:fs.file:vf.Od8txDbKSSelToVg1oc1VA?version=13"; 37 | public const string FileName = "MyHouse.rvt"; 38 | 39 | public static Token Token2Leg; 40 | public static Token Token3Leg; 41 | 42 | public static IEnumerable UrnTestCases() 43 | { 44 | yield return new object[] {_NavisUrn}; 45 | yield return new object[] {_RevitRealUrn}; 46 | } 47 | public static IEnumerable RevitTestUrn() 48 | { 49 | yield return new object[] {_RevitTestUrn}; 50 | } 51 | public static IEnumerable RevitRealUrn() 52 | { 53 | yield return new object[] {_RevitRealUrn}; 54 | } 55 | public static IEnumerable IFCTestUrn() 56 | { 57 | yield return new object[] {_IfcUrn}; 58 | } 59 | public static IEnumerable NavisTestUrn() 60 | { 61 | yield return new object[] {_NavisUrn}; 62 | } 63 | } -------------------------------------------------------------------------------- /APSToolkitUnit/SvfReaderTest.cs: -------------------------------------------------------------------------------- 1 | using APSToolkit; 2 | using APSToolkit.Schema; 3 | using APSToolkit.Utils; 4 | using NUnit.Framework; 5 | 6 | namespace ForgeToolkitUnit; 7 | 8 | public class SvfReaderTest 9 | { 10 | [SetUp] 11 | public void Setup() 12 | { 13 | var auth = new Auth(); 14 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 15 | } 16 | 17 | [Test] 18 | public void ReadSvfTest() 19 | { 20 | string path = @"\MyRoom.svf"; 21 | ISvfContent svfContent = SvfReader.ReadSvf(path); 22 | svfContent.fragments.ExportToCsv("result.csv"); 23 | Assert.AreNotEqual(0, svfContent.fragments.Length); 24 | Assert.AreNotEqual(0, svfContent.geometries.Length); 25 | } 26 | } -------------------------------------------------------------------------------- /APSToolkitUnit/UnitsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Threading.Tasks; 5 | using APSToolkit.Utils; 6 | using Autodesk.Forge; 7 | using NUnit.Framework; 8 | 9 | namespace ForgeToolkitUnit; 10 | 11 | public class UnitsTest 12 | { 13 | private static string Token { get; set; } 14 | 15 | [SetUp] 16 | public void Setup() 17 | { 18 | } 19 | 20 | [Test] 21 | public void GetAllUnits() 22 | { 23 | List unitsDatas = UnitUtils.GetAllUnits(); 24 | Assert.AreNotEqual(0, unitsDatas.Count); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /APSToolkitUnit/VersionTest.cs: -------------------------------------------------------------------------------- 1 | using APSToolkit; 2 | using Autodesk.Forge; 3 | using NUnit.Framework; 4 | 5 | namespace ForgeToolkitUnit; 6 | 7 | public class VersionTest 8 | { 9 | public Token Token { get; set; } 10 | [SetUp] 11 | public void Setup() 12 | { 13 | var auth = new Auth(); 14 | Settings.Token2Leg = auth.Get2LeggedToken().Result; 15 | } 16 | 17 | [Test] 18 | [TestCase("b.ca790fb5-141d-4ad5-b411-0461af2e9748","urn:adsk.wipprod:dm.lineage:HX2O7xKUQfukJ_hgHsrX_A")] 19 | // [TestCase("b.ca790fb5-141d-4ad5-b411-0461af2e9748", "urn:adsk.wipprod:fs.file:vf.HX2O7xKUQfukJ_hgHsrX_A",32,32)] 20 | public void TestGetInfoVersion(string projectId,string itemid) 21 | { 22 | VersionsApi versionsApi = new VersionsApi(); 23 | versionsApi.Configuration.AccessToken = Token.AccessToken; 24 | ItemsApi itemsApi = new ItemsApi(); 25 | itemsApi.Configuration.AccessToken = Token.AccessToken; 26 | dynamic versions = itemsApi.GetItemVersions(projectId, itemid); 27 | string versionId = versions.data[0].id; 28 | var version = versionsApi.GetVersion(projectId, versionId); 29 | string modelName = version.data.attributes.displayName; 30 | dynamic latestVersion = version.data.attributes.versionNumber; 31 | Assert.IsNotEmpty(versionId); 32 | Assert.IsNotEmpty(version); 33 | Assert.IsNotEmpty(modelName); 34 | Assert.IsNotEmpty(latestVersion); 35 | } 36 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | #### Contributions are more than welcome! Please work in the dev branch to do so: 4 | 5 | - Create or update your own fork of this repo under your GitHub account. 6 | - Checkout to the ``dev`` branch. 7 | - In the dev branch, implement and test you changes specific to the feature. 8 | - Build the project and make sure everything works. 9 | - Create well-documented commits of your changes. 10 | - Submit a pull request to the origin:dev branch. 11 | 12 | #### Build 13 | 14 | Debugging: 15 | 16 | - Run **Debug Profile** in Visual Studio or **Run Configuration** in JetBrains Rider. The required files have been added. All project files will be automatically copied to the Revit plugins folder. 17 | 18 | Creating a package: 19 | 20 | - Open the terminal of your IDE. 21 | - Install Nuke global tools `dotnet tool install Nuke.GlobalTool --global`. 22 | - Run `nuke` command. 23 | - The generated package will be in the **output** folder. 24 | 25 | --- 26 | #### Please avoid: 27 | 28 | - Lots of unrelated changes in one commit. 29 | - Modifying files that are not directly related to the feature you implement. -------------------------------------------------------------------------------- /ExportUnitAddin/ExportUnitAddin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net48 5 | enable 6 | disable 7 | latest 8 | x64 9 | CS0618;CS8618 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ExportUnitAddin/ExportUnitCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Text; 3 | using System.Text.RegularExpressions; 4 | using Autodesk.Revit.Attributes; 5 | using Autodesk.Revit.DB; 6 | using Autodesk.Revit.UI; 7 | using Newtonsoft.Json; 8 | 9 | namespace ExportUnitAddin; 10 | 11 | [Transaction(TransactionMode.Manual)] 12 | public class ExportUnitCommand : IExternalCommand 13 | { 14 | public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) 15 | { 16 | IList forgeTypeIds = UnitUtils.GetAllUnits(); 17 | List UnitDict = new List(); 18 | foreach (var forgeTypeId in forgeTypeIds) 19 | { 20 | // get label symbol 21 | var symbol = FormatOptions 22 | .GetValidSymbols(forgeTypeId).FirstOrDefault(x => x.Empty() == false); 23 | if (symbol != null) 24 | { 25 | string labelForSymbol = LabelUtils.GetLabelForSymbol(symbol); 26 | // pattent to split version and string : 27 | // e.g : autodesk.unit.unit:britishThermalUnits-1.0.1 => autodesk.unit.unit:britishThermalUnits-1.0.1 and 1.0.1 28 | var pattern = @"(.*)(-)(.*)"; 29 | var match = Regex.Match(forgeTypeId.TypeId, pattern); 30 | UnitsData unitsData = new UnitsData(); 31 | unitsData.UnitLabel = labelForSymbol; 32 | unitsData.TypeId = match.Groups[1].Value; 33 | unitsData.Version = match.Groups[3].Value; 34 | UnitDict.Add(unitsData); 35 | } 36 | } 37 | // save to txt and open 38 | string path = Path.Combine(Path.GetTempPath(), "units.json"); 39 | // save list object to json 40 | string json = JsonConvert.SerializeObject(UnitDict,Newtonsoft.Json.Formatting.Indented); 41 | File.WriteAllText(path, json, Encoding.UTF8); 42 | Process.Start(path); 43 | return Result.Succeeded; 44 | } 45 | } 46 | public class UnitsData 47 | { 48 | public string TypeId { get; set; } 49 | public string UnitLabel { get; set; } 50 | public string Version { get; set; } 51 | } -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | :; set -eo pipefail 2 | :; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | :; ${SCRIPT_DIR}/build.sh "$@" 4 | :; exit $? 5 | 6 | @ECHO OFF 7 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* 8 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] 4 | [string[]]$BuildArguments 5 | ) 6 | 7 | Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" 8 | 9 | Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } 10 | $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 11 | 12 | ########################################################################### 13 | # CONFIGURATION 14 | ########################################################################### 15 | 16 | $BuildProjectFile = "$PSScriptRoot\build\_build.csproj" 17 | $TempDirectory = "$PSScriptRoot\\.nuke\temp" 18 | 19 | $DotNetGlobalFile = "$PSScriptRoot\\global.json" 20 | $DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" 21 | $DotNetChannel = "STS" 22 | 23 | $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 24 | $env:DOTNET_NOLOGO = 1 25 | 26 | ########################################################################### 27 | # EXECUTION 28 | ########################################################################### 29 | 30 | function ExecSafe([scriptblock] $cmd) { 31 | & $cmd 32 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 33 | } 34 | 35 | # If dotnet CLI is installed globally and it matches requested version, use for execution 36 | if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` 37 | $(dotnet --version) -and $LASTEXITCODE -eq 0) { 38 | $env:DOTNET_EXE = (Get-Command "dotnet").Path 39 | } 40 | else { 41 | # Download install script 42 | $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" 43 | New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null 44 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 45 | (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) 46 | 47 | # If global.json exists, load expected version 48 | if (Test-Path $DotNetGlobalFile) { 49 | $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) 50 | if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { 51 | $DotNetVersion = $DotNetGlobal.sdk.version 52 | } 53 | } 54 | 55 | # Install by channel or version 56 | $DotNetDirectory = "$TempDirectory\dotnet-win" 57 | if (!(Test-Path variable:DotNetVersion)) { 58 | ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } 59 | } else { 60 | ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } 61 | } 62 | $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" 63 | $env:PATH = "$DotNetDirectory;$env:PATH" 64 | } 65 | 66 | Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)" 67 | 68 | if (Test-Path env:NUKE_ENTERPRISE_TOKEN) { 69 | & $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null 70 | & $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null 71 | } 72 | 73 | ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet } 74 | ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments } 75 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | bash --version 2>&1 | head -n 1 4 | 5 | set -eo pipefail 6 | SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 7 | 8 | ########################################################################### 9 | # CONFIGURATION 10 | ########################################################################### 11 | 12 | BUILD_PROJECT_FILE="$SCRIPT_DIR/build/_build.csproj" 13 | TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp" 14 | 15 | DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" 16 | DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh" 17 | DOTNET_CHANNEL="STS" 18 | 19 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 20 | export DOTNET_NOLOGO=1 21 | 22 | ########################################################################### 23 | # EXECUTION 24 | ########################################################################### 25 | 26 | function FirstJsonValue { 27 | perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}" 28 | } 29 | 30 | # If dotnet CLI is installed globally and it matches requested version, use for execution 31 | if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then 32 | export DOTNET_EXE="$(command -v dotnet)" 33 | else 34 | # Download install script 35 | DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" 36 | mkdir -p "$TEMP_DIRECTORY" 37 | curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" 38 | chmod +x "$DOTNET_INSTALL_FILE" 39 | 40 | # If global.json exists, load expected version 41 | if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then 42 | DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")") 43 | if [[ "$DOTNET_VERSION" == "" ]]; then 44 | unset DOTNET_VERSION 45 | fi 46 | fi 47 | 48 | # Install by channel or version 49 | DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" 50 | if [[ -z ${DOTNET_VERSION+x} ]]; then 51 | "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path 52 | else 53 | "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path 54 | fi 55 | export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" 56 | export PATH="$DOTNET_DIRECTORY:$PATH" 57 | fi 58 | 59 | echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)" 60 | 61 | if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then 62 | "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true 63 | "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true 64 | fi 65 | 66 | "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet 67 | "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@" 68 | -------------------------------------------------------------------------------- /build/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_style_qualification_for_field = false:warning 3 | dotnet_style_qualification_for_property = false:warning 4 | dotnet_style_qualification_for_method = false:warning 5 | dotnet_style_qualification_for_event = false:warning 6 | dotnet_style_require_accessibility_modifiers = never:warning 7 | 8 | csharp_style_expression_bodied_methods = true:silent 9 | csharp_style_expression_bodied_properties = true:warning 10 | csharp_style_expression_bodied_indexers = true:warning 11 | csharp_style_expression_bodied_accessors = true:warning 12 | -------------------------------------------------------------------------------- /build/Build.NugetPush.cs: -------------------------------------------------------------------------------- 1 | using Nuke.Common; 2 | using Nuke.Common.Git; 3 | using Nuke.Common.IO; 4 | using Nuke.Common.Tools.DotNet; 5 | using Nuke.Common.Utilities.Collections; 6 | using static Nuke.Common.Tools.DotNet.DotNetTasks; 7 | partial class Build 8 | { 9 | const string NugetApiUrl = "https://api.nuget.org/v3/index.json"; 10 | [Secret] [Parameter] string NugetApiKey; 11 | 12 | Target NuGetPush => _ => _ 13 | .Requires(() => NugetApiKey) 14 | .OnlyWhenStatic(() => GitRepository.IsOnMainOrMasterBranch()) 15 | .OnlyWhenStatic(() => IsLocalBuild) 16 | .Executes(() => 17 | { 18 | BinDirectory.GlobFiles("*.nupkg") 19 | .ForEach(package => 20 | { 21 | DotNetNuGetPush(settings => settings 22 | .SetTargetPath(package) 23 | .SetSource(NugetApiUrl) 24 | .SetApiKey(NugetApiKey)); 25 | }); 26 | }); 27 | } -------------------------------------------------------------------------------- /build/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | using Nuke.Common.Tooling; 5 | 6 | [TypeConverter(typeof(TypeConverter))] 7 | public class Configuration : Enumeration 8 | { 9 | public static Configuration Debug = new Configuration { Value = nameof(Debug) }; 10 | public static Configuration Release = new Configuration { Value = nameof(Release) }; 11 | 12 | public static implicit operator string(Configuration configuration) 13 | { 14 | return configuration.Value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build/_build.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | CS0649;CS0169;CA1050;CA1822;CA2211;IDE1006;CS8602: 8 | .. 9 | .. 10 | 1 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/APSToolkit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/aps-toolkit/e124e4a8262e9e64fff569331095ade5aa15aa9c/docs/APSToolkit.png -------------------------------------------------------------------------------- /docs/Nuget.md: -------------------------------------------------------------------------------- 1 | ## How to Push Nuget Package 2 | ```bash 3 | nuke NugetPush --NugetApiKey 4 | ``` 5 | -------------------------------------------------------------------------------- /docs/Tutorials/07. Explore Update Revit Data Back To ACC.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "dotnet_interactive": { 8 | "language": "csharp" 9 | }, 10 | "polyglot_notebook": { 11 | "kernelName": "csharp" 12 | }, 13 | "vscode": { 14 | "languageId": "polyglot-notebook" 15 | } 16 | }, 17 | "outputs": [ 18 | { 19 | "data": { 20 | "text/html": [ 21 | "
Installed Packages
  • APSToolkit, 1.0.8-beta
" 22 | ] 23 | }, 24 | "metadata": {}, 25 | "output_type": "display_data" 26 | }, 27 | { 28 | "data": { 29 | "text/plain": [ 30 | "Loading extensions from `C:\\Users\\chuongho\\.nuget\\packages\\microsoft.data.analysis\\0.21.1\\interactive-extensions\\dotnet\\Microsoft.Data.Analysis.Interactive.dll`" 31 | ] 32 | }, 33 | "metadata": {}, 34 | "output_type": "display_data" 35 | } 36 | ], 37 | "source": [ 38 | "#r \"nuget:APSToolkit , 1.0.8-beta\"" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": { 45 | "dotnet_interactive": { 46 | "language": "csharp" 47 | }, 48 | "polyglot_notebook": { 49 | "kernelName": "csharp" 50 | }, 51 | "vscode": { 52 | "languageId": "polyglot-notebook" 53 | } 54 | }, 55 | "outputs": [], 56 | "source": [ 57 | "using APSToolkit;" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "## Auth" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 3, 70 | "metadata": { 71 | "dotnet_interactive": { 72 | "language": "csharp" 73 | }, 74 | "polyglot_notebook": { 75 | "kernelName": "csharp" 76 | }, 77 | "vscode": { 78 | "languageId": "polyglot-notebook" 79 | } 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "using APSToolkit.Auth;\n", 84 | "// please visit tutorial : 01.Setup And Authentication.ipynb for more details\n", 85 | "var token = Authentication.Get2LeggedToken().Result;" 86 | ] 87 | } 88 | ], 89 | "metadata": { 90 | "language_info": { 91 | "name": "python" 92 | } 93 | }, 94 | "nbformat": 4, 95 | "nbformat_minor": 2 96 | } 97 | -------------------------------------------------------------------------------- /docs/Tutorials/09. Explore Data Knowledge Use LLM Agent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# This part you need to implement by yourself" 8 | ] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /docs/Tutorials/10. Build Pipeline Data Process with APSToolkit.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /docs/Tutorials/12. Custom Python In .NET Interactive.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /docs/Tutorials/13. Custom Metadata Export.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "nbformat": 4, 17 | "nbformat_minor": 2 18 | } 19 | -------------------------------------------------------------------------------- /sql/GetElementId.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, 2 | _objects_id.external_id AS externalId, 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | WHERE name = 'ElementId' -------------------------------------------------------------------------------- /sql/GetPrototype.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, 2 | _objects_attr.name AS name,_objects_attr.display_name AS propName , 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | WHERE externalId like "%Prototype%" -------------------------------------------------------------------------------- /sql/GetRevitCategories.sql: -------------------------------------------------------------------------------- 1 | SELECT DISTINCT 2 | _objects_val.value AS propValue 3 | FROM 4 | _objects_eav 5 | INNER JOIN 6 | _objects_id ON _objects_eav.entity_id = _objects_id.id 7 | INNER JOIN 8 | _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 9 | INNER JOIN 10 | _objects_val ON _objects_eav.value_id = _objects_val.id 11 | WHERE 12 | name LIKE '_RC' ESCAPE '\' AND 13 | propValue IS NOT NULL AND 14 | propValue <> '' -------------------------------------------------------------------------------- /sql/GetallData.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, 2 | _objects_id.external_id AS externalId, 3 | _objects_attr.name AS name, 4 | _objects_attr.category as category, 5 | _objects_attr.data_type AS dataType, 6 | _objects_attr.data_type_context AS dataTypeContext, 7 | _objects_attr.display_name AS propName, 8 | _objects_val.value AS propValue, 9 | _objects_attr.flags AS flags 10 | FROM _objects_eav 11 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 12 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 13 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id -------------------------------------------------------------------------------- /sql/QueryByDbId.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, 2 | _objects_attr.name AS name,_objects_attr.display_name AS propName , 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | where dbId = 3489 9 | -------------------------------------------------------------------------------- /sql/QueryByElementId.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, 2 | _objects_attr.name AS name,_objects_attr.display_name AS propName , 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | WHERE externalId = '7ca9f96f-614b-4d84-9743-5a38bcbe024e' 9 | -------------------------------------------------------------------------------- /sql/QueryInternalProperty.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, 2 | _objects_id.external_id AS externalId, 3 | _objects_attr.name AS name, 4 | _objects_attr.category AS category, 5 | _objects_attr.description AS des, 6 | _objects_attr.display_name AS propName , 7 | _objects_val.value AS propValue 8 | FROM _objects_eav 9 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 10 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 11 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 12 | where _objects_attr.category like "__%__" -------------------------------------------------------------------------------- /sql/QueryRevitFamily.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, 2 | _objects_attr.name AS name,_objects_attr.display_name AS propName , 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | where _objects_attr.name like "%_RFN%" -------------------------------------------------------------------------------- /sql/QueryRevitFamilyType.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, 2 | _objects_attr.name AS name,_objects_attr.display_name AS propName , 3 | _objects_val.value AS propValue 4 | FROM _objects_eav 5 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 6 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 7 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 8 | where _objects_attr.name like "%_RFT%" -------------------------------------------------------------------------------- /sql/QueryRevitLikeCategory.sql: -------------------------------------------------------------------------------- 1 | SELECT _objects_id.id AS dbId, 2 | _objects_id.external_id AS externalId, 3 | _objects_attr.name AS name, 4 | _objects_attr.category AS category, 5 | _objects_attr.description AS des, 6 | _objects_attr.display_name AS propName , 7 | _objects_val.value AS propValue 8 | FROM _objects_eav 9 | INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id 10 | INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id 11 | INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id 12 | where _objects_attr.category = "__viewable_in__" 13 | --------------------------------------------------------------------------------