[Closed] Maxscript ProBoolean Bug Workaround
Hey everyone
As mentioned in an old thread by denisT there is a Bug with ProBooleans in 3ds max.
He posted a nice workaround which works quite well. http://forums.cgsociety.org/showthread.php?t=806145
For my script, I also need to toggle the cookie option on and off depending on the task I´m performing which seems to have the same bug.
I can´t figure out how to use denisT method to set it.
Would be nice if someone can help me out.
Thanks,
Gerald
Thanks for your reply.
ProBoolean.SetCookieCut doesn´t seem to work using Max 2016.
Here´s the code with some cubes for testing:
fn getBooleanHWND =
(
hwnd = undefined
for c in (windows.getChildrenHWND #max) while hwnd == undefined where c[4] == "RollupPanelTitle" and c[5] == "Pick Boolean" do (
hwnd = UIAccessor.GetParentWindow c[1]
)
hwnd
)
fn setAddMethod method hwnd: update:on =
(
if hwnd == unsupplied do hwnd = getBooleanHWND()
if hwnd != undefined do
(
name = case method of
(
0: "Reference"
1: "Copy"
2: "Move"
3: "Instance"
default: "Copy"
)
if (bt = windows.getChildHWND hwnd name) != undefined do UIAccessor.PressButton bt[1]
if update do select selection
ok
)
)
fn doBooleanOp NodeA NodeB operation method isCookie = (
ProBoolean.setoperandA NodeA
select NodeA
if getCommandPanelTaskMode() != #modify do setCommandPanelTaskMode mode:#modify
if setAddMethod method == ok do
(
ProBoolean.SetBoolOp NodeA operation
ProBoolean.SetCookieCut NodeA isCookie
ProBoolean.setoperandB NodeA NodeB method 0
)
return NodeA
)
BoolA= Box position:[0,0,0]
BoolB= Box position:[0,-10,0] width:10 height:15 length:15
BoolC= Box position:[40,0,0]
BoolD= Box position:[40,-10,0] width:10 height:15 length:15
BoolE= Box position:[80,0,0]
BoolF= Box position:[80,-10,0] width:10 height:15 length:15
doBooleanOp BoolA BoolB 2 2 false
doBooleanOp BoolC BoolD 2 2 true
doBooleanOp BoolE BoolF 2 2 false
use Boolean2 interface instead of PolyBoolean.
delete objects
BoolA = Box position:[0,0,0]
BoolB = Box position:[0,-10,0] width:10 height:15 length:15
BoolC = Box position:[40,0,0]
BoolD = Box position:[40,-10,0] width:10 height:15 length:15
(
obj = boolObj.createBooleanObject BoolA BoolB 3 1
boolObj.setBoolOp obj 3
delete BoolB
-- converttopoly obj
)
(
obj = boolObj.createBooleanObject BoolC BoolD 3 1
boolObj.setBoolOp obj 5
boolObj.setBoolCutType obj 3
delete BoolD
-- converttopoly obj
)
Thanks for the reply and code, really appreciate the help.
Any chance to get this to work with ProBooleans?
Boolean2 is great for this simple example, but for the task, I want to perform ProBooleans give way better ( cleaner) results.
Not sure if its possible, but can´t we access the cookie checkbox with the hwnd workaround, like you did with the boolean method?
fn setProBooleanCookieCheck boolNode state =
(
BM_SETCHECKED = 0x00F1
BM_UNCHECKED = 0x0000
BM_CHECKED = 0x0001
if modpanel.getcurrentobject() != bool do
(
max modify mode
modpanel.setcurrentobject boolNode
)
obj = modpanel.getcurrentobject()
if iskindof obj ProBoolean and obj == boolNode do
(
hwnd = windows.getchildhwnd #max "Cookie"
if hwnd != undefined do
(
windows.SendMessage hwnd[1] BM_SETCHECKED (if state then BM_CHECKED else BM_UNCHECKED) 0
return state
)
)
undefined
)
proboolean.SetOperandA BoolA
setProBooleanCookieCheck BoolA off
Unfortunately, it still doesn´t work. It seems the windows.SendMessage part doesn´t do anything.
Here´s the updated code:
fn getBooleanHWND =
(
hwnd = undefined
for c in (windows.getChildrenHWND #max) while hwnd == undefined where c[4] == "RollupPanelTitle" and c[5] == "Pick Boolean" do (
hwnd = UIAccessor.GetParentWindow c[1]
)
hwnd
)
fn setAddMethod method hwnd: update:on =
(
if hwnd == unsupplied do hwnd = getBooleanHWND()
if hwnd != undefined do
(
name = case method of
(
0: "Reference"
1: "Copy"
2: "Move"
3: "Instance"
default: "Copy"
)
if (bt = windows.getChildHWND hwnd name) != undefined do UIAccessor.PressButton bt[1]
if update do select selection
ok
)
)
fn setProBooleanCookieCheck boolNode state = (
BM_SETCHECKED = 0x00F1
BM_UNCHECKED = 0x0000
BM_CHECKED = 0x0001
if modpanel.getcurrentobject() != boolNode do
(
max modify mode
modpanel.setcurrentobject boolNode
)
obj = modpanel.getcurrentobject()
if iskindof obj ProBoolean and obj == boolNode do
(
hwnd = windows.getchildhwnd #max "Cookie"
if hwnd != undefined do
(
windows.SendMessage hwnd[1] BM_SETCHECKED (if state then BM_CHECKED else BM_UNCHECKED) 0
return state
)
)
undefined
)
fn doBooleanOp NodeA NodeB operation method isCookie = (
ProBoolean.setoperandA NodeA
select NodeA
if getCommandPanelTaskMode() != #modify do setCommandPanelTaskMode mode:#modify
if setAddMethod method == ok do
(
ProBoolean.SetBoolOp NodeA operation
setProBooleanCookieCheck NodeA isCookie
ProBoolean.setoperandB NodeA NodeB method 0
)
return NodeA
)
BoolA= Box position:[0,0,0]
BoolB= Box position:[0,-10,0] width:10 height:15 length:15
BoolC= Box position:[40,0,0]
BoolD= Box position:[40,-10,0] width:10 height:15 length:15
BoolE= Box position:[80,0,0]
BoolF= Box position:[80,-10,0] width:10 height:15 length:15
doBooleanOp BoolA BoolB 2 2 false
doBooleanOp BoolC BoolD 2 2 true
doBooleanOp BoolE BoolF 2 2 false
i knew that…
the setting of the checkbox doesn’t automatically update internal proboolean structures.
we can set in stimulating ‘mouse click’… in this case it will update, but… there are another issues which you will meet later.
fn confirmProBooleanCookieCheck boolNode state =
(
BM_GETCHECKED = 0x00F0
BM_SETCHECKED = 0x00F1
BM_UNCHECKED = 0x0000
BM_CHECKED = 0x0001
WM_LBUTTONDOWN = 0x201
WM_LBUTTONUP = 0x202
if modpanel.getcurrentobject() != bool do
(
max modify mode
modpanel.setcurrentobject boolNode
)
obj = modpanel.getcurrentobject()
if iskindof obj ProBoolean and obj == boolNode do
(
hwnd = windows.getchildhwnd #max "Cookie"
if hwnd != undefined do
(
hwnd = hwnd[1]
check = (windows.sendmessage hwnd BM_GETCHECKED 0 0) == 1
if proboolean.GetCookieCut boolNode == state then
(
if check != state do windows.postMessage hwnd BM_SETCHECKED (if state then BM_CHECKED else BM_UNCHECKED) 0
)
else
(
windows.sendmessage hwnd WM_LBUTTONDOWN 0 0
windows.sendmessage hwnd WM_LBUTTONUP 0 0
check = (windows.sendmessage hwnd BM_GETCHECKED 0 0) == 1
)
return #(state, check, proboolean.GetCookieCut boolNode)
)
)
undefined
)
proboolean.SetOperandA BoolA
confirmProBooleanCookieCheck BoolA on
proboolean.SetBoolOp BoolA 2
Thanks, denis.
Seems like it´s more complicated than I initially thought.
I will try this code and if I run into any issues I will revert back to Boolean2.