Quantcast
Channel: GetCOREInterface

Announcing 3ds Max 2021! - Customization Update

$
0
0

3dsmax2021header

Welcome to 3ds Max 2021 API update! On March 27th, the new version of 3ds max was released. Shortly after, in early April, the 3ds Max Design Automation engine and Model Derivative Forge services were also updated to 3ds Max 2021. The following is a summary of features and changes in 3ds Max 2021 including customization aspects for customers and developers. 

If you are interested to know more about Forge Design Automation for 3ds Max, check out this webinar: https://youtu.be/sWJwo7du8vQ

General Feature Summary

The following is a brief summary of the most important new features in 3ds Max 2021:

  • New Bake to Texture Tool – a new tool to bake maps and generate surface maps, supports PBR workflows, Mikk-t normal, and more
  • Physically Based Rendering (PBR) Materials – physical material is the default throughout 3ds Max, new simplified physical material
  • New Weighted Normals Modifier – based on popular user request we added support for weighted normals to be calculated and applied to models in 3ds Max
  • New OSL Shaders - Color Correction, HDRI Environment, HDRI Lights, Float and Color Curves, Camera Projection, Object Projection, Spherical Projection, Uber Noise
  • Arnold 6 as default renderer – Right out of the box, 3ds Max 2021 offers a modern, high-end renderer
  • New Substance plugin – supports the new “Substance2” map, uses latest Substance engine and up to 8k textures
  • New Install Experience - the online and offline installation has been overhauled for a simpler and faster experience
  • Scene Converter - the Scene Converter's new and improved workflow makes creating custom conversion rules easy. Presets are locked and cannot be saved over, and you are reminded of unsaved changes before closing the Scene Converter.
  • Viewport Improvements – Viewports support Roughness and Ambient Occlusion, clearer viewport customization options can be saved as presets, performance and other quality improvements
  • ProSound improvements - Added support for 24bit wav files and unlimited number of audio clips, and bug fixes
  • Chamfer Improvements for Edit/Editable Poly – The new chamfer technology already available in the Chamfer modifier has been integrated into Edit Poly Modifier and Editable Poly Shape
  • Sketchup Import improvements – the ATF based Sketchup Importer now support more features previously available in the legacy Sketchup Importer
  • User Defined Defaults - Users can now set their own default values that persists through 3ds Max sessions

Developer Feature Summary

  • New Developer Help – the documentation for the C++ SDK, Python, MAXScript and MCG are available in a new online publication that is separate from the 3ds Max online help. This will help when searching on common 3ds Max topics, but in a developer/customization context! The direct link is here.
  • Backward compatibility with 3ds Max 2020 - 3ds Max 2021 is compatible with and will load C++ plugins compiled for 3ds Max 2020. For 3ds Max 2020 plugins packaged as an Application Package Format, the SeriesMax tag has to be 2021 in order for 3ds Max 2021 to load them.
  • 3ds Max SDK download – the 3ds Max SDK will be available as a free download on the Autodesk Developer Network website. It will also ship on the 3ds Max 2021 cd-image (<cd-image>\x64\Tools\MAXSDK), but it is not offered as an optional install item through the new 3ds Max 2021 installer.
  • New Python 3 Support – the Python 3 interpreter integrated into 3ds Max 2021 offers a modern and robust experience for extending and integrating 3ds Max into production pipelines. Python 2.7 is still supported and can be enabled with a command line switch of environment variable. See this link for details.
  • Python 3 Samples - The product team also put together a nice github repo of Python How-to samples. These match the MAXScript tutorials content, but using the newest Python 3 environment. See here for details.
  • pymxs Python API improvements and MaxPlus Python API deprecation – Python developers can confidently migrate from MaxPlus to pymxs knowing that they can access the entire set of functionalities 3ds Max has to offer, and interoperate with MAXScript . The MaxPlus Python API is still available with Python 2.7, but you should consider moving to poymxs, so you can get into Python 3.x because the Python organization has deprecated Python 2.x.
  • Application Plugin Package Format Improvements – AMG and OSL shaders, and Scene Converter extension scripts are now supported by the Application Plugin Package Format making it easier to migrate your plugin to it

 

What’s New in the 3ds Max C++ SDK

The documented changes are here.

Here is a highlight of the most important things to know:

No SDK Break

3ds Max 2021 is binary backward compatible with 3ds Max 2020. Plugins compiled for 3ds Max 2020 will load and work in 3ds Max 2021.

Note: for 3ds Max 2020 plugins packaged as an Application Package Format, the SeriesMax tag has to be 2021 in order for 3ds Max 2021 to load them.

Compiler

3ds Max 2021 is compiled with the same compiler as 3ds Max 2020, namely Visual Studio 2017, toolset 14.1. The header files are now compatible with the Visual Studio /permissive- flag which allows plugin developers to turn on standards-conforming compiler behavior.

Qt version and configuration

3ds Max 2021 is using Qt 5.12.5. 3rd party 3ds Max plugins that use Qt 5.12 are supported.

3ds Max SDK Download

The 3ds Max SDK is now available on the 3ds Max Developer Center. It’s still provided in most distribution media, but you can download anytime from here. https://www.autodesk.com/develop3dsmax

Application Plugin Package Format

The plugin package format has been improved to support AMG and OSL shaders, and also supports the scene converter extensions. See link here.

Change in behavior regarding loading plugins compiled for a compatible release of 3ds Max

3ds Max 2021 will not automatically load binary plugin dlls whose run-time requirements specify 2020 as SeriesMax, even though 3ds Max 2021 is binary compatible with 3ds Max 2020. Plugin developers will have to re-publish their plugins with the SeriesMax run-time requirement attribute set to 2021, once they verified that their plugins built against the 3ds Max 2020 SDK works properly in 3ds Max 2021.

Why use the Application Plugin Package Format?

Packaging and installing plugins using this format has the following advantages for plugin developers and their users:

  • Plugin installers don’t need to understand where 3ds Max is installed. Instead 3ds Max will discover and load all plugins that are packaged and described in a way that adheres to the Application Package Format
  • 3ds Max installations are not modified by plugin installers, reducing the risk to break it, and making it easier for the users to un-install 3ds Max and 3rd party plugins
  • Plugins can be installed anywhere, if the ADSK_APPLICATION_PLUGINS environment variable contains a path to the installation directory. It is strongly recommended that plugins offer as default installation path %APPDATA%\Autodesk\ApplicationPlugins\ or%PROGRAMDATA%\Autodesk\ApplicationPlugins\

We strongly suggest to plugin developers to adopt this plugin packaging and installation format, since support for loading plugins described in configuration files will be dropped in the future.

Note that plugin package format has been supported since 3ds Max 2015.

New C++ APIs

 

What’s New in 3ds Max Python Scripting

Python based tools for 3ds Max have been gaining popularity over the last few years. To better support the needs of our tech-savvy users, we are updating our Python support, and improving the Python development experience with 3ds Max. See here for all the changes.

MaxPlus Python deprecation

One thing to make note of… The MaxPlus Python API is not available with Python 3.7, and it will be deprecated in the future alongside Python 2.7. Currently 3ds Max 2021 still supports MaxPlus in the Python 2.7 environment to help give porting time to pymxs.

 

What’s New in MAXScript

MAXSCript has also been improved for 2021 release. See here for complete list of updates.

Highlights:

  • The new Bake-To-Texture feature has been exposed to Maxscript as a new utility class.
  • PluginPackageManager interface has six new APIs for getting information about paths searched for the Scene Converter, OSL, and AMG.  See the “Interface: PluginPackageManager” topic for more information.
  • The callbacks.addScript() method can now take a MAXScript function as the callback argument. Previously this argument was a string, stringStream, or file name.
  • The new Weighted Normals Modifier is exposed in the MAXScript class Weighted_Normals.
  • All of the ATF-based import plugins have two new properties: importHiddenObjects and preserveLayers.
  • The Edit_Poly object and Editable_Poly modfier have many new properties and methods exposing the Chamfer updates introduced in previous 2020 releases.
  • The SME (Slate Material Editor) interface has several new methods for managing Material Libraries.

For a list of new features released throughout 3ds Max 2020 Updates, please see this online help page.


3ds Max 2022 Customization Update

$
0
0

Email-header-interior- Image courtesy of Binyan Studio
Image courtesy of Binyan Studio

When looking for an interesting image to spiff up this post, I found the above image and struck me as especially poignant in these covid-19 times. Given that we have not been able to meet in person, it fits well. Never-the-less it's an awesome image rendered in 3ds Max by one of our awesome customers. :-) I sincerely hope you and yours have been safe during this time, and continue to be diligent to maintain safety.

Now to the gist of this post.... :-)  On March 24th 3ds Max 2022 was released. 3ds Max 2022 is also available on the Forge platform through the Model Derivative service and on Design Automation. If you are an ADN member, the new release should be in your Autodesk account already. Also note that the 3ds Max Developer Center has been updated with the SDK and a few modules need for certain SDK samples. The SDK is still provided with the distribution as well, but it is not included in the product installation routine. You can find it in the <unzipped distribution>\x64\Tools\MAXSDK folder. You can install just by executing the MSI file. Additionally for ADN members we have the debug/hybrid build posted to the ADN member site.

As always, it is helpful to checkout the new features to be sure any customization you already have takes advantage of new features and are compatible. See the list of new features here.  There are release notes provided here.

3ds Max SDK update

2022 is an SDK Break

  • 3ds Max 2022 SDK is not backward compatible with the 3ds Max 2021 SDK
  • Plugins must be rebuilt
  • New SDK features support
    • Modeling, Viewport, and Scripting
    • Performance
    • Robustness (for example, applying const correctness to existing APIs)
  • Requirements:
    • Microsoft Visual Studio 2017, Platform Toolset v141
    • Windows SDK 10.0.17134.0
    • .NET 4.8
    • Qt 5.15.1

Details

Plugin Package changes

The Plugin Package format is now the preferred way to load plugins. This allows you to maintain your plugins and resources outside of the 3d max environment. No changes are needed to any of the 3ds Max config files or environment. The only requirement is location of the plugin package. In 3ds Max 2022 these two details were added:

  • SeriesMax attribute is now required
  • SeriesMin and SeriesMax now support update versions specifically

Details

MAXScript localization changes affecting the SDK

A big change to MAXScript environment includes localization features. 3ds Max 2022 eliminates the need for the dictionaries (maxscrpt.lcl files) by allowing plugins to supply both the English and non-English names of their properties. The changes include:

  • New virtual methods that were added
  • Non-Virtual methods whose signatures have been updated
  • Virtual methods that were replaced
  • Trackview and Controller property and sub-anim name support
  • New reference message added
  • New parameter definition tag added

Details

Software Security

3ds Max has a new Safe Scene Script Execution feature to protect customers from being hacked. For the SDK, a few things have been chaged/added to support this feature:

  • New ISceneScriptSecurityManager interface
  • SecurityException thrown when an unsafe MAXScript command is blocked
  • 3rd party plugin’s participation in Safe Scene Script Execution 

Details

Viewport, Rendering, Materials

  • New methods to handle the new 3ds Max Presentation Mode feature
  • Viewport Bloom feature settings are accessible through IViewportViewSettings2
  • Support for customized material creation through the IMaterialBrowserEntryInstanceCallback interface. This allows you to register a callback that gets executed when a user creates a material or texture

Details

Modeling

  • Changes to class Matrix3 and DMatrix3
  •     Now initialized to identity matrix
  •     No longer need Matrix3::SetNotIdent()
  • Changes to class TriObjectNormalXTC
  •     Performance boost
  • Changes to class Deformer
  •     non-const Map() and IsThreadSafe() are deprecated
  •     MapNormal() has been added and is thread safe
  •     const Map() is now thread safe
  • New functions added to the MNMesh class
  •     Performance improvement
  •     New methods to determine “dead” vertices, edges, and faces via the internal cache
  • New function added to the Modifier class
  •     Modifier::ShouldCollapseOnSave()
  • Improve sub-object picking with High DPI systems
  •     Picking with the mouse now properly accounts for high DPI displays
  •     You can now better handle High DPI with new methods

Details

Miscellaneous Changes and Improvements

There were also number of miscellaneous changes and improvements. 

Details

3ds Max .NET API

There were no API changes to the .NET API environment. However, note that the .NET Framework was updated to 4.8. With Visual Studio, you may need to install this framework before you can update your plugin. You will need to rebuild to ensure it works properly in 3ds Max 2022. Make sure to test functionality as well!

3ds Max Python

There were some version updates for the python support. The complete history and summary is here. These are the versions of various components needed to work with 3ds Max 2022:

  • Python version: 3.7.9
  • Python PySide: 5.15.1

Python deprecations

  • Python version 2.7 is no longer available (as announced in 2021 release)
  • The MaxPlus module is now fully deprecated and no longer available (as announced in 2021 release). Use pymxs module as the python API now.

Python samples

As introduced in 3ds Max 2021, we have added a github repo for Python samples. Find all the sample here: https://github.com/ADN-DevTech/3dsMax-Python-HowTos

MAXScript

See the help docs for a complete summary of the changes to MAXScript. Find it here.

Porting a C++ Plugin to 3ds Max 2022 and Installing the 3ds Max 2022 C++ Wizard

$
0
0

Even though the build tools (toolset) did not change, there were a number of changes made to the 3ds Max SDK that requires a plugin to be ported and recompiled. Because the SDK changed and has new requirements, this affects the binary compatibility.

The first one you are likely to hit, is that all plugins typically have an implementation of the ClassDesc2 (or ClassDesc, if not needing ParamBlock2 support). Minimally you will have to add a new method required by the underlying base ClassDesc, NonLocalizedClassName. Please take a moment to read the article about this aspect here, especially if you are providing localized plugins.

I also noticed that the Matrix3 class has changed. Depending on how you are using it, and your warning/error level you use in your projects, you may have to update code (or the project). The changes are documented here. In the case of the ADN Bake Radiosity example, the Matrix3 was initialed using the old constructor (which takes a BOOL and remember BOOL in 3ds Max is an int type). You will still see this syntax scattered throughout the SDK samples, and rather than fixing their code, they are using the ”MAX_SILENCE_DEPRECATED_MATRIX_BOOL_CTOR “ definition to silence the warning. In my opinion,  this is a good opportunity to cleanup your own code, though, and you will be in good shape if the SDK team decides to completely remove the deprecated constructor.

Finally, I would like to discuss Visual Studio 2019. Although 3ds Max and other Autodesk products have not moved to VS2019 (and toolset 142), you can use the IDE and be compatible with VS2017 (and toolset 141). This has been the case for a number of VS releases where you can target previous toolsets. With VS 2019, most editions also provide the VS2017 (toolset 141). There is a discussion about it here. Although they talk about binary compatibility, we advise to stick with the same toolset that 3ds Max is built with to avoid any unknowns. There is nothing worse than tracking down some weird binary incompatibility, and now that VS 2017 (toolset 141) is included with VS2019 there is no reason you cannot use latest greatest IDE and features, while sticking to the official toolset.

One note about VS 2019 and “classic” wizards like 3ds Max, there is no longer default folder structure that supports an “out-of-the-box” installation. However you can easily create the correct structure to install the 3ds Max Wizard. Also note that there was a bug (found by one of our other ADN engineers here) that was fixed, and requires to have the later builds of VS2019. See here for the details.

Here are the steps I would suggest to successfully setup the 2ds Max 2022 wizard in Visual Studio 2019:

  1. Make sure VS 2019 is updated to at least v16.5.2. You can find this in the Help -> About dialog.
  2. Create this folder structure if it is not present. Depending on other modules you have installed, this could already be present: <install folder>\msvs2019\Common7\IDE\VC\vcprojects
  3. Copy the files from the 3ds Max 2022 SDK folder. These are:
    • <install folder>\maxsdk\howto\3dsmaxPluginWizard\3dsmaxPluginWizard.ico
    • <install folder>\maxsdk\howto\3dsmaxPluginWizard\3dsmaxPluginWizard.vsdir
    • <install folder>\maxsdk\howto\3dsmaxPluginWizard\3dsmaxPluginWizard.vsz
  4. Open the 3dsmaxPluginWizard.vsz file in a text editor
    • Update the wizard engine to 16:   
      Wizard=VsWizard.VsWizardEngine.16.0
    • Add the path. Note it only worked for me to use forward slash (and before backslash was fine). In my case it was like this:
      Param="ABSOLUTE_PATH = d:/me/3dsmax/maxsdk2022/maxsdk/howto/3dsmaxPluginWizard"

After these changes, you should see the Wizard in the Visual Studio 2019 projects now. Also note that you can setup several versions of the Wizard as you want. This only requires adding pertinent information. In my case I like to make sure to use the support wizards for each version of 3ds Max. After setting up 3ds Max 2021 and 3ds Max 2022 in the Visual Studio 2019 environment, I can easily create projects for each version, using the Wizard for each specific version. Because the UI of Visual Studio 2019 has changed, it may not be obvious at first. Here’s how to find the 3ds Max C++ Wizard...

  1. After starting Visual Studio 2019, it will look like this:
    Fig01
  2. Click on “Create a new project” (as highlighted in above screenshot).
  3. Now you will see a long list of project types, and C++ is found a long way down if you have installed other types of targets. You can switch to C++, and it still will not display because the 3ds Max Wizard is a classic one, and does not provide the keywords.
  4. In the Search box at the top, search for “3ds Max” and now they will be found. See the red box highlight in below screen shot.
  5. Once you create a project, it will then display in the “Recent project templates” list. See the yellow box in the below screen shot.
    Fig02

Although these are minor things, it is worth mentioning that some of the samples (for example the ADN Bake Radiosity) it was the first time I had to actually update the code in many releases, even when toolsets were upgraded!

As such, please take extra time to properly port your plugins, and as always be diligent with testing.

Tips for troubleshooting Visual Studio output and getting Qt to work with 3ds Max SDK

$
0
0

Let's start with the background leading up to this article... I had a question where I needed to build a Qt sample, specifically this one: <install>\maxsdk\howto\qtObjectDemo. I wanted to continue setting up my newer laptop and had not installed Qt yet, and was just getting 3ds Max 2022 setup. I am using Visual Studio 2019, but of course targeting the MSVC 2017 toolset (141).

First, the output window in Visual Studio does not always tell you the details of what went wrong with a build action. I learned recently the amount of detail can be configured through the “Build and Run” settings. By default it seems the setting is “Minimal”. You can find the setting in “Options”, which can be found in at least two places: the Debug menu and also Tools menu. For example, navigate to the “Tools”->”Options” and then select “Projects and Solutions” in the left list of categories. Under that category, select “Build and Run” and then you will see two drop downs titled “MSBuild project build output verbosity” and “MSBuild project build log verbosity”. In my setup, these are set to Minimal at start.

Why would you need to change this? Anytime the output window shows you an error, but does not give enough information! In my case, again, I was trying to compile the <install>\maxsdk\howto\qtObjectDemo sample. To build an individual sample, I usually just open the vcxproj into a text editor and change the  <MaxSDK> entry to the Windows environment variable that is created when installing the SDK. For example in 2022, my entry looks like this: ADSK_3DSMAX_SDK_2022=D:\me\3dsmax\maxsdk2022\maxsdk, so dropping $(ADSK_3DSMAX_SDK_2022) into that MaxSDK definition is enough for the Max SDK components to be found (include, libraries, tools).

The issue came -up with a failed build and when the “minimal” output said: “The system cannot find the path specified.” Very helpful… Not. Ok, I’ll get to the troubleshooting help after we talk about Qt.

The next topic to include here is the Qt tools. Let’s start by reminding you about Qt. 3ds Max started to include Qt in the 3ds Max 2017 release. Each release requires a different version of Qt to correspond to the 3ds Max version used for each major release. You will find the specifics in the SDK Requirements docs. For 2022 see here. The good news is that only the 3ds Max 2017 release required a “patched” version of Qt (available in pre-built form on the 3ds Max developer center. All versions after that are using the default source and binaries from Qt directly.

Next comes installing Qt… Qt distributions are a bit interesting. They now have a commercial version, and an open source version. As a developer, you will need to decide which version is appropriate for your business. Either version will install Visual Studio specific versions. So, if you are supporting multiple 3ds Max versions, you will also need to install multiple versions of Qt, and their Qt Maintenance Tool can help you to stay updated as you move forward. For example, I installed these for my new machine:

Qt_versions
Again, for me, I needed to setup a new machine, and also at same time was setting up for the recent 3ds Max 2022 release, I was able to select the versions listed from the 3ds Max SDK Requirements… After the Qt installation (which took some time), it also helps to have the Visual Studio Qt Extension. From the SDK docs, see step 2 here.

In my case, I was setting up Visual Studio 2019 Professional IDE (to use with the msvc2017 toolset (141)). The place to install the Qt Extension is on a menu called “Extensions”. Here you can click “Manage” and search for Qt and then install it.
Qt_tools

Next, using the Qt Extension, you can configure Visual Studio to use the versions you installed… Note you can find it in the MSVS Options area after it is installed… Or direct from the Extensions menu:
Qt_config

You’ll click <add new Qt version> to configure and add your installed versions and locations.

Ok, now going back to the 3ds Max project, and trying to build…  In the options for “Build and Run” you will see two drop downs titled “MSBuild project build output verbosity” and for me was set to “Minimal” where I got this output:
Vs_min_output

Note the two Qt commands at beginning… Those are output from the 3ds Max Project file. They are one after another, then the error occurs 2x times. At first I did not think of Qt being an issue, but after we change the MSVS output option to be “Detailed” we get a lot more information in the output window. It takes a close eye, but I was suspecting Qt now (because other non-Qt projects were building fine). So, in the output Window I did a search for Qt (Ctrl-F), and bam… right away I see some suspicious issues for example:

1>Property reassignment: $(QtMigrateLib)="D:\me\3dsmax\maxsdk2022\maxsdk\QtWinMigrate\lib\" (previous value: "D:\me\QtWinMigrate\lib\") at D:\me\3dsmax\maxsdk2022\maxsdk\ProjectSettings\PropertySheets\3dsmax.general.project.settings.props (237,3)

Notice it is coming from the maxsdk\ProjectSettings\PropertySheets\3dsmax.general.project.settings.props file…

Later (towards end where the actual build errors are) I also see the calls to Qt uic.exe and moc.exe tools for this project. For example:
1>    "D:\me\3dsmax\maxsdk2022\maxsdk\Qt\5.15.1\\bin\uic.exe" -o ".\GeneratedFiles\ui_QtPluginRollup.h" "D:\work\sfdc\case17823411\qtObjectDemo\QtPluginRollup.ui"

Here’s where the problem is… Notice that the front part of the path is 3ds Max SDK, but second part is the versioned Qt path (but missing a Qt platform). This is not the correct way to find Qt. I found that in the 3dsmax.general.project.settings.props file that 3ds Max team is setting Qt values to be relative to the 3ds Max SDK path. For example: <QTDIR Condition="'$(IsDefaultQtVsProjectFormat)' == 'false'">$([MSBuild]::ValueOrDefault(`$(QTDIR)`, `$(MaxSdkDir)Qt\$(QTVER)\`))</QTDIR>

That evaluates to something like this: D:\me\3dsmax\maxsdk2022\maxsdk\Qt\5.15.1\\bin\uic.exe and is wrong.

There are two problems here… There is the 3ds Max SDK path, and even if we installed there, it could be an issue because there is no Qt “platform” folder in that evaluation.

What is the solution? Well, I found that the easiest was just to set the QTDIR from my VS environment (ie. a VS2019 command prompt). You could also change the QTDIR value in the 3dsmax.general.project.settings.props file, but that means changing source SDK files, which I always try to avoid (being in support, I want what is shipped, and could also be issues if trying to setup a new environment, how do you remember to change that again?) The local environment variable does not require changes to the 3ds Max SDK props file.

For example in a VS2019 command prompt, I was able to: set QTDIR=D:\cc\qt\5.15.1\msvc2019_64 and this overrides the props setting when loading the project from that environment.

I'd be interested to here your feedback or if you found a better way, so feel free to leave a comment.

3ds Max 2023 Released!

$
0
0

Hopefully by now you have seen the new release of 3ds Max. For a overview of the new features, check out the help here. The Autodesk AREA site has also bee revamped, to be more community oriented. Check it out: area.autodesk.com. Some features I think is cool include the gltf format support, and include MAXScript capabilities. A subtle feature is that now the 3ds Max physical material is compatible with the Autodesk standard surface. This makes exchanging materials between 3ds Max and Maya easier, but also extends to other tools, including the Forge Viewer.

For SDK changes, check out the help here. Highlights include Instance Display API, Instance Rendering API, and Volume Display API. Another aspect improved is the Plugin Packages.

MAXScript Custom Value Types from 3ds MAX SDK

$
0
0

3ds Max Design Window

Building a custom value type for MAXScript

3ds MAX is a is a professional 3D computer graphics program that can be used to create 3D animations, models, games, and images. The power that it can do comes not only from the robust UI (User Interface) tools and ease of building plugins but also from the inbuilt scripting capability using Autodesk MAXScript. It is no doubt the power that MAXScript adds to 3ds Max. It is a great scripting method for automation, animation, object creation and manipulation. Lately, it has become the core of initiating 3ds Max Design Automation in the Autodesk Platform Services (formerly Forge).

Object Manipulation using MAXScript

To manipulate objects in scene (create, modify, animate, etc.), the returned object on the Maxscript side must give you access to the underlying exposed properties. Let us create a simple box object and look at the exposed properties that the object has.

 

    • Let us create and add a box object to the scene. Add the command box1 = box().

      3ds Max Design Window

       

      The command above creates a primitive type of box object with the name Box001 at x,y,z (0,0,0) as shown below.

      3ds Max Design Window

 

    • Let us begin by viewing all the exposed properties of the box object. We use the command getPropNames <object_name> i.e., getPropNames box1. This returns a thorough list of properties # (#typeinCreationMethod, #typeInPos, #typeInLength, #typeInWidth, #typeInHeight, #length, #width, #height, #widthsegs, #lengthsegs, #heightsegs, #mapcoords, #realWorldMapSize)

 

    • We can therefore manipulate the created scene object by changing the values of the associated properties.

        box1.length = 45
        box1.width = 100
        box1.height = 300

      3ds Max Design Window

 

  • Resultant object on scene is as shown below (notice changes in size as compared to the initial box object)

    3ds Max Design Window

As noted, each object type on the 3ds MAX does pose some properties that can be manipulated from the MAXScript side. A similar approach can be used to view properties for other objects like Sphere, Cylinder, Cone, etc.

 

Making Custom Properties

Building your own custom objects may require you to set up your own custom properties exposed to the MAXScript. This is important as many a times we use primitive objects to build complex objects that we may need to access and manipulate from the MAXScript. As such, any data exposed to MAXScript from the C++ side inherits from the Value type. You can read more about how Value type work in MAXScript here https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=GUID-911865D9-A5F9-4686-B01A-243308F41C55.

Creating a Custom Value Type

    • In your project, add a new class to your project, let us call it CustomValue, inheriting the Value type as shown below.

      3ds Max Design Window

 

  • With that set, add the following snippets to your .h file

    
            #include <maxscript/maxscript.h>
            #include <maxscript/foundation/numbers.h>
            #include <maxscript/foundation/3dmath.h>
            #include "resource.h"
    
            #ifdef ScripterExport
            #undef ScripterExport
            #endif
            #define ScripterExport __declspec( dllexport )
    
            class CustomValue : public Value
            {public:
                ENABLE_STACK_ALLOCATE(CustomValue);voidcollect(){ deletethis; }voidsprin1(CharStream* s);Value* get_property(Value** arg_list, int count);Value* set_property(Value** arg_list, int count);// Generic commands for copying/deleting/showing properties/etc.
                def_generic(delete, "delete");
                def_generic(copy, "copy");
                def_generic(show_props, "showProperties");
                def_generic(get_props, "getPropNames");
            };
    • What do these functions do?
      • void sprin1(CharStream* s)– returns a string representation of the object. When instantiating the object from MAXScript, a string is returned showing the default or set values.
      • Value* get_property(Value** arg_list, int count)– Used to get property values into the MAXScript side. When a property is accessed from the MAXScript i.e., during computation, this function is called automatically, and it returns the current set value of the property.
      • Value* set_property(Value** arg_list, int count)– Similar to get_property, but in this case use to pass a new value from the MAXScript to the c++. Basically, used to update property values. It is also called automatically when assigning a value to a property. I.e., box1.pos = [0.5,3.4,5.6]
      • def_generic(get_props, "getPropNames")– Defines a generic property called getPropNames used in Maxscript to return all property names that can be accessed from MAXScript and maps it to an internal function in our class called get_props.

     

    With all declarations done, let's now implement the functionality before adding new property types to our class.

    Value* CustomValue::get_property(Value** arg_list, intcount)
        {returnValue::get_property(arg_list, count);
        }Value* CustomValue::set_property(Value** arg_list, intcount)
        {returnValue::set_property(arg_list, count);
        }Value* CustomValue::delete_vf(Value** arg_list, intcount)
        {return&ok;
        }Value* CustomValue::copy_vf(Value** arg_list, intcount)
        {return this;
        }
    
        void
        CustomValue::sprin1(CharStream* s)
        {
            // String reprentation of the data ie Point3Vales
        }Value* CustomValue::get_props_vf(Value** arg_list, intcount)
        {
            // getPropNames <max_object> [#dynamicOnly] -- returns array of prop names of wrapped obj
    
            MAXScript_TLS* _tls = (MAXScript_TLS*)TlsGetValue(thread_locals_index);
            one_typed_value_local_tls(Array * result);
            vl.result = new Array(0);
            return_value_tls(vl.result);
        }Value* CustomValue::show_props_vf(Value** arg_list, intcount)
        {
            // showProperties <max_object> [_T("prop_pat")] [to:<file>]   - applies to ref0 in the wrapperreturn&false_value;
        }

     

    Let us add new properties. First, a property is defined as follows.

    • def_property(<property name>)– Added to the class
    • Value* CustomValue::get_<property name>(Value** arg_list, int count)– getter function for the property
    • Value* CustomValue::set_<property name>(Value** arg_list, int count)– setter function for the property

     

    Let us create a couple of properties that can be manipulated from Max side. We define it as follows.

    • Point3 m_pos– A Point3 object that we intend to expose to MAXScript
    • def_property(pos)– A property called pos that we will return the m_pos above
    • def_property(x)– The x-coordinate of the Point3 m_pos created
    • def_property(y)– The y-coordinate of the Point3 m_pos created
    • def_property(z)– The z-coordinate of the Point3 m_pos created

     

    Consequently, lets create the setter and getter functions for each of the properties above i.e.,

    Value* CustomValue::get_pos(Value** arg_list, intcount)
    {return new Point3Value(m_pos);
    }Value* CustomValue::set_pos(Value** arg_list, intcount)
    {
        m_pos = arg_list[0]->to_point3();return arg_list[0];
    }

    For the x,y,z properties, it is like the implementation above. Check the full code link attached for the implementation. Implement the get_props_vf function by adding the four properties to the result array.

    Last touches:

    • Added the 4 properties to the get_props_vf() function in the result array
    • Add a default constructor for the CustomValue and instantiate the m_pos variable to a Point3 value
    • Bonus, implement the show_props_vf() function in the CustomValue.cpp




    Bonus Tip!

    Building and Running the Snippet above


    This assumes you have already installed Visual Studio, 3ds MAX and 3ds MAX SDK. Check on how to setup the 3ds Max SDK and plugin wizard if you do not have that already. This is covered in the 3ds MAX documentation here http://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=installing_the_plug-in_wizard_ap



    To enable us to build and run our created class, we will be using a StaticInteface in a Global Utility interface (GUT) plugin type in 3ds MAX SDK. Let us first create a global utility object (GUT) using the Plugin Wizard. The wizard will create a barebone project with all required functions for us to implement them.

     

    3ds Max Design Window

     

    Next, we will add a static interface to expose a static object to the 3ds MAX side. This is the instance we will be using when getting and manipulating properties from the MAXScript. In Visual Studio, add a new class, let us call it ADNStaticInterface and add the following snippets.

    class ADNStaticInterface : public FPStaticInterface 
    {public:// The follow exposes our functions to Maxenum FN_IDS {
            fn_run1
        };BEGIN_FUNCTION_MAP                FN_0(fn_run1, TYPE_VALUE, run1);
        END_FUNCTION_MAP// Implement the functions exposed aboveValue* run1();// General purpose exposurestatic ADNStaticInterface* GetInstance(){ return&_theInstance; }private:
        DECLARE_DESCRIPTOR(ADNStaticInterface);// The single instance of this classstatic ADNStaticInterface _theInstance;// Point3CustomValue *m_customValue;
        CustomValue* m_customValue;
    };

    We first begin by exposing our function to MAX; first an Enum of function ids (fn_run1)

    • Value* run1() - This defines a function that will be called from Maxscript and returns a Value type. The return value object will allow manipulation of the properties.
    • static ADNStaticInterface* GetInstance()– Returns a static access object

     

    Let us implement the declared functions. Beginning with the

    
    ADNStaticInterface ADNStaticInterface::_theInstance
    (
        IADN_STATIC_INTERFACE, _T("ADN"), 0, NULL, FP_CORE,
        ADNStaticInterface::fn_run1, _T("run1"), 0, TYPE_VALUE, 0, 0,
    
        p_end
    );
    

     

    The function declares an ADN (Autodesk Developer Network) object that can be used from the MAX side to call the functions in the C++ side.

    Value* ADNStaticInterface::run1()
    {
        Point3Value* nValue = new Point3Value(0.0, 0.0, 0.0);return nValue;
    }

     

    The run1 function returns an object to the MAXScript side. We have just set up a Point3Value to be returned to the MAXScript. The Point3Value is a Point3 type which inherits from the Value class to enable exposing the values to MAXScript.

    Let us build and run the code to test if all works so far. Run the project within visual studio, with 3ds MAX launched, open the MAXScript listener window and run the command apt = adn.run1(), you should be getting an output like below.

     

    3ds Max Design Window

     

    If that works so far, let us now proceed to building our own custom value type. Remember all values exposed to Maxscript must be of the Value type (inherits from the value type).

     

    Running the custom value to the Static Interface Attach the new CustomValue to the ADNStaticInterface class and return it in the run1() method.

    • Include the custom value header to the ADNStaticInterface.h
    • Add a private member object of the CustomValue type i.e., CustomValue* m_value
    • In the run1() function, instantiate the CustomValue and return it from the function.

     

    Run the program and manipulate the properties as shown below.

    3ds Max Design Window

     

    Check out the full project code attached or from the git link below.

     

    Source Code on Github

     




    I hope that was quite descriptive way of creating your own custom value type for MAXScript. I would love to hear if you find better ways of doing it.

    Any questions? Feel free to reach out. Cheers!

Learning 3ds Max SDK - My Journey

$
0
0

image001

Image adapted from http://aneeswork.blogspot.com/2015/10/3d-interior-design-3ds-max-vray.html

Learning 3ds Max SDK: My Journey

One thing has always fascinated me for a very long time, that is, programming. I used to really wonder how big software did work and how they came to being. The absolute beauty of just writing English grammar with some semantics and later the computer gets to understand it, isn’t that just awesome?

My journey learning 3ds Max and 3ds Max SDK was not that easy. Let’s be frank, transitioning into a new codebase, semantics, UI, documentation, etc. is overwhelming at start.

So, why learn the SDK?

Let’s address the elephant in the room, the why question. It’s with no doubt if you ever used any software, you ever felt like, “I wish I had this feature” or “I wish this was simpler” or “I wish I could be able to just automate these tasks”. Yes, I know the frustration of sometimes finding out what you wanted isn’t available or is just long and tedious. We mostly solve some of such tasks with keyboard key-bindings (shortcuts) but some tasks are not that simple for such operations. That’s where the SDK comes into play. Giving you the ability to make and tweak as you wish.

With access to the APIs through the SDK, you are given the power to make your own custom plugins to add or modify existing tasks, automate operations like rendering, generations, etc. and much more! But with such power comes some responsibility, let’s look at them in a bit!

Prerequisites

To be able to learn 3ds Max and its SDK, you require some tools and knowledge.



NOTE: This is very important to note: Depending on the 3ds Max version you chose, let’s say 3ds Max 3ds Max 2023, each version supports a specific SDK version, Visual Studio compilers, Qt version, etc. Always check for the right versions from the site https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=sdk_requirements. This gives each MAX version and the compatible OS, SDK, C++ compiler, .NET framework and Qt version.


So where do I start?

With all the pre-requisites satisfied, am sure you have a strong quest to get your feet on the move. 3ds Max is a big software, developed for decades. As such, it comes with history of then and now. Depending on the material you can get your hands on to read or watch, you may be getting old concepts that may have been deprecated or changed to new formats. Always keep that in mind.

3ds Max introduces some new terminologies, youll get to hear things like modifiers, reference systems, parameter blocks, nodes, etc. Delving into these topics right away seems a bit overwhelming. Here is how I handled it:

  • Learn 3ds Max UI basics first– To understand how things work behind the scenes, we need to know how its handled on the scene. User interaction with the software is important and most critical and a s such, knowing how to work as a user gives you knowledge of how objects are modified stack by stack till you attain a desired 3d object. The areas to start with are:

    • Basic geometric objects– Getting to know how to create box, sphere, cylinder, etc. objects on scene. This also entails, how to modify the parameters of such objects like length, width, height, segments, etc.
    • Transforms– This is basically 3d manipulations on an object on scene. It’s applied on the entire object and its independent of the shape of the scene object. It’s the object position, rotation, and scale.
    • Modifiers– This is how the basic shapes are changed. Adding modifiers on them allows manipulation of the underlying object. For instance, adding a bend modifier on a straight object gives an output as shown below. Check out how such a modifier is added and resulting effect on the object here https://help.autodesk.com/videos/0zd2FvbTrAtMzQjiHcH39SnEZstxFDYC/video.webm. Other types of modifiers are: Edit poly, OpenSubdiv, chamfer, shell, etc.


    image002



    • Animation and animation controllers– This entail adding motion to scene objects. 3ds Max comes with a couple of animation controllers that you can attach to your object on scene. The keyframe timeline allow for keyframe manipulation of the animation motion. A basic understanding of how to do animation and use the different tools on the UI for the same purpose is important to working with animation on the SDK later. Learn more here https://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=interactivehelpanimation_animation_controllers_html.
    • Lighting and Rendering– After all modification on objects has been completed, we add lights to give a realistic object before it rendered out to a desired output format. This section will give insights of the different render engines and how they work, how to work with different light types, working with cameras, etc. Here is a pictorial of scene lighting. Read more on this here https://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=interactivehelplighting_rendering_html.


    image003



    • Materials– Creating realistic objects require a look a feel with what we do interact with in our day to day lives. Materials are data that is assigned to the surface/faces of objects to make it appear a certain way when rendered. They include but not limited to iron, steel, leather, wool, etc.


  • Learning the SDK– With the UI basics covered, learning the SDK is less overwhelming. So, how do you go about it?

    • Hello World!– As any standard practice, begin with a hello world program. 3ds Max SDK documentation has a good tutorial to hep you do exactly this. Check out https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=lesson_1_sample_utility_plug-in on how to begin a simple utility plugin. [I do assume you did setup the plugin wizard on your visual studio installation]. The code sample below shows a text Hello World on the prompt stack in the 3ds Max UI.

      ip->PushPrompt(_M("Hello World from Lesson 1"));

    With that out of the way and well understood, lets now look at other concepts of the SDK.

    • 3ds Max SDK: The Learning Path – This is a series of lessons covering different aspects of the SDK. The tutorial is available at https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=3ds_max_sdk_-thelearning_path. Let’s have a rundown of what it entails:
    • Sample Utility– This is the hello world program for a utility plugin. Will give you a rundown of what it takes to setup a plugin project, explanation of all files in the project as well as what the different functions generated by the plug-in wizard generated.
    • Scene Graphs & Nodes– Scene objects (geometric objects, lights, cameras, etc.) in 3ds Max and the relationship with each other are stored in a scene graph. This gives a good understanding of the scene graph structure, how to transverse the scene graph and manipulate the nodes (add, remove, update as well as a sample code that shows a simple graph exporter into a text file.
    • Reference System– Think of this to get updates from changes when entity changes in scene. From a Qt background, think of it has the signal/slot mechanism but way different. This gives an understanding of how plugins can propagate changes on scene through which other plugins/objects can get the changes. A good understanding of this subject will make it easy developing plugins since most times plugins depend on external data on scene and need to be notified of the changes as well as modify them and cause appropriate change propagation.
    • Animation Controllers– These are plugins that provide 3ds Max the value of a parameter for a scene object at any given time. Think of it as a function that given the time (keyframe timestamp) it returns the property value at the given time. This section goes through how to implement a simple controller to achieve scene object animation over time.
    • Geometric Objects– On the 3ds Max scene, objects created by mouse clicks, or any other means is because of combination of one or more geometric shapes. This is used for creating 2D shapes like circles, squares, boxes, triangles, etc. or even 3d like cylinder, box, etc. God understanding of this gives enough knowledge to aid in developing custom shapes and objects on scene or even modify existing shapes.
    • Parameter Blocks– This is a 3ds Max way of reading from and writing to plug-in parameter values which is independent of the plug-in type. This is 3ds Max specific implementation giving ease of sharing plugin data, easy updates by other plugins, easy serialization, etc. This section seems intimidating at first to grasp but it’s one of the most critical to understand well for you to develop plugins that can maintain and share parameter states with other plugins.


  • 3ds Max Webcast Tutorials– Similar to the learning path above, the webcast was initially done as virtual tutorials to train on 3ds max SDK topics with assignments after each topic. Unlike the learning path, the webcast goes an in-depth with explanations of why thigs are done the way they are done. This gives a better understanding of the concepts conveyed both in the documentations and the learning path tutorials. With an addition of assignments after each section, this gives room to try out from knowledge learnt with assurance of explanation of the required response if not well understood or if stuck. Although this content is old, upgrade of such content is underway. Let’s look at the main sections that prove to be useful for a beginner.

    • General 3ds Max customization Introduction– This goes through 3ds Max UI overview and how it can be customized, a rundown of MAXScript usage in scene objects manipulation, the .NET API in 3ds Max and 3ds Max SDK usage.
    • Getting started in the 3ds Max SDK basics – This section goes into the SDK basics, terminologies, plug-in types, and a rundown of the basic scene concepts (Scene, Node, References, Parameter Blocks, Animation, etc.)
    • Transformation and Scene, Node, Scene Graph– Scene objects are represented by Nodes on the scene graph. So, this section explains how transformation (translation, rotation, scale) of the scene is done, scene compositions, scene objects and scene graphs manipulation & its traversing.
    • Reference System– If you didn’t understand how reference systems work from the Learning path, this will be your teacher. It goes in-depth on how reference systems work, the logic behind, as well as good/bad practices in reference systems in 3ds Max.
    • Parameter Blocks and Function Publishing– Similar to what is detailed in the learning path, this explains parameter blocks systems, its implementation and expound on the concepts that make it such a powerful concept behind the 3ds Max robustness. In addition, this section goes to give an introduction into function publishing - a concept for exposing functions in C++ to the MAXScript.
    • Geometry Fundamentals– Further from what was covered by the geometry section of the learning paths, this section goes further into covering shapes, splines, patches, and meshes in the making & manipulation of scene objects.
    • Modifiers– Similar to what was mentioned under 3s Max UI learning, modifiers here look at how to make custom modifiers that manipulate objects, edits, mapping coordinates and world space. Such modifiers are bend, taper, twist, extrude, surface, etc.


Tips & Tricks

Fast learning does exist, but pitfalls are the hindering factor. Here are my suggestions based on what I did learn in my journey:


  • Use the Webcast & the Learning path tandem– Some of us like reading, some like watching, depending who you are, try watching the concepts and listening to the in-depth explanations then later go do the reading on the learning path and/or the 3ds Max SDK documentation. This may save you hours of wondering what you are reading.
  • Don’t go too deep– Quite controversial, but, if your intent is to work with the SDK then, take care you don’t get too deep learning the UI. Autodesk gives recommendation of tutorials to follow to learn the UI section, which is very detailed. You may look at specific sections to know the basics then later go deeper as needed.
  • C++ is important!– Learning the SDK requires some level of understanding C++ concepts. Sharpen your knowledge/skills there first since there is less/no explanations of such concepts once you start working with the SDK.
  • Be careful with burnout– Yes, this is real. The SDK concepts are a lot, I don’t expect you to master all in a single day. Give yourself time, rest whenever you feel overwhelmed, and most important – reach out for any questions.
  • Make SDK examples & samples your charm!– The 3ds Max SDK ships with samples and example code which you can refer to see how things were implemented. Be careful to always change the plug-in class IDs to avoid conflicts with the default implemented plug-ins.
  • Check attached samples for tutorials– Both the Learning path and webcast material have completed code samples. Check on them in case things are not working as expected. The Learning path and the webcast Github/videos/materials can be found in the links below.

Learning Path Github Repository - https://github.com/ADN-DevTech/3dsMax-Learning-Path
3ds Max Developer Center - https://www.autodesk.com/developer-network/platform-technologies/3ds-max#3dsmax-sdk


Developer center provides 3ds Max SDK Training Webcasts in both English and Japanese and a separate Download for the training materials. Videos are provided in a zip file.



I hope this will help you in your journey to learning 3ds Max SDK.


Any question? Any suggestion? Feel free to reach out!



3ds Max 2024 Released!

$
0
0

2024_blog

Well, another year has passed, and another great release of 3ds Max has arrived. Check out the new features of 3ds Max 2024 here.
Changes for the 3ds Max 2024 SDK are documented here. Highlights from the SDK include:

  • SDK Break - means you should recompile any plugins for use with 3ds Max 2024.
  • 3ds Max 2024 and the SDK are now using C++17 as a standard. For bringing older plugin code into the 2024 SDK, you should consider changing the project settings to use C++17 (C/C++ -> Language -> C++ Language Standard) to be ISO C++17 Standard. This is especially important for newer headers and API features to be compatible. For all the details, see here. The plugin wizard and underlying property pages are already updated.
  • New Color Management API
  • Mesh and MNMesh changes  (Note that BezierShape is mentioned there, but it is a mistake... no changes to that class).

Another change for the 2024 release is that the https://manage.autodesk.com download now does not include the SDK due to size restrictions. You can get the SDK from the 3ds Max developer center here, or from the ADN Member site. Note that we are also posting the 3ds Max USD SDK in those locations as well.

For all the changes to the customization environments, check out these sections:

 


Porting MaxPlus to pymxs - What you need to know

$
0
0

Porting MaxPlus to pymxs - What you need to know

Introduction

As of 3ds Max 2022, the MaxPlus library is deprecated. This blog intends to assist those using MaxPlus to transition to pymxs for 3ds Max. This article will focus on an example of porting the xref system from MaxPlus to pymxs.

As of 3ds Max 2021, MaxPlus was not supported in Python 3. From 3ds Max 2022, shipping of MaxPlus stopped as pymxs became the supported Python scripting in 3ds Max. Check here for complete documentation https://help.autodesk.com/view/MAXDEV/2022/ENU/?guid=MAXDEV_Python_what_s_new_in_3ds_max_python_api_html.

3ds Max Scripting

Scripting in 3ds Max has been a powerful tool for automating tasks and creating custom plugins that extend the functionality offered by 3ds Max or introduce new features not present in the software. This capability is crucial in Design Automation, where activities are executed within the Autodesk Platform Services (formerly known as Forge). To harness the power of scripting, 3ds Max provides two primary options: MAXScript, the native scripting language of 3ds Max, and Python, a wrapper around MAXScript. By leveraging these scripting languages, users can achieve high flexibility and control over 3ds Max. Additionally, 3ds Max offers SDKs for C++ and C# for those who prefer plugin development, allowing for the creation and extension of capabilities within the software.

Scripting in MAXScript

MAXScript comes baked into 3ds Max by default and is accessible o the bottom left window of the UI or through the Scripting menu option in 3ds Max.

Scripting menu option in 3ds Max 2023

For instance, click the Scripting Listener option on the drop-down above to launch the scripting window. This brings a Scripting listener window with two choices of MAXScript and Python. Scripts can be inputted and executed in the editor window when we move to a new line, as shown below.

MAXScript listener window showing script execution

To learn more on how to use MAXScript and its complete tools, look at the documentation here https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=GUID-F039181A-C072-4469-A329-AE60FF7535E7.

Scripting in Python

Scripting in Python has been an option for quite some time now. Initially, 3ds Max exposed its APIs through a library called MaxPlus (https://help.autodesk.com/view/3DSMAX/2019/ENU/?guid=__developer_maxplus_python_api_introduction_maxplus_python_api_main_classes_html) which became deprecated in 3ds Max 2019 and was replaced by pymxs. Both libraries work differently and have differences in functionalities that get exposed to Python.

To compare the difference, the code below shows how the code structure looks to create an object on scene and modify its parameters.

import MaxPlus

obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box)
obj.ParameterBlock.Width.Value = 10.0
obj.ParameterBlock.Length.Value = 10.0
obj.ParameterBlock.Height.Value = 10.0

 

import pymxs

obj = pymxs.runtime.box(width=10.0, length=10.0, height=10.0)

 

Why the difference?

If you are familiar with 3ds Max SDK, the MaxPlus code has a similar approach when creating objects. It’s generated from the C++ SDK, so its code system follows how it’s done in C++ or in .NET.

Unlike MaxPlus, pymxs, on the other hand, follows a different approach. Notice the first code we did for MAXScript to add a box to the scene, similar - right? Pymxs is built as a wrapper around MAXScript rather than the C++ SDK. As such, the code looks more straightforward to understand if you know bits of scripting in MAXScript.

Porting MaxPlus to pymxs

Let’s say you have some old scripts you made in MaxPlus, and you want to port them over to the recent version of 3ds Max, but now, the latest 3ds Max versions no longer ship MaxPlus libraries. The option is porting the codebase to either C++/.NET, MAXScript or Python. Let’s look at some examples:

1. XREFS

xrefs is a terminology for external referencing other files or scenes in the current scene. This prevents loading whole exterior projects into the current project but instead just referencing it. MaxPlus provides direct manipulation of xref files as follows:

 

File counting

import MaxPlus

num_xrefs = MaxPlus.XRefs.GetXRefFileCount()
print(num_xrefs)

An equivalent pymxs code for a similar functionality is given below

import pymxs
num_xrefs = pymxs.runtime.xrefs.getXRefFileCount()
print(num_xrefs)

 

Getting xref file

Once xrefs are created within a scene, retrieving specific xref files for any purpose can be achieved as follows in both MaxPlus and pymxs

import MaxPlus

index = 0 # index of the xref file
xref_file = MaxPlus.XRefs.GetXRefFile(index)
print(xref_file)

# IN PYMXS

import pymxs

index = 0 # index of the xref file
xref_file = pymxs.runtime.xrefs.getXRefFile(index)
print(xref_file)

Note that both require a parameter specifying the index of the XRef file to get information about.

 

Setting xref file

This is intended for setting a file to xref

import MaxPlus

# get the XRef object that you want to set the file path for
xref_object = MaxPlus.Core.GetINodeByName("MyXRefObject")

# set the file path for the XRef object
file_path = "C:/path/to/my/xref/file.max"
MaxPlus.Core.SetXRefFile(xref_object, file_path)

Note that this code represents a workaround for updating the XRef file since there is no direct way to update the file in pymxs.

import pymxs

index = 1
# Get the XRef object for index 1
xref_obj = pymxs.runtime.xrefs.getXRefFile(index)

new_file = "path\to\file\something.max"

# Using MAXScript in pymxs
maxscript_code = f'''
axref = xrefs.getXRefFile {index}
axref.filename = "{new_file}"
flagChanged axref'''

_axref = pymxs.runtime.execute(maxscript_code)

print(_axref)

 

Flagging xref file as changed

Used to flag that the xref has been changed.

import MaxPlus

# get the XRef object that you want to flag as changed
xref_object = MaxPlus.Core.GetINodeByName("MyXRefObject")

# flag the XRef object as changed
MaxPlus.Core.FlagXrefChanged(xref_object)

To flag specific file as changed, pymxs doesn’t expose any way to directly do that. Alternatively, we can invoke MAXScript to flag the files as changed as shown;

import pymxs

index = 1 # Index for the xref you want to flag as updated

maxscript_code = f'''
axref = xrefs.getXRefFile {index}
flagChanged axref
axref'''

_axref = pymxs.runtime.execute(maxscript_code)

print(_axref)

 

Updating changed xrefs

Updates the XRefs that have been flagged as changed. This function actually loads the new versions of the referenced files and updates the XRefs in the scene accordingly.

# In MAXPLUS
import MaxPlus

# update all XRef objects that have been flagged as changed
MaxPlus.Core.UpdateChangedXRefs()

# In PYMXS
import pymxs

# Updates the changed XRefs and resets their changed flags
pymxs.runtime.xrefs.updateChangedXRefs()

 

3. Animation

Getting Animation Range

Getting Animation Range is used to retrieve the animation range of the current scene.

import MaxPlus

# get the animation range of the current scene
start_time, end_time = MaxPlus.Animation.GetAnimRange()

# print the start and end times of the animation range
print("Animation Range:")
print("Start Time:", start_time)
print("End Time:", end_time)

MaxPlus's corresponding function in pymxs returns a pair of time objects: the first element of the tuple is the animation range's start time, and the second element is the animation range's end time.

import pymxs

# Get the animation range in 3ds Max
anim_range = pymxs.runtime.animationRange

# Print the start and end times of the animation range
print("Start Time:", anim_range.start)
print("End Time:", anim_range.end)

 

Getting current time

Returns current time in the animation

import MaxPlus

# get the current time in the animation
current_time = MaxPlus.Animation.GetTime()

# print the current time to the console
print("Current Time:", current_time)

The following code samples are used to get the current time when animating in pymxs.

import pymxs

# get current time 
current_time = pymxs.runtime.currentTime

# Log the values
print(current_time)
print(current_time.frame)
print(current_time.ticks)

Conclusion

The samples do not cover all the aspects of porting code from MaxPlus to pymxs. However, the complete guide can be found on the documentation at https://help.autodesk.com/view/MAXDEV/2023/ENU/?guid=MAXDEV_Python_using_pymxs_maxplus_to_pymxs_html. The guide aimed to give ideas on how to look at porting current codes to pymxs.

 

We have looked at both pymxs native functions similar to or representing the MaxPlus functions and embedding MAXScript in pymxs to achieve functionality not currently exposed to pymxs.

 

FAQ’s

  • Are MaxPlus and pymxs one-to-one match?

    No. Due to the architecture, these two bear different exposure to underlying functionalities. So, some functions and modules in MaxPlus are not available in pymxs and vice versa.

  • Can I convert my MaxPlus code to pymxs fully?

    Yes. MaxPlus code can be ported to pymxs, but no one-to-one conversion exists. Note that you’ll need to combine pymxs and MAXScript for some functionality to achieve it. It’s all about getting similar functionality.

  • So, what about pymxs and MAXScript?

    pymxs is a MAXScript wrapper but not all functionality and properties in MAXScript are directly generated into pymxs modules/functions/properties. There are workarounds but not direct functions/modules like the ones in MAXScript.

Saving QWidget Docking States per 3ds Max Scene

$
0
0

Cover

The Flexibility of Docking Windows

Within 3ds Max, windows and panels can either float freely or be docked onto another panel, providing a customizable layout tailored to the user's preferences. This flexibility proves vital, especially considering the diverse screen sizes and DPI configurations prevalent today. Ensuring our tools are strategically positioned enhances the user experience without compromising the workspace.

Docking isn't confined to native Win32 UI elements; 3ds Max supports the creation of custom tools (plugins) using Qt for the UI. This empowers developers to build robust tools that seamlessly align with their workflow. Even commercial tools can be crafted with the flexibility of docking to existing UI elements.

Crafting a Dockable Widget in Qt

To create a dockable widget in Qt for 3ds Max, we typically derive a widget class from QDockWidget. In the context of 3ds Max plugin development, the QMaxDockWidget offers enhanced control and integration with the 3ds Max UI elements. The SDK provides a variety of UI elements, accessible in the <sdk installation path/include/qt/> directory.

Here is an example:

 

// Code Excerpt

class ADNSampleQmaxDocking

    : public UtilityObj,

        public MaxSDK::QmaxDockWidget

{

    // ... other member functions

public slots:

    void onTopLevelChanged(bool isFloating);

private:

    void LoadSavedLayout(); // To load saved layouts

    // ... other member variables

    QString m_layoutPath;

    MaxSDK::QmaxMainWindow* qmaxMainWindow; // Save a reference to the Qt MainWindow

};

 

The code skeleton above outlines the necessary structure for creating a dockable Qt widget for a UtilityObj-derived plugin. Remember that, as a UtilityObj plugin, additional functions must be implemented. Our constructor initializes the dock widget and sets the QSettings saving path.

Below is an excerpt from the constructor:

 

// Code Excerpt

ADNSampleQmaxDocking::ADNSampleQmaxDocking(MaxSDK::QmaxMainWindow* parent)

: iu(nullptr), QmaxDockWidget(parent)

{

    // ... other initialization

    // Set the desired directory

    MSTR path = GetCOREInterface()->GetDir(APP_SCENE_DIR);

    path.append(_M("\\dockslayout.ini"));

  // ... other setup

    m_layoutPath = QString::fromWCharArray(path);

    show();

}

 

The constructor establishes the default dock position, sets the desired save directory (we have used the scene directory in this example), and creates a filename for the .ini settings file. To load the layout after initialization, we implement the `BeginEditParams` function:

// Code Excerpt

void ADNSampleQmaxDocking::BeginEditParams(Interface* ip, IUtil* iu)

{

    // ... initialization and adding plugin widgets

    // Load the saved scene layout file if it already exists

    LoadSavedLayout();

    // Connect topLevelChanged for the dock window to the saving of the layout

    connect(this, &MaxSDK::QmaxDockWidget::topLevelChanged,

                 this, &ADNSampleQmaxDocking::onTopLevelChanged);

}

 

We connect the `topLevelChanged` signal, saving the new layout only when the window is docked. The two slots, `onTopLevelChanged` and `LoadSavedLayout`, complete the setup as shown below.

 

// Code Excerpt

void ADNSampleQmaxDocking::onTopLevelChanged(bool isFloating)

{

    // Save on docking state

    // The isFloating flag can be used to save the docks when not floating

    qmaxMainWindow->saveLayout(m_layoutPath);

}

void ADNSampleQmaxDocking::LoadSavedLayout()

{

    try

    {

        qmaxMainWindow->loadLayout(m_layoutPath);

    }

    catch ()

    {

        // Handle errors

    }

}

Executing the application and starting the plugin will create the .ini file in the selected directory if it doesn't exist. This file saves not only the single plugin but all widgets and toolbars in use, restoring them if they are already open.

Leveraging Qt in 3DS Max

In conclusion, when building UI in Qt for 3ds Max, utilizing Qt tools already integrated into the software provides an elegant solution for saving and restoring docking states. Further optimizations and adjustments can be made to meet specific needs. The full code is attached below as a .zip file; feel free to explore and share your thoughts on this functionality.

Happy coding! Cheers!

Full project source code: Download ADNDockingSample 





Latest Images