Notifications
Clear all

[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
7 Replies
1 Reply
(@ypuech)
Joined: 11 months ago

Posts: 0

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?
:¬)

1 Reply
(@ypuech)
Joined: 11 months ago

Posts: 0

I’ve no idea how to implement this behaviour. Why do you want to 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.

1 Reply
(@magicm)
Joined: 11 months ago

Posts: 0

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.