[Closed] 'Create' button for primitives ?
Hello.
I have written a template script for custom primives I’m working on and I’d like to have both by-button and by-mouse creation modes.
The thing is I don’t know where to put the on doIt pressed do block nor what to put in it. Can anyone help please ?
plugin simpleObject primTemp
name:"Template"
category:"Custom Primitives"
classID:#(0x356fa575, 0x54da4b86)
(
parameters main rollout:params
(
sides type:#integer ui:sides default:12
radius type:#float ui:radius default:0
)
rollout params "Parameters"
(
spinner sides "Sides" range:[3,60,12] type:#integer
spinner radius "Radius" range:[0,100,0]
button doIt "Create"
)
on buildMesh do
(
vArr = #()
fArr = #()
append vArr [0,0,0]
for i = 1 to sides do
(
tAng = (i - 1) * 360 / sides
append vArr [radius * cos(tAng), radius * sin(tAng),0]
append fArr [1,i + 1,(mod i sides) + 2]
)
setMesh mesh vertices:vArr faces:fArr
)
tool create
(
-- on doIt pressed do ...what?
on mousePoint click do
case click of
(
1: nodeTM.translation = gridPoint
2: #stop
)
on mouseMove click do
radius = length [gridDist.x,gridDist.y]
)
)
Did I make the noob mistake and ask for something either very hard to implement or just impossible?
Someone, please?
This may be a case of the blind leading the blind, Pat, but it’s sounding to me that you’d want a simple Boolean switch to enable either creation by mouse or creation by button. I’d think a couple of radio buttons would do it, i.e., on rdo_creation mode changed do (create tool, etc.). Or a simple “if/then/else” statement.
Hi Bruce. So we meet here too. Small world, hu?
It’s more about creating the node with a button pressed event, like the regular max primitives.
This is what I’ve understood so far from the MaxScript user reference and some of Bobo’s threads (I was hoping he’d be around):
The buildmesh creates a virtual mesh (in memory, not in the scene). So you need a create tool to make an instance of that mesh (a node in the scene). But the create tool seems to accept only mouse events handlers and this is where I’m stuck. I don’t see where a button pressed event can fit in. Nor of any other way to create the instanced node than the create tool.
I fear that it can only be achieved through the SDK. But I would have liked a confirmation.
I was hoping for a way around, like maybe faking the mouseclick through some code, or calling a separate script? I don’t know.
Could one of the MXS masters around here shed some light on the matter? I’m really stuck here. And more than likely misunderstanding some important concepts.
Maxscript Tools and Interaction with 3ds Max > Creating MAXScript Tools > Scripted Plug-ins > Scripted SimpleObject Plug-ins
“The mesh plug-in local variable is accessible in any of the plug-in’s handlers, but is typically only built in the on buildMesh handler. You can either modify the existing TriMesh value in place using the TriMesh methods, or construct a new TriMesh value and assign it to the mesh plug-in local variable.”
The “on doIt pressed” must be inside the rollout.
May be you can call a function to modify the mesh from there.
You can access to the trimesh with “this.mesh”
Good luck!
Thanks a lot for your answer, Fernando.
After a lot of tries, it feels that I’m pretty close to a solution. But I haven’t been able to find the correct form with “this.mesh”.
I guess the setMesh method alone is not enough to create a node outside of the on buildMesh block. I don’t know how to create the node and still have access to its parameters through the rollout (like with the regular Primitives).
Here is what I’ve got, with obvioulsy something missing:
plugin simpleObject primTemp
name:"Template"
category:"Custom Primitives"
classID:#(0x356fa575, 0x54da4b86)
(
local vArr = #()
local fArr = #()
fn buildIt s r =
(
vArr = #()
fArr = #()
append vArr [0,0,0]
for i = 1 to s do
(
tAng = (i - 1) * 360.0 / s
append vArr [r * cos(tAng), r * sin(tAng),0]
append fArr [1,i + 1,(mod i s) + 2]
)
)
parameters main rollout:params
(
sides type:#integer ui:sides default:12
radius type:#float ui:radius default:0
)
rollout params "Parameters"
(
spinner sides "Sides" range:[3,60,12] type:#integer
spinner radius "Radius" range:[0,100,0]
button doIt "Create"
on doIt pressed do
(
radius.value = 25
buildIt sides.value radius.value
setMesh mesh vertices:vArr faces:fArr -- <<< something missing...
)
)
on buildMesh do
(
buildIt sides radius
setMesh mesh vertices:vArr faces:fArr
)
tool create
(
on mousePoint click do
case click of
(
1: nodeTM.translation = gridPoint
2: #stop
)
on mouseMove click do
radius = length [gridDist.x,gridDist.y]
)
)
I must be somewhere in the User Reference, but I can’t find it.
The mesh needs do be set inside your buildIt function or else all that work you’ve done just disappears when the fn ends. So you need to put:
setMesh this.mesh vertices:vArr faces:fArr
as the last line of buildIt() and take it out of the on buildMesh and on doIt.
Hello James. Thanks for your reply.
I’ve done as you said:
plugin simpleObject primTemp
name:"Template"
category:"Custom Primitives"
classID:#(0x356fa575, 0x54da4b86)
(
local vArr = #()
local fArr = #()
fn buildIt s r =
(
vArr = #()
fArr = #()
append vArr [0,0,0]
for i = 1 to s do
(
tAng = (i - 1) * 360.0 / s
append vArr [r * cos(tAng), r * sin(tAng),0]
append fArr [1,i + 1,(mod i s) + 2]
)
setMesh this.mesh vertices:vArr faces:fArr
)
parameters main rollout:params
(
sides type:#integer ui:sides default:12
radius type:#float ui:radius default:0
)
rollout params "Parameters"
(
spinner sides "Sides" range:[3,60,12] type:#integer
spinner radius "Radius" range:[0,100,0]
button doIt "Create"
on doIt pressed do
(
radius.value = 25
buildIt sides.value radius.value
)
)
on buildMesh do
(
buildIt sides radius
)
tool create
(
on mousePoint click do
case click of
(
1: nodeTM.translation = gridPoint
2: #stop
)
on mouseMove click do
radius = length [gridDist.x,gridDist.y]
)
)
The button handler still doesn’t perform any action, but now the creation by mouse is gone too. Though if I change
setMesh this.mesh vertices:vArr faces:fArr
by
setMesh mesh vertices:vArr faces:fArr
in the function, I get the mouse tool back, but nothing new with the button
I try to understand the logic behind it, I’ve been through an through everything I could find in the User Reference, I tried to find examples on the net. Nothing.
And I thought the question was trivial when I posted it…
So, what’s missing?
What I’ve found so far:
There is no dependents till the mouse tool starts, (one of the dependents is the node you are trying to modify).
Because:
print (refs.dependents this)
prints nothing till you move the mouse inside any viewport.
fn createIt tempmesh = (
...
setMesh tempmesh vertices:vArr faces:fArr
tempmesh
)
...
on buildMesh do (mesh = (createIt mesh))
works only for the mouse tool.
on create do (print "create")
Inside the plugin and at the of it (after the mouse tool create), prints “create” anytime the plugin starts, (by clicking on the Template button).
So, here there would be a way to create an empty trimesh outside the mouse tool (the one needed to the node you are creating).
May be you have to experiment developing another tool inside the plugin…
Hi Fernando. Thanks again for the help.
I feel that I’m going in circle here.
Maybe it’s something inherent to simpleObject plugins that the node must be created inside the buildMesh block.
And even if I were able to create the node, I think I couldn’t keep it wired to its parameters because the setMesh method refuses to work outside the buildMesh, or a function called from the buildMesh.
When they say “but is typically only built in the on buildMesh handler”, I guess by “typically” they mean “exclusively”.
I dunno. I might be missing some important point again. I’ll make some more tries tomorrow.
James, just a precision. In the code just before your post, where the “setMesh mesh vertices:vArr faces:fArr” is executed from within the buildMesh block, not the function, the mouse tool worked fine. That’s because vArr and fArr are declared outside any block, so the function fills them and then can be accessed from anywhere in the code.
I declared the arrays there so I could experiment with the setMesh at different places without having to worry about them.