From 9e1b0b94a1384a338cf29ae7946236ef2d81ad12 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Wed, 22 Jul 2020 15:21:40 +0200 Subject: [PATCH 01/11] fix typos --- docs/designautomation/appbundle/engines/max.md | 2 +- docs/environment/rundebug/2legged_da.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/designautomation/appbundle/engines/max.md b/docs/designautomation/appbundle/engines/max.md index e97f627..00d4dc8 100644 --- a/docs/designautomation/appbundle/engines/max.md +++ b/docs/designautomation/appbundle/engines/max.md @@ -30,7 +30,7 @@ The project should contain a `Class1.cs` class, let's rename the file to `Comman ## Commands.cs -This is the main code that will run with 3ds Max. Copy the following content into `Command.cs`. There are three classes to handle the Design Automation porcessing. First is the `InputParams` that will be used to interface with the JSON input data. Next is `ParameterChanger` class that is used to iterate the scene, and find all Casement Windows (but could be any object types as identified by the class ids). Finally the `RuntimeExecute` is used to take the input and drive the automation. Also note there is a specialized logging that will output information to the Design Automation console. See the LogTrace function. Note that the `ILogSys` 3ds Max managed class is used for this, and the flags used with the `LogEntry` API indicated are necessary for the output to show in the Design Automation console. +This is the main code that will run with 3ds Max. Copy the following content into `Command.cs`. There are three classes to handle the Design Automation processing. First is the `InputParams` that will be used to interface with the JSON input data. Next is `ParameterChanger` class that is used to iterate the scene, and find all Casement Windows (but could be any object types as identified by the class ids). Finally the `RuntimeExecute` is used to take the input and drive the automation. Also note there is a specialized logging that will output information to the Design Automation console. See the LogTrace function. Note that the `ILogSys` 3ds Max managed class is used for this, and the flags used with the `LogEntry` API indicated are necessary for the output to show in the Design Automation console. ```csharp using System; diff --git a/docs/environment/rundebug/2legged_da.md b/docs/environment/rundebug/2legged_da.md index 3ddc94c..f06b879 100644 --- a/docs/environment/rundebug/2legged_da.md +++ b/docs/environment/rundebug/2legged_da.md @@ -4,7 +4,7 @@ Now that your app is ready, it's time to run it. This is where we can test and c ## Using the sample -At the top-roght, click on **Configure** to define AppBundle & Activity. This only need to be done once. Specify the new `width` and `height` on the left panel, select the `input file` and click on `Start workitem`. The right panel should show the results. +At the top-right, click on **Configure** to define AppBundle & Activity. This only need to be done once. Specify the new `width` and `height` on the left panel, select the `input file` and click on `Start workitem`. The right panel should show the results. You can find [sample files here](https://github.com/Developer-Autodesk/learn.forge.designautomation/tree/master/sample%20files). From b82db86c6a954e960b2dcda2acd7e45908f22ca5 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Wed, 22 Jul 2020 15:30:59 +0200 Subject: [PATCH 02/11] fix broken link --- docs/designautomation/appbundle/engines/autocad.md | 2 +- docs/designautomation/appbundle/engines/max.md | 2 +- docs/designautomation/appbundle/engines/revit.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/designautomation/appbundle/engines/autocad.md b/docs/designautomation/appbundle/engines/autocad.md index 40bbaeb..416398a 100644 --- a/docs/designautomation/appbundle/engines/autocad.md +++ b/docs/designautomation/appbundle/engines/autocad.md @@ -138,7 +138,7 @@ namespace UpdateDWGParam ## PackageContents.xml -Create a folder named `UpdateDWGParam.bundle` and, inside, a file named `PackageContents.xml`, then copy the following content to it. Learn more at the [PackageContents.xml Format Reference](https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Customization/files/GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0-htm.html). This file defines the new AutoCAD custom command `UpdateParam` that will be called when Design Automation executes. +Create a folder named `UpdateDWGParam.bundle` and, inside, a file named `PackageContents.xml`, then copy the following content to it. Learn more at the [PackageContents.xml Format Reference](https://help.autodesk.com/view/ACD/2021/ENU/?guid=GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0). This file defines the new AutoCAD custom command `UpdateParam` that will be called when Design Automation executes. ```xml diff --git a/docs/designautomation/appbundle/engines/max.md b/docs/designautomation/appbundle/engines/max.md index 00d4dc8..c58702d 100644 --- a/docs/designautomation/appbundle/engines/max.md +++ b/docs/designautomation/appbundle/engines/max.md @@ -184,7 +184,7 @@ namespace Autodesk.Forge.Sample.DesignAutomation.Max ## PackageContents.xml -Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml`. Copy the content listed below in the XML section into the PackageContents.xml file. Learn more at the [PackageContents.xml Format Reference](https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Customization/files/GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0-htm.html). For more 3ds Max specific information for packaging your 3ds Max plugins see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) +Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml`. Copy the content listed below in the XML section into the PackageContents.xml file. Learn more at the [PackageContents.xml Format Reference](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_format_html). For more 3ds Max specific information for packaging your 3ds Max plugins see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) This file will tell 3ds Max the modules to load (in this case the .NET API plugin assembly we are creating, but can also include MAXScripts, Python, and/or C++ plugins.) Because the plugin is being loaded through this feature, you only need to worry about the instructions to trigger your automation job. Please note that a unique ID for both ProductCode and UpgradeCode are required for 3ds Max to correctly load your code. See above mentioned documentation for details. diff --git a/docs/designautomation/appbundle/engines/revit.md b/docs/designautomation/appbundle/engines/revit.md index 18423a9..30bd1cf 100644 --- a/docs/designautomation/appbundle/engines/revit.md +++ b/docs/designautomation/appbundle/engines/revit.md @@ -129,7 +129,7 @@ namespace Autodesk.Forge.Sample.DesignAutomation.Revit ## PackageContents.xml -Create a folder named `UpdateRVTParam.bundle` and, inside, a file named `PackageContents.xml`, then copy the following content to it. Learn more at the [PackageContents.xml Format Reference](https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Customization/files/GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0-htm.html). This file tells Revit to load our `.addin` plugin. +Create a folder named `UpdateRVTParam.bundle` and, inside, a file named `PackageContents.xml`, then copy the following content to it. Learn more at the [PackageContents.xml Format Reference](https://help.autodesk.com/view/ACD/2021/ENU/?guid=GUID-BC76355D-682B-46ED-B9B7-66C95EEF2BD0). This file tells Revit to load our `.addin` plugin. ```xml From 8a0a583f308bf8c0342070c136a2cf69289aad9a Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Wed, 22 Jul 2020 15:42:47 +0200 Subject: [PATCH 03/11] use of AppBundle term - Make use of AppBundle term as it is in the documentation. - Change section title 'Prepare an AppBundle (plugin)', only plugin can mislead. --- docs/_sidebar.md | 2 +- docs/designautomation/appbundle/README.md | 2 +- docs/designautomation/appbundle/common.md | 2 +- docs/designautomation/appbundle/netcore.md | 8 ++++---- docs/designautomation/appbundle/nodejs.md | 12 ++++++------ docs/designautomation/html/netcore.md | 2 +- docs/designautomation/html/nodejs.md | 2 +- docs/tutorials/modifymodels.md | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 13d247f..35011de 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -17,7 +17,7 @@ - [Modify your models](tutorials/modifymodels.md) - [Create a server](environment/setup/2legged_da.md) - [Basic app UI](designautomation/html/) - - [Prepare a plugin](designautomation/appbundle/) + - [Prepare an AppBundle (plugin)](designautomation/appbundle/) - [Define an activity](designautomation/activity/) - [Execute workitem](designautomation/workitem/) - [Run & Debug](environment/rundebug/readme.md) diff --git a/docs/designautomation/appbundle/README.md b/docs/designautomation/appbundle/README.md index f15d067..67589aa 100644 --- a/docs/designautomation/appbundle/README.md +++ b/docs/designautomation/appbundle/README.md @@ -1,4 +1,4 @@ -# Prepare a plugin +# Prepare an AppBundle (plugin) Design Automation uses .bundle just like the Autodesk App Store, meaning you need to create a `PackageContents.xml` and a ZIP with the `DLL` (and other required files). For detailed information on how to create them, please visit [Autodesk App Store Developer Center](https://www.autodesk.com/developer-network/app-store). diff --git a/docs/designautomation/appbundle/common.md b/docs/designautomation/appbundle/common.md index b031d96..9242483 100644 --- a/docs/designautomation/appbundle/common.md +++ b/docs/designautomation/appbundle/common.md @@ -1,4 +1,4 @@ -# Upload app bundle +# Upload AppBundle Now the ZIP bundle is ready, let's upload to Design Automation. diff --git a/docs/designautomation/appbundle/netcore.md b/docs/designautomation/appbundle/netcore.md index 17f9b1c..f9180b3 100644 --- a/docs/designautomation/appbundle/netcore.md +++ b/docs/designautomation/appbundle/netcore.md @@ -1,4 +1,4 @@ -# Code for creating App Bundle (.NET Core) +# Code for creating AppBundle (.NET Core) ## DesignAutomationController.cs @@ -81,7 +81,7 @@ Look at the `bundles` folder and return a list of .ZIP files. ```csharp /// -/// Names of app bundles on this project +/// Names of AppBundles on this project /// [HttpGet] [Route("api/appbundles")] @@ -138,10 +138,10 @@ public async Task CreateAppBundle([FromBody]JObject appBundleSpec string packageZipPath = Path.Combine(LocalBundlesFolder, zipFileName + ".zip"); if (!System.IO.File.Exists(packageZipPath)) throw new Exception("Appbundle not found at " + packageZipPath); - // get defined app bundles + // get defined AppBundles Page appBundles = await _designAutomation.GetAppBundlesAsync(); - // check if app bundle is already define + // check if AppBundle is already define dynamic newAppVersion; string qualifiedAppBundleId = string.Format("{0}.{1}+{2}", NickName, appBundleName, Alias); if (!appBundles.Data.Contains(qualifiedAppBundleId)) diff --git a/docs/designautomation/appbundle/nodejs.md b/docs/designautomation/appbundle/nodejs.md index 720d809..6dd4f5f 100644 --- a/docs/designautomation/appbundle/nodejs.md +++ b/docs/designautomation/appbundle/nodejs.md @@ -1,4 +1,4 @@ -# Code for creating App Bundle (Node Js) +# Code for creating AppBundle (Node Js) Inside `route/` folder create `DesignAutomation.js` file. In this file we will write all the endpoints. @@ -188,13 +188,13 @@ class Utils { } ``` -**2. App Bundle** +**2. AppBundle** -Before creating activity, we need to define app bundle with plugin and selecting the appropriate engine. Copy & paste the following endpoint after the utils class: +Before creating activity, we need to define AppBundle with plugin and selecting the appropriate engine. Copy & paste the following endpoint after the utils class: ```javascript /// -/// Names of app bundles on this project +/// Names of AppBundles on this project /// router.get('/appbundles', async /*GetLocalBundles*/ (req, res) => { // this folder is placed under the public folder, which may expose the bundles @@ -236,7 +236,7 @@ router.post('/forge/designautomation/appbundles', async /*CreateAppBundle*/ (req // check if ZIP with bundle is here const packageZipPath = _path.join(Utils.LocalBundlesFolder, zipFileName + '.zip'); - // get defined app bundles + // get defined AppBundles const api = await Utils.dav3API(req.oauth_token); let appBundles = null; try { @@ -247,7 +247,7 @@ router.post('/forge/designautomation/appbundles', async /*CreateAppBundle*/ (req diagnostic: 'Failed to get the Bundle list' })); } - // check if app bundle is already define + // check if AppBundle is already define let newAppVersion = null; const qualifiedAppBundleId = `${Utils.NickName}.${appBundleName}+${Utils.Alias}`; if (!appBundles.data.includes(qualifiedAppBundleId)) { diff --git a/docs/designautomation/html/netcore.md b/docs/designautomation/html/netcore.md index 7009e67..5ca9940 100644 --- a/docs/designautomation/html/netcore.md +++ b/docs/designautomation/html/netcore.md @@ -269,4 +269,4 @@ At this point you can run your project, just hit **play**, the HTML interface sh ![](_media/net/start_debug.png) -Next: [Prepare a plugin](designautomation/appbundle/) \ No newline at end of file +Next: [Prepare an AppBundle (plugin)](designautomation/appbundle/) \ No newline at end of file diff --git a/docs/designautomation/html/nodejs.md b/docs/designautomation/html/nodejs.md index 8b7fffe..09f2dd1 100644 --- a/docs/designautomation/html/nodejs.md +++ b/docs/designautomation/html/nodejs.md @@ -299,4 +299,4 @@ The final result should look like: ![](_media/designautomation/nodejs/basefiles.PNG) -Next: [Prepare a plugin](designautomation/appbundle/) \ No newline at end of file +Next: [Prepare an AppBundle (plugin)](designautomation/appbundle/) \ No newline at end of file diff --git a/docs/tutorials/modifymodels.md b/docs/tutorials/modifymodels.md index d498aab..61f1fd0 100644 --- a/docs/tutorials/modifymodels.md +++ b/docs/tutorials/modifymodels.md @@ -10,7 +10,7 @@ To modify your models, you need the following steps: 1. [Create a server](environment/setup/2legged_da) << First time developer? You should start here 2. [Basic app UI](designautomation/html/) -3. [Prepare a plugin](designautomation/appbundle/) +3. [Prepare an AppBundle (plugin)](designautomation/appbundle/) 4. [Define an activity](designautomation/activity/) 5. [Execute workitem](designautomation/workitem/) From 03e583f292a9bbea35c6c23f4a3676329863e795 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Wed, 22 Jul 2020 16:43:13 +0200 Subject: [PATCH 04/11] review DA Modify your models introduccion - Make clear the intention: Use of DA API and development of a sample. - Make clear what is the sample about and what it does. - Provide workflow overview (link to API doc). - Provide link to API documentation for DA terms. - Provide Postman collection doc link for even faster tests. --- docs/tutorials/modifymodels.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/modifymodels.md b/docs/tutorials/modifymodels.md index 61f1fd0..b07d970 100644 --- a/docs/tutorials/modifymodels.md +++ b/docs/tutorials/modifymodels.md @@ -1,12 +1,27 @@ # Modify your models -This tutorial will guide you through creating a webapp that can upload an input file, change its `width` and `height` parameter and save the output file. The UI will let you define AppBundle & Activity (as an initial configuration) and execute Workitems, with a output result. +This tutorial will guide you to create a webapp sample that uses Forge Design Automation API. This sample illustrates how we can use this API to modify on the cloud, a model saved in a file, chosing one of the Autodesk products (AutoCAD, Revit, Inventor or 3ds Max). More information about Design Automation API can be found [here](https://forge.autodesk.com/api/design-automation-cover-page/). + + +## Resize model sample + +We will develop a webapp that can upload an input file with a model on it, and change its `width` and `height` parameter. In our case, the model is a Window. The app will save the new resized model in a new output file. > Both input and output files are saved in OSS Buckets, you can use [View Models](tutorials/viewmodels) tutorial to view them. +The sample will let you: +- define an AppBundle and an Activity (as an initial configuration) linked to a specific engine (AutoCAD, Revit, Inventor or 3ds Max). This will be possible with the `Configure` option on the top right corner. +- execute the Workitem, task of changing the model size, defining the `width`, `height`, `input` model and the preconfigured `activity`. The process is being logged, and at the end, it will include a link to the resulted output file. + ![](_media/tutorials/run_sample_modifymodels.gif) -To modify your models, you need the following steps: +## Workflow + +The sample follows a [typical Design Automation workflow using a custom Activity](https://forge.autodesk.com/en/docs/design-automation/v3/developers_guide/basics/#typical-workflows). Even that some of the Design Automation will be described during the turtorial, you can [here](https://forge.autodesk.com/en/docs/design-automation/v3/developers_guide/basics/) get already familiar with them, or come back to that documentation later. + +### Steps + +To modify your models, you need: 1. [Create a server](environment/setup/2legged_da) << First time developer? You should start here 2. [Basic app UI](designautomation/html/) @@ -19,6 +34,8 @@ If you want to download the project ready to use, visit the following repos: - [.NET Core](https://github.com/Autodesk-Forge/learn.forge.designautomation) - [Node.js](https://github.com/Autodesk-Forge/learn.forge.designautomation/tree/nodejs) +> If you want to test the Design Automation API without UI, you have also available a number of [Postman collections](https://github.com/Autodesk-Forge/forge-tutorial-postman) following the same workflow as the sample above, and described in the [API documentation](https://forge.autodesk.com/en/docs/design-automation/v3/tutorials/3dsmax/about_tutorial/) + Ready to start coding? Next: [Create a server](environment/setup/2legged_da) \ No newline at end of file From a49fd0b20c3f5bfcc12db227c605320f3a63b003 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Wed, 22 Jul 2020 17:26:57 +0200 Subject: [PATCH 05/11] make project setup visible --- docs/environment/setup/2legged_da.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/environment/setup/2legged_da.md b/docs/environment/setup/2legged_da.md index e7ee89b..80ae7c9 100644 --- a/docs/environment/setup/2legged_da.md +++ b/docs/environment/setup/2legged_da.md @@ -18,4 +18,6 @@ After download, unzip it. Open the Windows **Command Line Prompt** (CMD) and nav !> **Warning**: `ngrok` exposes your localhost server to the web while it is in use. Be sure to turn it off when your testing it done. Do not use this outside development environment -Setup Project, choose your language: [Node.js](environment/setup/nodejs_da) | [.NET Core](environment/setup/netcore_da) \ No newline at end of file +**Project setup** + +Please choose your language: [Node.js](environment/setup/nodejs_da) | [.NET Core](environment/setup/netcore_da) \ No newline at end of file From a7be09c105880bbff9189d83c63b4264442465d4 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Thu, 23 Jul 2020 16:01:50 +0200 Subject: [PATCH 06/11] improve readability --- docs/designautomation/appbundle/README.md | 13 ++++++------- docs/designautomation/appbundle/engines/max.md | 6 +++++- docs/designautomation/html/README.md | 2 +- docs/designautomation/html/netcore.md | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/designautomation/appbundle/README.md b/docs/designautomation/appbundle/README.md index 67589aa..0fa7357 100644 --- a/docs/designautomation/appbundle/README.md +++ b/docs/designautomation/appbundle/README.md @@ -1,23 +1,22 @@ # Prepare an AppBundle (plugin) -Design Automation uses .bundle just like the Autodesk App Store, meaning you need to create a `PackageContents.xml` and a ZIP with the `DLL` (and other required files). For detailed information on how to create them, please visit [Autodesk App Store Developer Center](https://www.autodesk.com/developer-network/app-store). +At this section we will create a basic plugin or AppBundle that searches for the Windows in the scene model tree and updates the `width` and `height` parameters of it, saving the resulting file as a new file. -At this section we will create a basic plugin that update `width` and `height` parameter and save the resulting file. Also the supporting files (`PackageContents.xml`) and the folder structure to place them. Finally create a .ZIP file ready to upload to Design Automation. +Design Automation uses .bundle just like the Autodesk App Store. For it, a `PackageContents.xml` descriptor file will be created and ZIP together with the `DLL` and other possible required files. For detailed information on how to create them, please visit [Autodesk App Store Developer Center](https://www.autodesk.com/developer-network/app-store). The created ZIP AppBundle file will be uploaded. ### Prerequisites - **7zip**: use to create the .ZIP with bundle files, please install [from here](https://www.7-zip.org/). This tutorial assumes **7zip** is installed on the default folder: _C:\Program Files\7-Zip\7z.exe_. -### Additional prerequisites +#### Additional prerequisites For the next session you can use the pre-build plugin. Or if you decide to build it, you will need: - **Visual Studio**: Visual Studio 2017 or newer is required, please visit [this link](https://visualstudio.microsoft.com/vs/). -- **AutoCAD, Inventor, Revit or 3ds Max**: In order to develop, test and debug your Design Automation plugin: [AutoCAD](https://www.autodesk.com/products/autocad/overview) | [Inventor](https://www.autodesk.com/products/inventor/overview) | [Revit](https://www.autodesk.com/products/revit/overview) | [3ds Max](https://www.autodesk.com/products/3ds-max/overview). +- **AutoCAD, Inventor, Revit or 3ds Max**: In order to develop, compile, test and debug your Design Automation plugin, you will need the respective application installed: [AutoCAD](https://www.autodesk.com/products/autocad/overview) | [Inventor](https://www.autodesk.com/products/inventor/overview) | [Revit](https://www.autodesk.com/products/revit/overview) | [3ds Max](https://www.autodesk.com/products/3ds-max/overview). *** -For the next step, choose the **Engine**, which is the Autodesk application where you plugin will run. You'll need the respective application installed in order to compile, debug and test locally. - -Choose the engine: [AutoCAD](/designautomation/appbundle/engines/autocad) | [Inventor](/designautomation/appbundle/engines/inventor) | [Revit](/designautomation/appbundle/engines/revit) | [3ds Max](/designautomation/appbundle/engines/max) \ No newline at end of file +The **Engine** is the Autodesk application where your plugin or App will run. Choose the engine you will use: +[AutoCAD](/designautomation/appbundle/engines/autocad) | [Inventor](/designautomation/appbundle/engines/inventor) | [Revit](/designautomation/appbundle/engines/revit) | [3ds Max](/designautomation/appbundle/engines/max) \ No newline at end of file diff --git a/docs/designautomation/appbundle/engines/max.md b/docs/designautomation/appbundle/engines/max.md index c58702d..8d1163b 100644 --- a/docs/designautomation/appbundle/engines/max.md +++ b/docs/designautomation/appbundle/engines/max.md @@ -11,7 +11,11 @@ Remember that for Design Automation, there should be no UI or prompts that canno ## Create a new .NET project -Right-click on the solution, the **Add** >> **New Project**. Select **Windows Desktop**, then **Class Library** and, finally, name it `UpdateMAXParam`. You will then need to reference the Autodesk.Max.Dll managed assembly (3ds Max .NET API core module). This module is found in the 3dsmax.exe folder and when referencing, make sure to turn off the "Copy Local" flag. There are a few other modules used for .NET API support (see [The 3ds Max .NET SDK](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_3ds_max__net_sdk_html)), but for this tutorial we will use only Autodesk.Max.dll. Then search and install `Newtonsoft.Json` (which is used to parse input data in JSON format). +Right-click on the solution, and then **Add** >> **New Project**. Select **Windows Desktop**, then **Class Library** and, finally, name it `UpdateMAXParam`. + +You will then need to reference the Autodesk.Max.dll managed assembly (3ds Max .NET API core module). This module is found in the 3dsmax.exe folder and when referencing, make sure to turn off the "Copy Local" flag. There are a few other modules used for .NET API support (see [The 3ds Max .NET SDK](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_3ds_max__net_sdk_html)), but for this tutorial we will use only Autodesk.Max.dll. + +Then search and install `Newtonsoft.Json` (which is used to parse input data in JSON format). > Please select .NET Framework 4.7. If not listed, [please install the Dev Pack](https://dotnet.microsoft.com/download/dotnet-framework/net47). diff --git a/docs/designautomation/html/README.md b/docs/designautomation/html/README.md index a4b5771..1115efe 100644 --- a/docs/designautomation/html/README.md +++ b/docs/designautomation/html/README.md @@ -1,5 +1,5 @@ # Basic UI -The interface is based on vanilla `HTML5` & `JavaScript`. It essentially the same for any server-side, but there are a few differences: the Websocket implementation uses socket.io (Node.js) or SignalR (.NET Core). +The interface is based on vanilla `HTML5` & `JavaScript`. The only difference between languagues is the Websocket implementation that will use socket.io (Node.js) or SignalR (.NET Core). Choose your language: [Node.js](designautomation/html/nodejs.md) | [.NET Core](designautomation/html/netcore.md) \ No newline at end of file diff --git a/docs/designautomation/html/netcore.md b/docs/designautomation/html/netcore.md index 5ca9940..2073d15 100644 --- a/docs/designautomation/html/netcore.md +++ b/docs/designautomation/html/netcore.md @@ -265,7 +265,7 @@ The final result should look like: ![](_media/designautomation/netcore/basefiles.png) -At this point you can run your project, just hit **play**, the HTML interface should open, indicating that your project was created correctly. None of the buttons should work... let's move forward. +At this point you can run/debug your project, hitting the **play** button in Visual Studio. It will launch the HTML interface of the app in a browser. None of the buttons are ready to work yet... let's continue. ![](_media/net/start_debug.png) From 9a774f98bafb21e9e4c2529fdf98f06a794220fb Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Mon, 27 Jul 2020 18:02:59 +0200 Subject: [PATCH 07/11] rearrange sections in "prepare an AppBundle" In order to make it easier to understand, the storyline order changes: creating the AppBundle structure first, and then the logic the activity executes. - Command.cs section move down - new section "Testing locally" created at the botton. Changes inside the sections will be commited next. --- .../designautomation/appbundle/engines/max.md | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/docs/designautomation/appbundle/engines/max.md b/docs/designautomation/appbundle/engines/max.md index 8d1163b..443c584 100644 --- a/docs/designautomation/appbundle/engines/max.md +++ b/docs/designautomation/appbundle/engines/max.md @@ -32,6 +32,48 @@ As a result, the **package.config** should look like the following for the Newto The project should contain a `Class1.cs` class, let's rename the file to `Command.cs` (for consistency). +## PackageContents.xml + +Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml`. Copy the content listed below in the XML section into the PackageContents.xml file. Learn more at the [PackageContents.xml Format Reference](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_format_html). For more 3ds Max specific information for packaging your 3ds Max plugins see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) + +This file will tell 3ds Max the modules to load (in this case the .NET API plugin assembly we are creating, but can also include MAXScripts, Python, and/or C++ plugins.) Because the plugin is being loaded through this feature, you only need to worry about the instructions to trigger your automation job. Please note that a unique ID for both ProductCode and UpgradeCode are required for 3ds Max to correctly load your code. See above mentioned documentation for details. + +```xml + + + + + + + + + + + + + +``` + +Finally, create a subfolder named `Contents` and leave it empty. At this point, the project should look like: + +![](_media/designautomation/max/bundle_folders.png) + ## Commands.cs This is the main code that will run with 3ds Max. Copy the following content into `Command.cs`. There are three classes to handle the Design Automation processing. First is the `InputParams` that will be used to interface with the JSON input data. Next is `ParameterChanger` class that is used to iterate the scene, and find all Casement Windows (but could be any object types as identified by the class ids). Finally the `RuntimeExecute` is used to take the input and drive the automation. Also note there is a specialized logging that will output information to the Design Automation console. See the LogTrace function. Note that the `ILogSys` 3ds Max managed class is used for this, and the flags used with the `LogEntry` API indicated are necessary for the output to show in the Design Automation console. @@ -186,48 +228,6 @@ namespace Autodesk.Forge.Sample.DesignAutomation.Max } ``` -## PackageContents.xml - -Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml`. Copy the content listed below in the XML section into the PackageContents.xml file. Learn more at the [PackageContents.xml Format Reference](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_format_html). For more 3ds Max specific information for packaging your 3ds Max plugins see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) - -This file will tell 3ds Max the modules to load (in this case the .NET API plugin assembly we are creating, but can also include MAXScripts, Python, and/or C++ plugins.) Because the plugin is being loaded through this feature, you only need to worry about the instructions to trigger your automation job. Please note that a unique ID for both ProductCode and UpgradeCode are required for 3ds Max to correctly load your code. See above mentioned documentation for details. - -```xml - - - - - - - - - - - - - -``` - -Finally, create a subfolder named `Contents` and leave it empty. At this point, the project should look like: - -![](_media/designautomation/max/bundle_folders.png) - ## Post-build event > For Node.js it is required to adjust the AppBundle ZIP output folder. @@ -249,6 +249,8 @@ If you build the `UpdateMAXParam` project now you should see something like belo ![](_media/designautomation/max/build_output.png) +## Testing locally + At this point, you could test the functionality using the 3ds Max batch tool. It works similarly to the 3ds Max Design Automation engine and is a good way to test all your automation locally before sending the job to the Forge DA cloud services. For .NET Classes to be instantiated in MAXScript environment, we can use the `dotNetClass` MAXScript function. For this sample project, the MAXScript code would look like this: ```MAXScript @@ -261,7 +263,7 @@ fn UpdateParam = UpdateParam() ``` -To execute this locally, we could do test a a command-line prompt with something like this: +To execute this locally, we could do test a command-line prompt with something like this: ```CommandLine "%ADSK_3DSMAX_x64_2019%\3dsmaxbatch.exe" -sceneFile .max da_script.ms ``` From 8aebbe1801bdc667255b138ba51da7d1154988b6 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Mon, 27 Jul 2020 18:29:16 +0200 Subject: [PATCH 08/11] improve readability --- .../designautomation/appbundle/engines/max.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/designautomation/appbundle/engines/max.md b/docs/designautomation/appbundle/engines/max.md index 443c584..72ccf55 100644 --- a/docs/designautomation/appbundle/engines/max.md +++ b/docs/designautomation/appbundle/engines/max.md @@ -34,9 +34,13 @@ The project should contain a `Class1.cs` class, let's rename the file to `Comman ## PackageContents.xml -Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml`. Copy the content listed below in the XML section into the PackageContents.xml file. Learn more at the [PackageContents.xml Format Reference](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_format_html). For more 3ds Max specific information for packaging your 3ds Max plugins see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) +Create a folder named `UpdateMAXParam.bundle` and inside this folder add a file named `PackageContents.xml` that will be the AppBundle descriptor. Copy the content listed below in the XML section into the PackageContents.xml file. + +This file will tell 3ds Max the modules to load. In this case points to the .NET API plugin assembly we will compile, but it can also include MAXScripts, Python, and/or C++ plugins. Because the dll plugin is being loaded through this feature, you only need to worry later about the instructions to trigger your automation job. Please note that a unique ID for both ProductCode and UpgradeCode are required for 3ds Max to correctly load your code. + +> You can learn about the [PackageContents.xml Format Reference](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_packagexml_format_html). +> For more 3ds Max specific information for packaging your 3ds Max plugins, please see here [Packaging Plugins](http://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_writing_plug_ins_packaging_plugins_html) -This file will tell 3ds Max the modules to load (in this case the .NET API plugin assembly we are creating, but can also include MAXScripts, Python, and/or C++ plugins.) Because the plugin is being loaded through this feature, you only need to worry about the instructions to trigger your automation job. Please note that a unique ID for both ProductCode and UpgradeCode are required for 3ds Max to correctly load your code. See above mentioned documentation for details. ```xml @@ -70,13 +74,19 @@ This file will tell 3ds Max the modules to load (in this case the .NET API plugi ``` -Finally, create a subfolder named `Contents` and leave it empty. At this point, the project should look like: +Create a subfolder named `Contents` and leave it empty. At this point, the project should look like: ![](_media/designautomation/max/bundle_folders.png) ## Commands.cs -This is the main code that will run with 3ds Max. Copy the following content into `Command.cs`. There are three classes to handle the Design Automation processing. First is the `InputParams` that will be used to interface with the JSON input data. Next is `ParameterChanger` class that is used to iterate the scene, and find all Casement Windows (but could be any object types as identified by the class ids). Finally the `RuntimeExecute` is used to take the input and drive the automation. Also note there is a specialized logging that will output information to the Design Automation console. See the LogTrace function. Note that the `ILogSys` 3ds Max managed class is used for this, and the flags used with the `LogEntry` API indicated are necessary for the output to show in the Design Automation console. +This is the main code that will run within 3ds Max. Copy the following content into `Command.cs`. There are three classes to handle the Design Automation processing. + +1. `InputParams` will interface with the JSON input data. +2. `ParameterChanger` iterates through the scene, and find all Casement Windows models in our sample. It could also be any object types as identified by the class ids. +3. `RuntimeExecute` takes the input and drives the automation. + +Note there is a specialized logging that will output information to the Design Automation console. See the `LogTrace` function. Note that the `ILogSys` 3ds Max managed class is used for this, and the flags used with the `LogEntry` API indicated are necessary for the output to be shown in the Design Automation console. ```csharp using System; @@ -240,7 +250,7 @@ del /F "$(ProjectDir)..\forgesample\wwwroot\bundles\UpdateMAXParam.zip" "C:\Program Files\7-Zip\7z.exe" a -tzip "$(ProjectDir)../forgesample/wwwroot/bundles/UpdateMAXParam.zip" "$(ProjectDir)UpdateMAXParam.bundle\" -xr0!*.pdb ``` -This will copy the DLL from /bin/debug/ into .bundle/Contents folder, then use [7zip](https://www.7-zip.org/) to create a zip, then finally copy the ZIP into /bundles folders of the webapp. +This will copy the compiled DLL from /bin/debug/ into .bundle/Contents folder. It will then use [7zip](https://www.7-zip.org/) to create a zip. And finally it will copy the ZIP into /bundles folders of the webapp. ![](_media/designautomation/max/post_build.png) > Note how the **Post-build event** uses the project and folder names, so make sure you're using these names. From 9c99d3433075cd605795333225fcf93a274a0873 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Mon, 27 Jul 2020 19:07:43 +0200 Subject: [PATCH 09/11] improve readability - around the AppBundle creation --- docs/designautomation/appbundle/common.md | 4 ++-- docs/designautomation/appbundle/netcore.md | 6 ++---- docs/designautomation/appbundle/nodejs.md | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/designautomation/appbundle/common.md b/docs/designautomation/appbundle/common.md index 9242483..6c5ecd2 100644 --- a/docs/designautomation/appbundle/common.md +++ b/docs/designautomation/appbundle/common.md @@ -1,5 +1,5 @@ -# Upload AppBundle +# Create and upload AppBundle -Now the ZIP bundle is ready, let's upload to Design Automation. +Now that the ZIP AppBundle is ready, let's upload it to Design Automation. Choose your language: [Node.js](designautomation/appbundle/nodejs) | [.NET Core](designautomation/appbundle/netcore) \ No newline at end of file diff --git a/docs/designautomation/appbundle/netcore.md b/docs/designautomation/appbundle/netcore.md index f9180b3..d0117c3 100644 --- a/docs/designautomation/appbundle/netcore.md +++ b/docs/designautomation/appbundle/netcore.md @@ -1,8 +1,6 @@ -# Code for creating AppBundle (.NET Core) +# Create and upload AppBundle (.NET Core) -## DesignAutomationController.cs - -Under **Controllers** folder create a `DesignAutomationController.cs` with the following content. This is just the class, we'll define the endpoints later, but note the `DesignAutomationHub` at the end, which allow us push notifications to the client via [SignalR](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-2.2). +Under **Controllers** folder create a `DesignAutomationController.cs` with the following content. This is the class basics, where we will add the endpoints. Note the `DesignAutomationHub` at the end, which allow us push notifications to the client, using [SignalR](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-2.2). ```csharp using Autodesk.Forge; diff --git a/docs/designautomation/appbundle/nodejs.md b/docs/designautomation/appbundle/nodejs.md index 6dd4f5f..0d9b76d 100644 --- a/docs/designautomation/appbundle/nodejs.md +++ b/docs/designautomation/appbundle/nodejs.md @@ -1,4 +1,4 @@ -# Code for creating AppBundle (Node Js) +# Create and upload AppBundle (Node Js) Inside `route/` folder create `DesignAutomation.js` file. In this file we will write all the endpoints. From 727281f480f64dc1c0bf6810ba1a7087b5eee3d2 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Mon, 27 Jul 2020 19:11:28 +0200 Subject: [PATCH 10/11] improve readability - around the Activity creation - around the Workitem --- docs/designautomation/activity/README.md | 4 +++- docs/designautomation/workitem/README.md | 2 +- docs/designautomation/workitem/netcore.md | 6 +++--- docs/designautomation/workitem/nodejs.md | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/designautomation/activity/README.md b/docs/designautomation/activity/README.md index d43c7a7..ccbc496 100644 --- a/docs/designautomation/activity/README.md +++ b/docs/designautomation/activity/README.md @@ -1,7 +1,9 @@ # Define an Activity -Activity is the specification of an action that can be executed using a specified engine. It specifies the number of input and output files, and the AppBundle and entry-point to use. +Activity is the specification of an action that can be executed using a specified engine. It specifies: the number of input and output files, the AppBundle and an entry-point to use. In this tutorial sample, the activity has 2 inputs (file & JSON data) and 1 output (file). +> It's worth mentioning again the Design Automation documentation for [entities](https://forge.autodesk.com/en/docs/design-automation/v3/developers_guide/field-guide/), where you can see the relation between them in [Entity Relationships](https://forge.autodesk.com/en/docs/design-automation/v3/developers_guide/field-guide/#entity-relationships) + Choose your language: [Node.js](designautomation/activity/nodejs) | [.NET Core](designautomation/activity/netcore) \ No newline at end of file diff --git a/docs/designautomation/workitem/README.md b/docs/designautomation/workitem/README.md index be74233..263c6f4 100644 --- a/docs/designautomation/workitem/README.md +++ b/docs/designautomation/workitem/README.md @@ -1,6 +1,6 @@ # Execute Workitem -A job that executes a specified Activity, using specified input files and generating appropriate output files. +A workitem is a job that executes a specified Activity, using specified input files and generating appropriate output files. The relationship between an Activity and WorkItem can be thought of as a “function definition” and “function call”, respectively. The Activity specifies the AppBundle(s) to use, which in turn specify the Engine to use. The Workitem is then called to execute those. diff --git a/docs/designautomation/workitem/netcore.md b/docs/designautomation/workitem/netcore.md index d58edd9..eda7874 100644 --- a/docs/designautomation/workitem/netcore.md +++ b/docs/designautomation/workitem/netcore.md @@ -4,7 +4,7 @@ The following methods should be added to the `DesignAutomationController` class. **1. StartWorkitem** -This is where we actually start the Design Automation. The `StartWorkitemInput` is just a data structure. This method also uploads the input file to an OSS Bucket and define that the output should be saved at the same bucket. To help you identify the files, both input and output uses the same original file name, but with a suffix (`input` or `output`) plus a time stamp. +The `StartWorkitemInput` class uploads the input file to an OSS Bucket and define that the output should be saved at the same bucket. To help you identify the files, both input and output uses the same original file name, but with a suffix (`input` or `output`) plus a time stamp. ```csharp /// @@ -106,11 +106,11 @@ public class StartWorkitemInput } ``` -> Note how the `StartWorkitemInput` class is defined **inside** de **DesignAutomationController**, this is correct and it's used as input parameter for `StartWorkitem` method. +> Note how the `StartWorkitemInput` class is defined **inside** **DesignAutomationController**, this is correct and it's used as input parameter for `StartWorkitem` method. **2. OnCallback** -When the workitem is done, Design Automation will callback our app (using the ngrok forwarding URL). This function will handle it and push a notification to the client (using SignalR Hub). +When the workitem is done, Design Automation will callback our app (using the **ngrok** forwarding URL). This function will handle it and push a notification to the client (using **SignalR** Hub). ```csharp /// diff --git a/docs/designautomation/workitem/nodejs.md b/docs/designautomation/workitem/nodejs.md index d9e9601..962e0be 100644 --- a/docs/designautomation/workitem/nodejs.md +++ b/docs/designautomation/workitem/nodejs.md @@ -4,7 +4,7 @@ The following apis should be added to the `DesignAutomation` js file before the **1. StartWorkitem** -This is where we actually start the Design Automation. This endpoint also uploads the input file to an OSS Bucket and define that the output should be saved at the same bucket. To help you identify the files, both input and output uses the same original file name, but with a suffix (`input` or `output`) plus a time stamp. +This endpoint uploads the input file to an OSS Bucket and define that the output should be saved at the same bucket. To help you identify the files, both input and output uses the same original file name, but with a suffix (`input` or `output`) plus a time stamp. ```javascript /// From 1107d9110db945213cdb69baaacb3fe12f5c3c95 Mon Sep 17 00:00:00 2001 From: Sergio Leon Date: Tue, 28 Jul 2020 10:18:46 +0200 Subject: [PATCH 11/11] new line formatting in EngineAttributes method - earning readability and visualization --- docs/designautomation/activity/netcore.md | 28 +++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/designautomation/activity/netcore.md b/docs/designautomation/activity/netcore.md index a3415f8..6802044 100644 --- a/docs/designautomation/activity/netcore.md +++ b/docs/designautomation/activity/netcore.md @@ -12,10 +12,30 @@ To define the activity we'll need the executable and the default file extension. /// private dynamic EngineAttributes(string engine) { - if (engine.Contains("3dsMax")) return new { commandLine = "$(engine.path)\\3dsmaxbatch.exe -sceneFile \"$(args[inputFile].path)\" $(settings[script].path)", extension = "max", script = "da = dotNetClass(\"Autodesk.Forge.Sample.DesignAutomation.Max.RuntimeExecute\")\nda.ModifyWindowWidthHeight()\n" }; - if (engine.Contains("AutoCAD")) return new { commandLine = "$(engine.path)\\accoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\" /s $(settings[script].path)", extension = "dwg", script = "UpdateParam\n" }; - if (engine.Contains("Inventor")) return new { commandLine = "$(engine.path)\\inventorcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", extension = "ipt", script = string.Empty }; - if (engine.Contains("Revit")) return new { commandLine = "$(engine.path)\\revitcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", extension = "rvt", script = string.Empty }; + if (engine.Contains("3dsMax")) + return new { + commandLine = "$(engine.path)\\3dsmaxbatch.exe -sceneFile \"$(args[inputFile].path)\" $(settings[script].path)", + extension = "max", + script = "da = dotNetClass(\"Autodesk.Forge.Sample.DesignAutomation.Max.RuntimeExecute\")\nda.ModifyWindowWidthHeight()\n" + }; + if (engine.Contains("AutoCAD")) + return new { + commandLine = "$(engine.path)\\accoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\" /s $(settings[script].path)", + extension = "dwg", + script = "UpdateParam\n" + }; + if (engine.Contains("Inventor")) + return new { + commandLine = "$(engine.path)\\inventorcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", + extension = "ipt", + script = string.Empty + }; + if (engine.Contains("Revit")) + return new { + commandLine = "$(engine.path)\\revitcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", + extension = "rvt", + script = string.Empty + }; throw new Exception("Invalid engine"); } ```