Menu Close

Category: csTools

Substitute modifier mini tutorial and csStackCache

Substitute modifier is one of the most underrated modifiers in 3dsMax and one of my favorite modifiers. As the name suggests, this modifier replaces the object’s mesh/poly. How to use is very simple. Just apply the modifier, turn on “Pick Scene Object” button and pick an object in the scene to substitute.

You can choose to use the substitute mesh only for viewport or render.

You can also choose to use an object from another max file.

We can think about a few useful situations such as…

  • I already have a big stack and animation started from Box. Now I wanted to start from ChamferBox instead of Box.
  • I can substitute highres objects with low res ones only for viewport to make viewport faster.
  • I can have low res placement holder objects in the scene and substitute with highres objects in another max file.
  • You can have multiple versions of mesh in an object while keeping all the connection to other portions of 3dsMax.

BUT! That’s not all. Substitute modifier has more super powers.

It automatically disables the evaluation of all the modifiers under it

It makes sense since the Substitute modifier provides a mesh from the stack point. Whatever at the below of the stack doesn’t do anything in any way. The best part is that you don’t have to set anything manually. This modifier just does it. Combined with the feature that allow to use Substitute modifier only for viewport display, this provide a great work around to improve the scene performance when you have a lot of hires animated meshes.

For example…

  • if you substitute an animated tree with a static low res tree, this modifier blocks the evaluation of animation.
  • If you have an animated alembic cache object, this modifier will stop loading the alembic file every time when you scrub through. In the following image, I snapshot a frame and used that for display using Substitute modifier. You can see alembic object stopped loading  the cache file.
  • Turn off VRayVolumeGrid preview which will load files and update every frame. Make a preview mesh and use Substitute modifier to display it. This will allow you to directly place vdb without waiting for every singler cache file loading.

It can embed the replacement mesh data in the modifier

This is a really really powerful feature. After you pick an object from the scene, you can delete the object. Then, the modifier will hold the mesh information in itself which essentially act as a cache modifier.

This means that you can collapse the stack while keeping all the history. l Some of you probably have been duplicating objects and collapse in the scene and save a copy in another max file for future use. You don’t need to do that any more. Everything can be just stored in the same scene

one of the benefit of caching a big stack is to improve max file loading time. I want to cover this topic in depth some day. In short, 3dsMax file doesn’t save the result of stack in the .max file. If you make a Box and apply Bend modifier. 3dsMax just stores the class(Box, Bend and its parameters. Then, when the file is loaded, it evaluates all the classes and generates a mesh. This means if you have very big stack or very calculation intensive modifiers. The file opening can take a long time. That’s why some modifiers like Boolean, Conform or Retopology have own caching mechanism. With Substitute modifier, you can cache any objects with modifier in the scene if you want. Obviously, it has a trade off. It will increase the max file size. You gotta pick your poison.

Another benefit is that it can be used as a countermeasure for possible mesh corruption. As a procedural evaluation system, if anything goes wrong in the middle of the stack, the above of the stack would produce an unwanted result. For example, Edit Poly is an awesome and powerful modifier. But, it can be fragile with certain operations. In fact, Edit Poly never stored the result of change in the modifier. It is actually a mini stack in a stack. It stores every operation you did and re-execute then you open the file. So, even tho it is slim, there is a chance that one of hundreds of operations, especially one that removes or adds sub-objects, could go wrong. For that case, you can use Substitute modifier to lock/freeze the status of stack.

csStackCache

So, I made a small script called csStackCache to take advantage of Substitute modifier’s super power. You can find from csTools > csStackCach in the Customize UI dialog.

How to use is simple.

  1. Select objects that you want to cache.
    • All – all geometry objects
    • Selection – Selected objects
    • Selection Set – the chosen selection set
  2. Press “Cache”.
    This script will add a Substitute modifier named “csStackCache” just above of the first viewport enabled modifier. In the following image, It is added under TurboSmooth because it was set to Off in Viewport.

    If you already had “csStackCache”, it will use the position. So, if you need to add “csStackCache” at certain position. Use the “Add Cache” button to add and move around it. Then, Cache them. For example, if you have any animated modifiers, you will need to cache blow the modifiers. If you cache above them, it will freeze animation.
  3. If you want to remove “csStackCache”, select objects in the same way and pres “Remove Cache
You can download csStackCache from here.

BUT! I want really want to set a built-in “Cache” button in this modifier. That will be much faster than my scripted solution. So, please visit here and vote for me!
https://forums.autodesk.com/t5/3ds-max-ideas/add-quot-cache-quot-button-in-the-substitute-modifier/idi-p/12470220

 

csSetClippingPlane

There has been many requests for providing a way to adjust clipping plane by numbers.
Your voice was heard. 3dsMax 2024.2 bring MXS exposure for the clipping plane.

vpSetting = NitrousGraphicsManager.GetActiveViewportSetting()
vpSetting.ViewportClippingEnabled = true
vpSetting.ViewportClipNear = 0.05
vpSetting.ViewportClipFar = 0.8
vpSetting.ResetViewportClipNearFar()

Note: Same as UI, the allowed range of near/far is [- 0.1, 1.1], and the specified value should obey the rule: near < far

Of course, I know there are many who don’t/can’t script. So, I made a script for you which you saw in my video.

Download csSetClippingPlane here!

csMakePreview 1.21

csMakePreview is a scripted UI of the newly improved MXS createPreview function in 3dsMax 2024. For the details, please check this post. Now it has been updated to 1.21 with a few new features including the new Mini mode.

Download csMakePreview 1.21 Here

 

Mini Mode

  • Press Mini Mode button to change to Mini mode.
    Mini mode on.off status will be saved in the settings file which means it will be kept across max session.
  • Only few options are exposed in Mini mode.
    The intended workflow is making presets using full mode and use for Mini mode.
    .
  • If you want to return to full mode, click “Mini” button.

Other new features

  • Custom resolution by pixel. Turn on the “Resolution” button and set the preview resolution as you want.
  • <version> token.
    It’ll add 3 digit padded version number.
    This value is saved for each scene file. So, you will know which version you used last time for the scene.
  • Preview path preview button
    This button will show the preview of the resolved preview path. If you press button, the preview path will be printed in the listener.
  • Open/P{lay button will be disabled then there are no files in the preview path.
    When button is disabled, the line color will be slightly darker(left).
  • Quality Override for the temporary override of ShadowMap size and Anti-Aliasing setting.
  • Play When Done moved to Settings dialog.

Other features

csMakePreview looks similar and based on 3dsMmax MakePreview. But, it has a few additional features.

  • Use Current Viewport Settings check button
    If this button is on, the current Viewport Preset/Stylem Edges Faces and Texture settings of the active viewport will be used. Basically, it will make a preview as you can see in the viewport. This is on by default.
  • The output path textbox is editable.
    You can directly type/edit in the textbox.
  • Token support!
    It supports all tokens in “Name Template”.  You can also use any global variable or global function.
    For example, you can make a  setPrefiewPath global function and set <setPrefiewPath> as path. This script will run the global function and use the result as the output path.
    Ot, If you want to add fps in the name, you can use <FrameRate>.
  • mpt4 support via ffmpeg
    You need to download ffmpeg by yourself and set the path in the Settings dialog. Eventually.
  • Ramplayer, ChaosPlayer, Custom player support.
    To use a custom player, you need to make csPlayPreview global function with 4 arguments [output path], [fps],  [start], [end].
  • Play Preview button
  • Open the preview folder button
  • Presets
    you can save/load as many as presets you want.

 

cs_sme_drop

It seems everybody loves the new multiple image drag and drop to Slate material editor in 3dsMax 2024.1.

As I mentioned in the video. You can make own function for the new callback. Here is an example script that supports VRay, Corona, Arnold and OSL map. You can add this as a startup script folder. It will auto-detect VRay, Corona, Arnold, FStorm, Octane, Redshift and make a native image loader for each renderer. If you edit as “local useOSL = true”, it will generate OSL UberBitmap.

Here is the download Download - Updated to 1.1

Here is the code.

-- cs_sme_drop v1.1
-- by Changsoo Eun
-- www.changsooeun.com
(
local maxver = (maxversion())
if maxver.count > 7 and maxver[8] > 2023 and maxver[5] > 0 then (
fn cs_sme_drop test urls pos = (
if not test then (
for f in urls do (
-- Set this to true if you want OSL UberBitmap
local useOSL = false
local amap = (bitmaptexture())
amap.filename = f
if useOSL then 
(
amap = (osl_UberBitmap2b())
amap.filename = f
)
else
(
if Corona != undefined and ((classof renderers.current) == Corona) then (
amap = (CoronaBitmap())
amap.filename = f
)
if vray != undefined and (matchpattern (renderers.current as string) pattern:"*v_ray*") then (
amap = (vrayhdri())
amap.HDRIMapName = f
)
if (matchpattern (renderers.current as string) pattern:"*FStorm*") then (
amap = (FStormBitmap())
amap.filename = f
)
if (matchpattern (renderers.current as string) pattern:"*octane*") then (
amap = (RGB_image())
amap.filename = f
)
if (matchpattern (renderers.current as string) pattern:"*redshift*") then (
amap = (RS_Bitmap())
amap.tex0_filename = f
)
if Arnold != undefined and ((classof renderers.current) == Arnold) then (
amap = (ai_image())
amap.filename = f
)
)
if useOSL then (
pos.x += 100
)
else(
pos.y += 100
)
amap.name = (getFilenameFile f)
(sme.getview sme.activeview).createnode amap pos
)
)
true
)
sme.fileDropCallback = cs_sme_drop
)
else (
messagebox "3dssMax 2024.1+ is required"
)
)

 

csMakePreview

3dsMax 2024 bring a lot of new features. Some of them are hard to show in a video. This is one of those features.

I always have wanted to have a modified version of Make Preview. For example, if you are a pipe guy at a studio, you probably would not want to give assess to the output path to artists. How about forcing some consistent studio-default options?

I have used UIAccessor in the past. I also know some studio just made their own make preview utility. But, with the update in 3dsMax 2020, I really wanted to use Max’s own Make Preview engine since it can make bigger than screen size preview.

There is a MXS command, createPreview. But, it didn’t have all the functionality of UI version. Especially, there was no way to control viewport settings. Finally, the 3dsMax 2024 createPreview function exposes every single UI option to MXS function.

So, I re-created Make Preview dialog as a script for the following reasons.

  • I wanted to check if it still misses anything compared to UI.
  • I wanted to give a template implementation for other users.
  • I wanted to add some of the features that users wanted
Download csMakePreview from here.

The added features

  • Use Current Viewport Settings checkbutton – If this button is on, the current Viewport Preset/Stylem Edges Faces and Texture settings of the active viewport will be used. Basically, it will make a preview as you can see in the viewport. This is on by default.
  • The output path textbox is editable. You can directly type/edit in the textbox.
  • Token! It supports all tokens in “Name Template”.  You can also use any global variable or global function.
    For example, you can make a  setPrefiewPath global function and set <setPrefiewPath> as path. This script will run the global function and use the result as the output path.
    Ot, If you want to add fps in the name, you can use <FrameRate>.
  • mpt4 support via ffmpeg – you need to download ffmpeg by yourself and set the path in the Settings dialog. Eventually.
  • Ramplayer, ChaosPlayer, Custom player support.
    To use a custom player, you need to make csPlayPreview global function with 4 arguments [output path], [fps],  [start], [end].
  • Set default button –  you can save default settings per user.
  • Play Preview button
  • Open the preview folder button
  • Presets – you can save/load as many as presets you want.

SmartExtrude Toggle

Smart Extrude is awesome. But, I know sometimes you want to be not so smart.
Good news. There is a maxscript property which you can turn on/off “Smart”.

Editable_Poly and Edit_Poly has #enableEnhancedHotkeyExtrude property, and as you expect, it turns Smart Extrude on/off.

For your convenience, I made a simple macroscript. Unzip and drag and drop to a viewport. Since it is a macroscript, you can make button or assign to a hotkey or add to the quad menu and etc.
Download

Because this is a property of Editable Poly and Edit Poly modifier, each Editable Poly/Edit Poly will remember the on.off status.

If you want to turn off all the time, you can use DefaultParamInterface or CustomDefaultParamManager or just run the following code to set off by default.

DefaultParamInterface.SetDefaultParamValue Editable_Poly "enableEnhancedHotkeyExtrude" false persistent:true
DefaultParamInterface.SetDefaultParamValue Edit_Poly "enableEnhancedHotkeyExtrude" false persistent:true

 

 

csArrayMaker

3dsMax 2023.2 has been released with the new feature-packed Array modifier.

This is an array/tile “rigger” based on the new Array modifier. I originally wanted to make a series of tutorials. But, I had to admit that typical Max users are too lazy to follow all the steps. So, I just made this script. I still hope to have some tutorials. But, you can just use this meanwhile.
Download

 

The generated object is “rigged”. If you change the base object size, the array/tile will adapt to it.

  • 4 geometric patterns – Circle, Diamond, Triangle, Hexagon
  • 4 tile types – Herringbone, Chevron, Wood Strip, Basker Weave
  • Option to make Chamferd/Non-Chamfered version
  • Initial Size option
  • Clone UV ID
  • 5 Material presets
    • Bitmap projection
    • Random Color MTL – random color between 2 colors per clone.
    • Random Switcher MTL – randomly chosen colors per clone among 5 given color. You can change the amount of color.
    • Random UV Offset Bitmap MTL – randomly offset UV transform and color for a bitmap.
    • Random Advanced Wood MTL – randomly offset UV 3D transform and Advanced Wood material

3dsMax 2021.1 Custom Default Parameter – and the manager!

3dsMax 2024.1 added a way to set the custom default with right click menu. Therefore, you wouldn’t need to use this script anymore for most cases.

Updated to 1.11! 11/29/2021

3dsMax 2021.1 has been released today. There are many fixes and nice improvement.
One of a new feature is the custom default parameter using Maxscript by DefaultParamInterface. Click here for details. This new feature allows you to have custom default for most areas of 3dsMax as long as it is a class.

The simplest  example would be the height segment of Cylinder. The current default is 5. Id you change it, whatever that value becomes the default for the session. Now you can set your own default  height segment using Maxscript DefaultParamInterface. It is not limited to object and modifiers since it is supported for all classes. You can also use this to set your own renderer default include 3rd party plugins.

The custom defaults will be saved in C:\Users\[username]\Autodesk\3ds Max 2021\User Settings\DefaultParameters.ini. Next time when you update to 3dsMax 2022. You just need to copy that file to the corresponding 3dsMax 2022 folder.

BUT, you would wonder… “why do I have to use Maxscript?”. I think setting the custom default using UI will come in the future. There was some prototype for UI in beta. But, it was removed from release because it doesn’t cover some cases.

So, that’s why I made this Custom Default Param Manager script. This script give you a UI to search a class and parameters and allow you to set default value.

Download 1.11

Download, unzip and drag and drop the script into the viewport. It will be nder csTools > CustomDefaultParamManager. Or simply type X > CustomDefaultParamManager.

This is the UI.

On the left, you can choose a class. On the right, you can choose a parameter name. Then, you will see the spinner of checkbox to input the new default.
Then, just press Set button.
Persistent checkbutton is on by default. To make the default for the next session, you need to check this. So, don’t turn off.
The last 3 buttons are to remove the custom default. You can clear custom default for selected parameter or restores to the factory default. You can also remove everything you set.

Have you heard about renderStacks? The smarter way to render? Let’s click here and check it out!

 

simpleMapBaker

3dsMax 2021 has been release. One of the new feature is the brand new BakingToTexture tool. This tool is written from scratch and the replacement of legacy Render to Texture tool. This is the first iteration of this tool and still in active development.

Along with this tool, now 3dsMax provide the full support of MikkT tangent space from baking to rendering , viewport and SDK.

simpleMapBaker is a simplified front-end of new BakingToTexture. It allow users to bake certain utility map with one click. Also it was used to test the maxscript exposure of BakingToTexture tool.

Download simpleMapBaker

You can bake the following maps.

  • Curvature
  • AO
  • Position
  • World Normal
  • Vertex Normal
  • Material IDs
  • Normal

simpleMapBaker utilize the new override map feature to render most maps at once. Also it uses Arnold’s Curvature and AO shader. Therefore, it will save render preset of the current render.Therefore, it will switch to Arnold for all maps other than Normal map. For normal map, it will switch to Scanline renderer(This is temporary workaround until Arnold normal baking is ready). After baking, the renderer will be reverted to back.

Select objects, and just turn on the map buttons to render and press the big Bake button.

You can set up parameters for some maps and output parameters that BakingToTexture supports.

After bake, it will show all baked maps in the dropdownlist at the bottom. If you select a map there, it will use viewport override for preview baked map.

For normal map, it is using the new MikkT tangent space.

If you want to preview the previously baked maps, select object and press Reload button. It will search the maps and show preview if it finds the map.

Installation
  1. Download simpleMapBaker zip file
  2. Unzip
  3. drag and drop .ms into a viewport
  4. csTools > simpleMapBaker

thanks!

renderStacks can also make your work a lot simpler. Click here and check it out!