[Closed] custom helpers
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
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
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.
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?
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.
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.
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.
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
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.
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.
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
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?
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
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
Have you read “Flatland”?
Even the smoothest curve can be seen as just an N-gon with a very high N
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
Now is there a way to link up a colorpicker to the helper so it allows users to change the color of the manipulator?
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"
)
)