Notifications
Clear all

[Closed] transform vertex in PolyOb ?

Hi, so I tried doing some searches about this, and right when I thought I was making some headway I kept getting “can’t allocate memory” errors while my search was processing. So I thought I’d just check to see if someone could help me out.

 I've been practicing with maxscripts lately, and I'm trying to write a basic tool that'd allow me to select more than one vertex in an Editable Poly and then transform their position based on a users input. My only problem is I can't figure out how to retrieve the vertex data.  Any help, as usual, will be appreciated, thanks.
9 Replies

Hi,

For the memory prob, either restart Max,
or in preferences/maxscript increase memory (maxscript heap)

for the script, lookup PolyOp in the maxscript reference
here is a basic example:

(
obj=selection[1] – the Editable_poly object you work on
offset=[10,0,0] – the amount to move the verts (10 units in x)
Numverts = Polyop.getnumverts obj – number of vertices
Selected_verts = (polyOp.getVertSelection obj) as array – array of selected vertices
polyOp.moveVert obj Selected_verts offset – move the selected vertices by offset
)

mkay, I’ll give that a try tomorrow. And on the memory thing, it was actually in reference to cgtalk. I was searching the forums (as I do before posting a question) and then I kept getting that error.

Alllll-right, so I finally got it working.

   'obj=selection[1]', which was 'obj = $[1]' in my case turned out giving me an error about 'SubAnim visibility', I won't even try to understand that one right now.
   
   So I moved on to getNumVerts & getVertSelection. getVertSelection ended up being what I needed, so from there this is what I came up with..
on moveVertBtn pressed do (
 	 currSelection = $
 
 	 if currSelection != undefined then (
 		  seldVerts = (polyOp.getVertSelection currSelection) as array
 
 		  if chkBox04.state == true then ( allowVertMove = true )
 		  if chkBox05.state == true then ( allowVertMove = true )
 		  if chkBox06.state == true then ( allowVertMove = true )
 			
 		  if allowVertMove == true then (
 			   undo "moveVerts" on (
 					for i in seldVerts do (
 						 currVertPos = polyOp.getVert currSelection i
 						 
 						 if chkBox04.state == true then ( selX = spin04.value )
 						 else ( selX = currVertPos.x )
 						 if chkBox05.state == true then ( selY = spin05.value )
 						 else ( selY = currVertPos.y )
 						 if chkBox06.state == true then ( selZ = spin06.value )
 						 else ( selZ = currVertPos.z )
 
 						 polyOp.setVert currSelection i [selX, selY, selZ]
 					)
 			   )
 		  )
 	 )
 )

This is rather easy to explain.

$ can mean 3 things.

$ is undefined when nothing is selected.
$ is a scene node when ONE object is selected.
$ is a collection of multiple scene nodes when multiple objects are selected.

In other words, $[1] is NOT the same as selection[1], because selection is always a collection of nodes even when a single node is selected and an index would be valid, but it wouldn’t be valid with $ in the same case.

Using selection[1] gives you either the first node from the selection or undefined if nothing is selected, while $[1] will give you the first node only if multiple nodes are selected, but THE FIRST SUBANIM in the selected node if only one node is selected.
And the first sub-anim in any node is the visibility track, so you get
SubAnim:Visibility as result of $[1] for one selected node.

In short,
DON’T USE $ UNLESS YOU HAVE CHECKED WHAT IT CONTAINS!

For example, using

   if selection.count == 1 do theSel = polyOp.getVertSelection $

is valid because $ is guaranteed to be ONE OBJECT thanks to the IF.
Without the IF, all sorts of errors could occur, so you should try not to use $ at all.
(It was intended as a shortcut for quickly typing console code in the Listener, not for programming. Really, forget it even existed!)

ah ok, good to know about the ‘$’ thing. I always had something selected when testing out my script though, there’s no point in trying to test a selection script if you’ve got nothing selected, now is there.

So now that I’ve got things working with my script, I’m trying to convert it from a .ms to a .mcr so I can make it into a button and actually use it without having to manually load the script when I want to use it.
I’ve got most of it working except if I re-click on the button after the rollout window is open, then another window appears over my old one, but it’s empty. If I just close my rollout window with the ‘X’ then there’s no problem, I can click on the button to re-open the script again. So now I’m on the search of how to control the rollout window properties by clicking on my UI button. I’m thinking ‘closerolloutfloater’ has something to do with it, but can’t get it to work. Oh, and I want to figure out how to get my button to be ‘pressed’ when on, and ‘not pressed’ when off. weeeeeeeeeee … :shrug:

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Are you sure you did not miss the point?
I did not say not to use selections or not to select anything, I just said not to use $ to get the selection, but one of the other methods, because $ is morphing between a node and a collection and you cannot be sure which one it is. Use ‘selection’ instead, it is safer.

So now that I’ve got things working with my script, I’m trying to convert it from a .ms to a .mcr so I can make it into a button and actually use it without having to manually load the script when I want to use it.
I’ve got most of it working except if I re-click on the button after the rollout window is open, then another window appears over my old one, but it’s empty. If I just close my rollout window with the ‘X’ then there’s no problem, I can click on the button to re-open the script again. So now I’m on the search of how to control the rollout window properties by clicking on my UI button. I’m thinking ‘closerolloutfloater’ has something to do with it, but can’t get it to work. Oh, and I want to figure out how to get my button to be ‘pressed’ when on, and ‘not pressed’ when off. weeeeeeeeeee … :shrug:

Define your rollout or rolloutFloater as global variable.
Try to destroy it before defining and creation another one.
The define the rollout / floater and create the dialog.

For example, for a dialog:

macroScript someMacro category:"Forum Help"
(
global someDialogName
try(destroyDialog someDialogName)catch()
rollout someDialogName "Some Dialog"
(
--your controls go here
)
createDialog someDialogName
)--end script

Yeah I misinterpreted, while writing a response I think I got a grasp on what you were saying, and deleted what I was going to ask.

So I’m using a ‘newrolloutFloater’ not a dialog, and used ‘closeRolloutFloater’ instead of ‘destroyDialog’. And that worked perfectly, but I realize that’s not what I needed. It looks like I need something like…

global myRF
 global winOpen = false
 
 if winOpen == true then (
 	 winOpen = false
 	 on isChecked do winOpen
 	 closeRolloutFloater myRF
 )
 else (
 	 winOpen = true
 	 on is Checked do winOpen
 	 newrolloutFloater myRF
 )

But I tried that, and no go. I did some checks to see if my my winOpen var was changing and it wasn’t, it was staying false, so I guess I’ll tool around with that some more. Bobo (or anyone else), if you have anymore advice I’m listenin’.

Here is how to do it:

macroScript CheckIt category:"Forum Help"
(
	local checked = false
	global theRolloutFloater
	on isChecked return checked
	on Execute do
	(
		if checked then
		(
			checked = false
			try(closeRolloutFloater theRolloutFloater)catch()
		)
		else
		(
			rollout theRollout "Some Rollout"
			(
				label someLabel "Hello World!"
				on theRollout close do
				(
					checked = false
					updateToolbarButtons()
				)		
			)
			try(closeRolloutFloater theRolloutFloater)catch()
			theRolloutFloater = newRolloutFloater "Floater" 200 60
			addRollout theRollout theRolloutFloater
			checked = true
		)
	)
)

Ah suh-weeet, yup that did the trick. I ended up figuring out the ‘on execute do’ part, but the ‘isChecked’ and ‘closeRolloutFloater’ functions were giving me some problems. Turned out I had typed “cloaseRolloutFloater”, so that was an easy fix, and I just had ‘isChecked’ in the wrong areas.

So I think I’m finally done with this, it was a fun little project, when I get more time or feel the need to make another tool I’ll probably be back in this forum, heh. Here’s a quick rundown of what I made and why.

Set all CoOrds to 0:
When ever I start a model I always “zero out” my box or whatever I’m using, so that I can delete half of it, and when checking seams I can just set my mid vertex’s to 0. I’m sure a lot of people do the same, but I got tired of typeing in zero in the x,y, & z, now I just push the button.
Set Individual CoOrds:
This allows the user to move their objects to where ever. You do it to just one object or select multiple objects to move.
Set Verts to CoOrd:
Well I’ve noticed in the past that if you’ve got some stray verts you can’t just select all of them and type in new pos coordinates. For example I’ve got one vert at x:5 and another at x:3.45, but I want them both at 0. If you enter 0, it tends to just offset the verts. Now I don’t have to worry about that, yay!
And here’s a gif to show it in action. And thanks again Bobo for your help.