randomly select edge or edges on Object

randomly select edge or edges on Object

admin
Participant Participant
1,245 Views
10 Replies
Message 1 of 11

randomly select edge or edges on Object

admin
Participant
Participant

i want to select on or more edges on a selected object

if i use

 

$.EditablePoly.SetSelection random 1

 

it runs  my script but errors out with unable to convert random() into Integer

Can someone post me a help o to this up
fn edgSlct obj=


(

   i select my object
   i turn on subobejctlevel 2
   here i want to pick  a random edge on my selection


)

0 Likes
Accepted solutions (1)
1,246 Views
10 Replies
Replies (10)
Message 2 of 11

miauuuu
Collaborator
Collaborator
Accepted solution
(
	fn EdgSlct obj =
	(
		if classOf obj == Editable_Poly do
		(
			select obj
			max modify mode
			subobjectlevel = 2
			polyop.setEdgeSelection obj (random 1 (polyop.getNumEdges obj))
		)
	)	
	EdgSlct selection[1] 
)
https://miauu-maxscript.com/
Message 3 of 11

admin
Participant
Participant
i figured i need to get the selection somehow and found the get stuff in the documentation but never got it to work. Thank you a lot bro
0 Likes
Message 4 of 11

admin
Participant
Participant

if i evaluate the script it works and selects a random edge but if i want to use a button to change the selection randomly it sends an error.

1) what did i miss here???
2) where is the amount of selcted edges done? When i set random to 3 it selects still one edge....??

What does EdgSlct selection[1] exactly???

See Screenshot

0 Likes
Message 5 of 11

miauuuu
Collaborator
Collaborator
(
	global rol_testingStuff
	try(destroyDialog rol_testingStuff)catch()
	rollout rol_testingStuff "WHOPPER"
	(
		spinner spn_edgesToSel "Edges to select:" range:[1,1000,3] width:80 type:#integer
		button btn_test "WHOPPER"
		
		fn EdgSlct obj =
		(
			if classOf obj == Editable_Poly do
			(
				select obj
				max modify mode
				subobjectlevel = 2
				
				spnVal = spn_edgesToSel.value
				edgCnt = polyop.getNumEdges obj
				case of
				(
					(spnVal > edgCnt): messagebox "Selected object has less edges than the value in the spinner"
					(spnVal == edgCnt): (polyop.setEdgeSelection obj #{1..edgCnt})
					default:
					(
						edgToSelBA = #{}
						while edgToSelBA.numberset < spnVal do
						(
							edgToSelBA  += #{(random 1 edgCnt)}
						)				
						polyop.setEdgeSelection obj edgToSelBA
					)
				)
			)
		)	
		
		on btn_test pressed do
		(
			if selection.count == 1 do
				EdgSlct selection[1] 
		)
	)
	createdialog rol_testingStuff width:200
)
https://miauu-maxscript.com/
0 Likes
Message 6 of 11

denisT.MaxDoctor
Advisor
Advisor

@miauuuu wrote:

 

						while edgToSelBA.numberset < spnVal do
						(
							edgToSelBA  += #{(random 1 edgCnt)}
						)				

 


You didn't read my posts carefully..... 😉

Use #shuffle!

0 Likes
Message 7 of 11

denisT.MaxDoctor
Advisor
Advisor

with #while you might go into an infinite loop.  not quite infinite, but it can be very, very long. 🙂


0 Likes
Message 8 of 11

miauuuu
Collaborator
Collaborator

Yes, I know. 🙂

If the user decide to select 900 of 1000 edges it is better to generate 100 random numbers and then to use the rest of the numbers instead of waiting 3dsMax to generate 900 random numbers.

 

This shuffles the array, but on my Max2020, despite the edgToSelArr is filled with correct amount of numbers, 3dsMax selects equal or less amount of edges. 🙂

 

(
	global rol_testingStuff
	try(destroyDialog rol_testingStuff)catch()
	rollout rol_testingStuff "WHOPPER"
	(
		spinner spn_edgesToSel "Edges to select:" range:[1,1000,3] width:80 type:#integer
		button btn_test "WHOPPER"
		
		fn ShuffleArr arr =
		(
			for i = arr.count to 1 by -1 collect
			(
				swapIndex = random 1 i
				swap arr[random 1 i] arr[i]
			)
		)
		
		fn EdgSlct obj =
		(
			if classOf obj == Editable_Poly do
			(
				select obj
				max modify mode
				subobjectlevel = 2
				
				spnVal = spn_edgesToSel.value
				edgCnt = polyop.getNumEdges obj
				case of
				(
					(spnVal > edgCnt): messagebox "Selected object has less edges than the value in the spinner"
					(spnVal == edgCnt): (polyop.setEdgeSelection obj #{1..edgCnt})
					default:
					(
						randomizedArr = ShuffleArr (#{1..edgCnt} as array)
						edgToSelArr = for i = 1 to spnVal collect randomizedArr[i]
						polyop.setEdgeSelection obj edgToSelArr
					)
				)
			)
		)	
		
		on btn_test pressed do
		(
			if selection.count == 1 do
				EdgSlct selection[1] 
		)
	)
	createdialog rol_testingStuff width:200
)
https://miauu-maxscript.com/
0 Likes
Message 9 of 11

denisT.MaxDoctor
Advisor
Advisor

your shuffle function seems not correct... here is what I do:

fn shuffleArray list = 
(
	for k = 1 to list.count do 
	(
		i = random 1 k
		swap list[k] list[i]
	)
	list
)

fn selectPolyRandomVerts node numv seedvalue: = 
(
	if seedvalue != unsupplied do seed seedvalue
	
	list = shuffleArray ((node.verts as bitarray) as array)
	list.count = amin numv list.count
	node.selectedverts = list
)

delete objects
gc()

t = converttopoly (teapot segments:100 isselected:on) 
selectPolyRandomVerts t 100000)

 

Message 10 of 11

denisT.MaxDoctor
Advisor
Advisor

But of course, there is no need to shuffle all verts if you need a part. This will be a homework on how to modify the shuffle method to shuffle only the needed number 😉

0 Likes
Message 11 of 11

denisT.MaxDoctor
Advisor
Advisor

but these are outdated methods... now you can use Python 😊

0 Likes