[Closed] Using pickObject effectively
I have a rollout with a pickbutton to add the picked object to an array. Unfortunately, it’s a pain in the bum when you want to add a number of objects to that array because pickbuttons will only allow you to select one object at a time.
So I found out about pickObject which does what I want. However, I want it to prevent certain objects from being picked. I can filter an object from it but I can only get it to filter one object and the examples given only filter by object class.
What I want is for it to filter based on an array, to not be able to pick certain objects that already exist in a certain array.
How do I go about doing that?
Here’s the code I have so far:
rollout tester "pickbutton test"
(
fn testfilter o = (o != $example_obj)
checkbutton testpick width:(tester.width-10)
on testpick changed state do
if state == on then
(
pick_array = #()
pick_array = pickobject count:#multiple forceListenerFocus:false filter:testfilter
for i in pick_array do print i.name
testpick.state = off
)
)
createdialog tester
I think you have just to extend your testfilter function to return if this object already exists in the array.
For example:
fn testfilter o = ((findItem oArray o) != 0)
Hey, that works really well but what I want is for it to only make the objects NOT in the array available for picking so I changed the != to a == and it works a treat.
rollout tester "pickbutton test"
(
fn testfilter o = ((findItem testarray o) == 0)
checkbutton testpick width:(tester.width-10)
on testpick changed state do
if state == on then
(
pick_array = #()
pick_array = pickobject count:#multiple forceListenerFocus:false filter:testfilter
for i in pick_array do print i.name
testpick.state = off
)
)
createdialog tester
The only thing that would make it even more sexy is that while the button is checked and you’re in picking mode, once you picked an object you couldn’t pick it again…
How you you do THAT?
:¬)
Well, with pickObject you can pick the same object again and again, having the same object repeated in the array.
…maybe it’s more of a case of filtering out the duplicates in the array once your objects are picked.
Or you could use the pickObject function (in single object mode) in a while loop like this:
(
local pick_array = #()
fn testfilter o = ((findItem pick_array o) == 0)
local pick_obj = pickObject forceListenerFocus:false filter:testfilter
while pick_obj != undefined do
(
append pick_array pick_obj
pick_obj = pickObject forceListenerFocus:false filter:testfilter
)
format "Picked :
%
" pick_array
)
Martijn
That works pretty well Martijn, but unfortunately it doesn’t allow you to pick multiple ojects in a list (ie. by hitting the h hotkey).
I found an example in the maxscript help about how to remove duplicates from an array, bolted it into my own script and it works very nicely indeed.
-- don't forget to define the testarray first!
rollout tester "pickbutton test"
(
fn testfilter o = ((findItem testarray o) == 0)
fn compareArrayParts first second =
(
result = true
if first != second then result = false
else result = true
)
checkbutton testpick width:(tester.width-10)
on testpick changed state do
(
if state == on then
(
pick_array = #()
pick_array = pickobject count:#multiple forceListenerFocus:false filter:testfilter
for i = 1 to pick_array.count do
(
for j = pick_array.count to i+1 by -1 do
(
test = (compareArrayParts pick_array[i] pick_array[j])
if test do
(
deleteItem pick_array j
format "Deleting %
" j
)
)
)
for i in pick_array do print i.name
testpick.state = off
)
else max move
)
)
createdialog tester
Now it doesn’t matter if you pick the object more than once, it’ll remove any duplicates before providing you with the final, cleaned up array.
:¬)
to not enable an object to be picked again, freeze it. to make it appear like it isn’t frozen, in object properties uncheck “Display Frozen in Gray” both scriptable. It’s not perfect, but it’ll do what you want.