custom helpers


#1

Hi

How can i create custom helpers. I’m interested in creating 3d geometry like lines or boxes that aren’t actualy objects. Like the container object. It’s a nice box, but it doesn’t really consist of polygons, right?

David


#2

Create it as an extended spline object or hack around an extended dummy object. I would have a look at Paul Neale’s Control Objects and/or PEN Helper scripts to see how he is doing it.

-Eric


#3

Alternatively, look at using simple manipulator plugins (which are also Helpers) and provide the ability to create geometry (even colorful and shaded!), splines, text and some drawing primitives like circles, rectangles, diamonds etc. as seen around slider manipulators. Manipulators do not have to manipulate anything, and their scripted form is much better than extended helpers.

See my 2008 Master Class in the Subscription Center if you have access to it.


#4

I mentioned this in another thread, but I didn’t see the project files and notes you mentioned in the videos available for download. Do you know if they’re supposed to be and I’m just not seeing them?


#5

I don’t think I have my password at home so I cannot check right now, but I remember seeing the link on the Bio page.


#6

Been ages since I looked at these, do you need to be in manipulator mode to use them? This is one problem that I had with them way back when they were added.


#7

Nope, you have to be in manipulate mode if you want to manipulate them, but as I said you can set the “can manipulate” handler to always return false and not implement any manipulation at all. So the manipulator helper appears as a regular helper and you can use it as such without even knowing it was implemented using the simpleManipulator class.

But it lets you use various colors within its gizmos, use meshes in its gizmos (which appear shaded in shaded mode), add text to its gizmos, use other graphics primitives, basically everything extended helpers don’t let you do. And since the Container icons also use text to denote the state of the object, the manipulator helpers are much more useful to recreate the same look.


#8

How do you do that? If I set canManipulate to return always false, and Manipulate Mode is disabled, gismos don’t show up at all and updateGizmos event is never broadcasted. What am I missing? This is significant in my current work. Thank you.

  • Enrico

#9

Another question Bobo, are they as slow in the viewport as helpers are? Helpers are terrible and the reason that I have gone to geometry objects for all my controls. If they are fast I might make a switch to them.


#10

There are two different level of manipulator plugins - the ones like the Radius manipulator do not implement a ClassID and are not a creatable scene object. When they return false, they don’t draw.
But the Level 3 and higher manipulator plugins that provide a ClassID and create a scene node (and save with the scene) always draw. The canManipulate handler defines whether the Manipulate mode will let you change the settings of the object, not whether the object will be drawn on screen.

Paul, you will have to benchmark yourself, I would expect them to be as slow as regular helpers, but I haven’t experienced big problems with helpers anyway since I never create hundreds of them, thus I cannot tell. I know you do for rigging so this might not be a good solution for you.

Here is the simple UCS Helper I showed in the Master Class (the download of all scripts and the PDF is really on the main page of the Master Class in the Subscription center, just beneath my bio, so you can download them all and check them out).

-------------------------------------------------------------
  -- Autodesk Master Class 2008
  -- UCSManipulator Helper
  -- Code by Borislav "Bobo" Petrov
  -- This script may be distributed and modified freely
  -------------------------------------------------------------
  
  plugin simpleManipulator UCSManipulator
  	name:"UCS"
  	classID:#(0x58cfb958, 0x2fea5145)
  	category:"Manipulators"
  (
  	local greenColor =  green/255.0
  	local redColor =	red/255.0
  	local yellowColor = yellow/255.0
  	local blueColor = blue/255.0
  
  	parameters main rollout:paramRollout
  	( 
  		 size type:#float   animatable:false  ui:spn_size default: 1
  		 showLabels type:#boolean animatable:false ui:chk_showLabels default:true
  		 showXZ type:#boolean animatable:false ui:chk_showXZ default:false
  		 showYZ type:#boolean animatable:false ui:chk_showYZ default:false
  	)
  
  	rollout paramRollout "Parameters"
  	(
  		Spinner  spn_size "Icon Size:"  range:[0.01, 10000.0, 1.0]
  		checkbox chk_showLabels "Show Axis Labels" 
  		checkbox chk_showXZ "Show Z Axis In XZ Plane" 
  		checkbox chk_showYZ "Show Z Axis In YZ Plane" 
  	)
  
  	on canManipulate target return false
  
  	tool create
  	(
  		on mousePoint click do
  		   case click of
  		   (
  			  1: 
  			  (
  				  theTM = matrix3 1
  				theTM.row4 = gridPoint
  				nodeTM = theTM
  			  )
  			  2: #stop
  		   )
  		on mouseMove click do
  		(
  			case click of
  			(
  				2: (
  					size = length gridDist
  					)
  			)
  		)  
  	)
  
  	on updateGizmos do
  	(
  		this.clearGizmos()
  		
  		local flags = 0 
  		this.addGizmoMarker #asterisk [0,0,0] flags yellowColor redColor
  
  		local giz = manip.makeGizmoShape() 
  		giz.AddPoint ([-1.5,-1.5,0] * size)
  		giz.AddPoint ([5.5,-1.5,0]  * size)
  		giz.AddPoint ([5.5,-3,0] * size) 
  		giz.AddPoint ([8.5,0,0]  * size)
  		giz.AddPoint ([5.5,3,0]  * size)
  		giz.AddPoint ([5.5,1.5,0]  * size)
  		giz.AddPoint ([1.5,1.5,0]  * size)
  		this.addGizmoShape giz flags redColor redColor 
  		
  		if showLabels do
  		(
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([5.5,1,0] * size)
  			giz.AddPoint ([7,-1,0]  * size)
  			this.addGizmoShape giz flags redColor redColor 
  			
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([7,1,0] * size)
  			giz.AddPoint ([5.5,-1,0]  * size)
  			this.addGizmoShape giz flags redColor redColor 
  		)
  		
  		local giz = manip.makeGizmoShape() 
  		giz.AddPoint ([1.5,1.5,0]  * size)
  		giz.AddPoint ([1.5,5.5,0]  * size)
  		giz.AddPoint ([3,5.5,0]  * size)
  		giz.AddPoint ([0,8.5,0]  * size)
  		giz.AddPoint ([-3,5.5,0]  * size)
  		giz.AddPoint ([-1.5,5.5,0]  * size)
  		giz.AddPoint ([-1.5,-1.5,0]  * size)
  		this.addGizmoShape giz flags greenColor greenColor 
  		
  		if showLabels do
  		(
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([-0.7,7,0] * size)
  			giz.AddPoint ([0,6,0]  * size)
  			this.addGizmoShape giz flags greenColor greenColor 
  			
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([0.7,7,0] * size)
  			giz.AddPoint ([0,6,0]  * size)
  			this.addGizmoShape giz flags greenColor greenColor 
  			
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([0,6,0]  * size)
  			giz.AddPoint ([0,5,0]  * size)
  			this.addGizmoShape giz flags greenColor greenColor 			
  		)		
  		
  		if showXZ do
  		(
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([-1.5,0,0] * size)
  			giz.AddPoint ([-1.5,0,5.5] * size)
  			giz.AddPoint ([-3,0,5.5] * size)
  			giz.AddPoint ([0,0,8.5] * size)
  			giz.AddPoint ([3,0,5.5] * size)
  			giz.AddPoint ([1.5,0,5.5] * size)
  			giz.AddPoint ([1.5,0,0] * size)
  			giz.AddPoint ([-1.5,0,0] * size)			
  			this.addGizmoShape giz flags blueColor blueColor 	
  
  			if showLabels do
  			(
  				local giz = manip.makeGizmoShape() 
  				giz.AddPoint ([-0.7,0,7] * size)
  				giz.AddPoint ([0.7,0,7]  * size)
  				giz.AddPoint ([-0.7,0,5]  * size)
  				giz.AddPoint ([0.7,0,5]  * size)
  				this.addGizmoShape giz flags blueColor blueColor 
  			)	
  		)
  		if showYZ do
  		(
  			local giz = manip.makeGizmoShape() 
  			giz.AddPoint ([0,-1.5,0] * size)
  			giz.AddPoint ([0,-1.5,5.5] * size)
  			giz.AddPoint ([0,-3,5.5] * size)
  			giz.AddPoint ([0,0,8.5] * size)
  			giz.AddPoint ([0,3,5.5] * size)
  			giz.AddPoint ([0,1.5,5.5] * size)
  			giz.AddPoint ([0,1.5,0] * size)
  			giz.AddPoint ([0,-1.5,0] * size)			
  			this.addGizmoShape giz flags blueColor blueColor 		
  			
  			if showLabels do
  			(
  				local giz = manip.makeGizmoShape() 
  				giz.AddPoint ([0,-0.7,7] * size)
  				giz.AddPoint ([0,0.7,7]  * size)
  				giz.AddPoint ([0,-0.7,5]  * size)
  				giz.AddPoint ([0,0.7,5]  * size)
  				this.addGizmoShape giz flags blueColor blueColor 
  			)				
  		)
  		return "UCS"
  	)
  )

Note that this is a level 5 scripted plugin because it provides both a ClassID, a paramblock and a UI connected to it.


#11

Thank you Bobo, your knowledge is really deep. You’re right, I’m working with a simpleManipulator without defining a classID, because I coded a structure to do the gw drawing in a neater way, and didn’t want to add anything to the scene. I didn’t realize helper manipulators would work without needing to be in manipulate mode. Some expedients like callbacks on save could delete the helper from scene and recreate it afterward, just to leave the file clean… I need to take a deeper look at it. Thank you very much.

  • Enrico

#12

wow. thanks a lot guys, and especially Bobo. I think the ucs-script is a very useful template. It is spot-on what i was looking for.

But how do i know which classId to assign?


#13

Hi David, the ClassID must be a unique identifier of your plugin. From MaxScript Reference:

The classID is used by 3ds Max to recognize the plug-in class when loading the scene. To generate a new unique ID, you can use the GenclassID() method in the Listener and copy the result into the script.

Take a look at “Scripted Plug-ins” in the Reference for more information.

  • Enrico

#14

Quick question. Based on your example of the helper/manipulator, how do you go about making a manipulator with curvy shaped splines for instance? Can you place beziers on the add points in the code?

Thanks
JokerMartini


#15

Have you read “Flatland”?
Even the smoothest curve can be seen as just an N-gon with a very high N :slight_smile:

So if you need curves, you can either create enough points to get a curve, or use the curve primitives (like Circle) available in Manipulators.

For example, adding the lines

		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		this.addGizmoShape giz flags redColor redColor 

to the code above will draw a circle around the pivot point.

If you want to draw your own free-form curve, you will have to write some code to figure out the points you need. For example, the following adds a sine curve along the X axis starting at the origin:


		  local giz = manip.makeGizmoShape() 
		for i = 0.0 to 5.0 by 0.01 do
		(
			giz.AddPoint ([i,sin(i*360),0]*size )
		)
		this.addGizmoShape giz flags redColor redColor 

#16

Now is there a way to link up a colorpicker to the helper so it allows users to change the color of the manipulator?


#17

Of course.

It is just a scripted plugin.
Add a parameter to the paramblock, connect to a rollout, use the parameter in the drawing code, done!

Here is an updated example:


plugin simpleManipulator UCSManipulator
	  name:"UCS"
	  classID:#(0x58cfb958, 0x2fea5145)
	  category:"Manipulators"
  (

  
	  parameters main rollout:paramRollout
	  ( 
		  size type:#float   animatable:false  ui:spn_size default: 1
		  showLabels type:#boolean animatable:false ui:chk_showLabels default:true
		  showXZ type:#boolean animatable:false ui:chk_showXZ default:false
		  showYZ type:#boolean animatable:false ui:chk_showYZ default:false
		xColor type:#color animatable:true ui:clr_xColor default:red
		yColor type:#color animatable:true ui:clr_yColor default:green
		zColor type:#color animatable:true ui:clr_zColor default:blue
		labelColor type:#color animatable:true ui:clr_labelColor default:yellow
	  )
  
	  rollout paramRollout "Parameters"
	  (
		  Spinner  spn_size "Icon Size:"  range:[0.01, 10000.0, 1.0]
		  checkbox chk_showLabels "Show Axis Labels" 
		  checkbox chk_showXZ "Show Z Axis In XZ Plane" 
		  checkbox chk_showYZ "Show Z Axis In YZ Plane" 
		
		colorpicker clr_xColor "X Axis Color:" align:#right
		colorpicker clr_yColor "Y Axis Color:" align:#right
		colorpicker clr_zColor "Z Axis Color:" align:#right
		colorpicker clr_labelColor "Label Color:" align:#right
		
	  )
  
	  on canManipulate target return false
  
	  tool create
	  (
		  on mousePoint click do
			 case click of
			 (
				1: 
				(
					theTM = matrix3 1
				  theTM.row4 = gridPoint
				  nodeTM = theTM
				)
				2: #stop
			 )
		  on mouseMove click do
		  (
			  case click of
			  (
				  2: (
					  size = length gridDist
					  )
			  )
		  )  
	  )
  
	  on updateGizmos do
	  (
		local redColor =	xColor/255.0
		local greenColor =  yColor/255.0
		local blueColor = zColor/255.0		
		local yellowColor = labelColor/255.0
		
		  this.clearGizmos()
		  
		  local flags = 0 
		  this.addGizmoMarker #asterisk [0,0,0] flags yellowColor redColor
  
		  local giz = manip.makeGizmoShape() 
		  giz.AddPoint ([-1.5,-1.5,0] * size)
		  giz.AddPoint ([5.5,-1.5,0]  * size)
		  giz.AddPoint ([5.5,-3,0] * size) 
		  giz.AddPoint ([8.5,0,0]  * size)
		  giz.AddPoint ([5.5,3,0]  * size)
		  giz.AddPoint ([5.5,1.5,0]  * size)
		  giz.AddPoint ([1.5,1.5,0]  * size)
		  this.addGizmoShape giz flags redColor redColor 
		  
		  if showLabels do
		  (
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([5.5,1,0] * size)
			  giz.AddPoint ([7,-1,0]  * size)
			  this.addGizmoShape giz flags yellowColor yellowColor 
			  
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([7,1,0] * size)
			  giz.AddPoint ([5.5,-1,0]  * size)
			  this.addGizmoShape giz flags yellowColor yellowColor 
		  )
		  
		  local giz = manip.makeGizmoShape() 
		  giz.AddPoint ([1.5,1.5,0]  * size)
		  giz.AddPoint ([1.5,5.5,0]  * size)
		  giz.AddPoint ([3,5.5,0]  * size)
		  giz.AddPoint ([0,8.5,0]  * size)
		  giz.AddPoint ([-3,5.5,0]  * size)
		  giz.AddPoint ([-1.5,5.5,0]  * size)
		  giz.AddPoint ([-1.5,-1.5,0]  * size)
		  this.addGizmoShape giz flags greenColor greenColor 
		  
		  if showLabels do
		  (
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([-0.7,7,0] * size)
			  giz.AddPoint ([0,6,0]  * size)
			  this.addGizmoShape giz flags yellowColor yellowColor 
			  
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([0.7,7,0] * size)
			  giz.AddPoint ([0,6,0]  * size)
			  this.addGizmoShape giz flags yellowColor yellowColor 
			  
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([0,6,0]  * size)
			  giz.AddPoint ([0,5,0]  * size)
			  this.addGizmoShape giz flags yellowColor yellowColor 			
		  )		
		  
		  if showXZ do
		  (
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([-1.5,0,0] * size)
			  giz.AddPoint ([-1.5,0,5.5] * size)
			  giz.AddPoint ([-3,0,5.5] * size)
			  giz.AddPoint ([0,0,8.5] * size)
			  giz.AddPoint ([3,0,5.5] * size)
			  giz.AddPoint ([1.5,0,5.5] * size)
			  giz.AddPoint ([1.5,0,0] * size)
			  giz.AddPoint ([-1.5,0,0] * size)			
			  this.addGizmoShape giz flags blueColor blueColor 	
  
			  if showLabels do
			  (
				  local giz = manip.makeGizmoShape() 
				  giz.AddPoint ([-0.7,0,7] * size)
				  giz.AddPoint ([0.7,0,7]  * size)
				  giz.AddPoint ([-0.7,0,5]  * size)
				  giz.AddPoint ([0.7,0,5]  * size)
				  this.addGizmoShape giz flags yellowColor yellowColor 
			  )	
		  )
		  if showYZ do
		  (
			  local giz = manip.makeGizmoShape() 
			  giz.AddPoint ([0,-1.5,0] * size)
			  giz.AddPoint ([0,-1.5,5.5] * size)
			  giz.AddPoint ([0,-3,5.5] * size)
			  giz.AddPoint ([0,0,8.5] * size)
			  giz.AddPoint ([0,3,5.5] * size)
			  giz.AddPoint ([0,1.5,5.5] * size)
			  giz.AddPoint ([0,1.5,0] * size)
			  giz.AddPoint ([0,-1.5,0] * size)			
			  this.addGizmoShape giz flags blueColor blueColor 		
			  
			  if showLabels do
			  (
				  local giz = manip.makeGizmoShape() 
				  giz.AddPoint ([0,-0.7,7] * size)
				  giz.AddPoint ([0,0.7,7]  * size)
				  giz.AddPoint ([0,-0.7,5]  * size)
				  giz.AddPoint ([0,0.7,5]  * size)
				  this.addGizmoShape giz flags yellowColor yellowColor 
			  )				
		  )
		  return "UCS"
	  )
  )

#18

Using the circle gizmo is there a quick way to rotate the circle rather than making a custom one on the Y axis?
I’ve made a custom one using curves but it seems like the long way to do it considering there is already a basic circle manipulator available.


#19

RTFM? :twisted:

Each gizmo provides a transform method which can be called with an arbitrary matrix.
So you can pass a rotation matrix if you want it rotated.

		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		this.addGizmoShape giz flags yellowColor yellowColor 	

		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		giz.transform (rotateXMatrix 90)
		this.addGizmoShape giz flags yellowColor yellowColor 		  
		  
		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		giz.transform (rotateYMatrix 90)
		this.addGizmoShape giz flags yellowColor yellowColor 		

Or you can provide any matrix with a row4 to also offset the gizmo from the pivot of the manipulator.

	   local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		theTM = matrix3 1
		theTM.row4 = [8.5,0,0]*size
		giz.transform theTM
		this.addGizmoShape giz flags yellowColor yellowColor 	

		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		theTM = (rotateXMatrix 90)
		theTM.row4 = [8.5,0,0]*size
		giz.transform theTM
		this.addGizmoShape giz flags yellowColor yellowColor 		  
		  
		local giz = manip.makeCircle [0,0,0] (1.5*size) 32
		theTM = (rotateYMatrix 90)
		theTM.row4 = [8.5,0,0]*size
		giz.transform theTM
		this.addGizmoShape giz flags yellowColor yellowColor 		 

#20

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.