[Closed] UtilityPanel.OpenUtility causes 3ds max to hang
When called from a callback function, the UtilityPanel.OpenUtility causes 3ds max to hang.
Is there a reason for this? And does anyone know of a workaround? I need to open a UtilityPanel from a callback function.
Example code that will cause 3ds max to hang:
(
global whendeleted
fn whendeleted =
(
callbacks.removeScripts #selectedNodesPreDelete
format "callback function entered, trying to open the Maxscript by utilitypanel
"
UtilityPanel.OpenUtility MAXScript -- this will cause 3ds max to hang
)
fn foo =
(
-- make sure we remove the callback
callbacks.removeScripts #selectedNodesPreDelete
--register the function as general callback
callbacks.addscript #selectedNodesPreDelete "whendeleted()" persistent:true
mypot1 = teapot() --create a teapot
select mypot1
max delete --trigger the callback function
)
foo() -- test it!
)
and #selectionSetChanged works OK.
PS. When you use callbacks.removeScripts with name of event you have to know that you are deleting all scripts registered with this event. It’s better to use your own id, and delete by id (and name of event if you like)
Thanks for the quick reply Denis!
I’m sorry about the earlier example I did, it seems that my problem is related to the radiosityProcessDone callback and not the utilitypanel.openutility.
Try this code (which hangs 3ds max here):
(
global fnDoSomething
fn fnDoSomething =
(
-- utilitypanel.openutility Assign_Vertex_Colors
callbacks.removeScripts #radiosityProcessDone id:#radiosityDone
try (selection.showVertexColors = on) catch()
try (utilitypanel.openutility Assign_Vertex_Colors) catch() -- Max crashes here?
)
rollout roTestRadiosity "RadiosityCB" width:162 height:78
(
button btnStart "Start" pos:[16,20] width:128 height:32
on btnStart pressed do (
-- turn off the undo buffer and scene redraw (saves memory and increases speed)
with undo off with redraw off (
-- set the render to default_scanline_renderer
renderers.current = Default_Scanline_Renderer()
-- setting the material ID:1 (default) to black material
meditMaterials[1] = standard()
meditMaterials[1].ambient = color 0 0 0
meditMaterials[1].diffuse = color 0 0 0
-- assign black material to all objects in scene
$*.material = meditMaterials[1]
-- create sky light in scene
SkyLight()
-- if no radiosity solution exists
if(sceneRadiosity.radiosity == undefined) then (
-- assign a new radiosity effect to the scene
sceneRadiosity.radiosity = radiosity()
)
-- set radiosity settings
sceneRadiosity.radiosity.Reset true true -- reset radiosity solution without showing a warning dialog
sceneRadiosity.radiosity.radInitialQuality = 95.0
sceneRadiosity.radiosity.includeSkylight = true
-- add callback to continue after the radiosity is finished
callbacks.addScript #radiosityProcessDone "fnDoSomething()" id:#radiosityDone
-- start radiosity
try (sceneRadiosity.radiosity.Start()) catch()
)
)
)
createDialog roTestRadiosity
)
Last code works OK on my machine (MAX 2010 32-b) … I looked in and couldn’t find anything that might cause max crash except perhaps the memory issue. Try to call
(
gc light:on delayed:on
completeRedraw()
)
before openning utility.
By the way, do you know about AssignVertexColors interface? You don’t need Assign_Vertex_Colors utility. This utility is using this interface, and doing nothing more then that.
Thanks again for quick replies Denis. Maybe this is a bug that only happens in 3ds max 2009? I can’t get the utility panel to pop up without 3ds max bugging and hanging (have to terminate application by ctrl+delete). PS. my test scene consist of simple Editable Polys objects (like a couple boxes and spheres).
The AssignVertexColors Interface doesn’t do anything as far as I know. I’ve seen many reports that it’s broken on this forum. And I haven’t gotten it to work myself either… Is it fixed in 3ds max 2010?
Oh, and I will delete the skylight after the radiosity is finished.
AssignVertexColors is working GREAT for me since MAX 9 (?). Probably people don’t know how to use it. Well…
You have to create VertexPaint modifier, set all properties and settings that you need, apply this modifier to your nodes, and call “theAss.ApplyNodes node_list vertexPaint:vpaint”
Sample:
fn bakeVertex nodes:(selection as array) channel:0 /*vertex color */ = if nodes.count > 0 do
(
local theAssign = AssignVertexColors
local bakeModi = VertexPaint name:"Bake Vertex Colors"
for node in nodes do
(
if isproperty node #Bake_Vertex_Colors do deletemodifier node node.Bake_Vertex_Colors
addmodifier node bakeModi
)
bakeModi.lightingModel = 2
bakeModi.colorBy = 1
bakeModi.useMaps = on
bakeModi.mapChannel = channel
theAssign.ApplyNodes nodes vertexPaint:bakeModi
)
That’s the code I’ve used earlier for doing automatic baking of vertex colors, I only added the settings I needed (ie: vpModifier.useRadiosity = true).
I tried your code example and it didn’t work either (no vertex colors showing up). The script adds the Vertex Paint modifiers, but doesn’t assign any vertex colors to the selected objects. I also added the useradiosity settings and enabled show vertex colors in viewport in object properties. Still it didn’t assign the vertex colors based on the radiosity solution. If I do it manually it works fine.
However I think I stumbled upon the solution! If I have the Assign Vertex Colors utility panel open before I run the code – it suddenly works! I just added the following at the top of the script:
try (utilitypanel.openutility Assign_Vertex_Colors) catch() -- This is essential to make the Vertex Colors show up!
If only the utilitypanel.openutility wouldn’t cause max to hang as I run it from a callback function…
I’m going to download 3ds max 2010 trial to see if that will stop 3ds max from bugging up once the utilitypanel.openutility command is executed from a callback function.
Thanks again!
You are right. My code doesn’t work right in any version of MAX (without my plugin). I understood it yesterday night. AssignVertexColors works fine, but VertexPaint modifier doesn’t update mesh with new colors. It’s an old bug of MAX. You can easily reproduce it. Sometimes you have to press “Assign” button of VertexPaint modifier several times to get correct result. For refreshing vertex colors I’m using my own plugin for last 4 years and comlepelly forgot about it…
I’ll try to find a way of forcing vc update from MXS.
fn pressAssignVColor =
(
name = "Assign"
if (win = windows.getChildHWND #max "Assign Vertex Colors") != undefined do
(
if (bt = windows.getChildHWND (UIAccessor.GetParentWindow win[1]) name) != undefined do UIAccessor.PressButton bt[1]
)
)
fn bakeVertex nodes:(selection as array) channel:0 lightingModel:2 predel:on = if nodes.count > 0 do
(
bakeModi = VertexPaint name:"Bake Vertex Colors"
bakeModi.lightingModel = lightingModel
bakeModi.colorBy = 1
bakeModi.useMaps = off
bakeModi.mapChannel = channel
if getCommandPanelTaskMode() == #modify do setCommandPanelTaskMode mode:#modify
completeRedraw()
if predel do for node in nodes where isproperty node #Bake_Vertex_Colors do
(
deletemodifier node node.Bake_Vertex_Colors
)
select nodes
modpanel.addmodtoselection bakeModi ui:on
pressAssignVColor()
)
here is a trick version… It works for me.
Thanks again Denis!
Unfortunately your solution doesn’t work either when called from a callback function, at least not after the radiosity calculation is done. Here’s the callback I added:
callbacks.addScript #radiosityProcessDone "bakeVertex()" id:#radiosityDone
When I run the code bits separately they work just fine, but as soon as bakeVertex() is called after the radiosity process is done – it causes 3ds max to hang. I tested it on 3ds max 2010 and the same happened there.
I would NEVER let MAX kick my a$$!!!
global fnDoSomething
try(destroyDialog roTestRadiosity) catch()
fn pressAssignVColor =
(
name = "Assign"
if (win = windows.getChildHWND #max "Assign Vertex Colors") != undefined do
(
if (bt = windows.getChildHWND (UIAccessor.GetParentWindow win[1]) name) != undefined do
(
UIAccessor.PressButton bt[1]
)
)
)
fn applyVertexAssignment nodes:(selection as array) predel:on channel:0 lightingModel:2 radiosityOption:0 assign:on = if nodes.count > 0 do
(
bakeModi = VertexPaint name:"Bake Vertex Colors"
bakeModi.lightingModel = lightingModel
bakeModi.colorBy = 1
bakeModi.useMaps = off
bakeModi.mapChannel = channel
bakeModi.radiosityOption = radiosityOption
if getCommandPanelTaskMode() == #modify do setCommandPanelTaskMode mode:#modify
completeRedraw()
if predel do for node in nodes where isproperty node #Bake_Vertex_Colors do
(
deletemodifier node node.Bake_Vertex_Colors
)
select nodes
modpanel.addmodtoselection bakeModi ui:on
if assign do pressAssignVColor()
)
fn fnDoSomething =
(
-- utilitypanel.openutility Assign_Vertex_Colors
callbacks.removeScripts id:#radiosityDone
try (selection.showVertexColors = on) catch()
if iskindof (modi = modpanel.getCurrentObject()) VertexPaint do
(
modi.radiosityOption = 1
pressAssignVColor()
)
-- try (utilitypanel.openutility Assign_Vertex_Colors) catch() -- Don't call it here! MAX really crashes!
)
rollout roTestRadiosity "RadiosityCB" width:162 height:78
(
button btnStart "Start" pos:[16,20] width:128 height:32
on btnStart pressed do (
-- turn off the undo buffer and scene redraw (saves memory and increases speed)
with undo off with redraw off (
-- set the render to default_scanline_renderer
renderers.current = Default_Scanline_Renderer()
-- setting the material ID:1 (default) to black material
meditMaterials[1] = standard()
meditMaterials[1].ambient = color 0 0 0
meditMaterials[1].diffuse = color 0 0 0
-- assign black material to all objects in scene
$*.material = meditMaterials[1]
-- create sky light in scene
if (getClassInstances SkyLight).count == 0 do SkyLight()
-- if no radiosity solution exists
if(sceneRadiosity.radiosity == undefined) then (
-- assign a new radiosity effect to the scene
sceneRadiosity.radiosity = radiosity()
)
-- set radiosity settings
sceneRadiosity.radiosity.Reset true true -- reset radiosity solution without showing a warning dialog
sceneRadiosity.radiosity.radInitialQuality = 95.0
sceneRadiosity.radiosity.includeSkylight = true
-- add callback to continue after the radiosity is finished
callbacks.removeScripts id:#radiosityDone -- it's not necessary but it's cleaner to kill old callback before adding new one
callbacks.addScript #radiosityProcessDone "fnDoSomething()" id:#radiosityDone
-- start radiosity
-- try (utilitypanel.openutility Assign_Vertex_Colors) catch() -- call it here if you want to use Assign_Vertex_Colors utility
applyVertexAssignment lightingModel:0 assign:off
try (sceneRadiosity.radiosity.Start()) catch()
)
)
)
createDialog roTestRadiosity
It has to work!