[Closed] Scripted modifer crashes max
Hi there,
I’m working on my first scripted modifier and running into some Problems.
First of all, the code:
plugin modifier StickToSurfaceMod
name:"Stick to Surface"
classID:#(685325,452281)
extends:Edit_Mesh replaceUI:true version:1
(
parameters main rollout:params
(
RayDirX type:#float animatable:true ui:RayX default:0.0
RayDirY type:#float animatable:true ui:RayY default:0.0
RayDirZ type:#float animatable:true ui:RayZ default:1.0
--on RayDirX set val do delegate.angle = val
)
fn geomFilt o = (superClassOf o == GeometryClass) --- pickObject Filter
rollout params "StickToSurface"
(
spinner RayX "Ray X: " range:[0,1,0]
spinner RayY "Ray Y: " range:[0,1,0]
spinner RayZ "Ray Z: " range:[0,1,1]
button ObjectSelectButton "Select target object"
on ObjectSelectButton pressed do
(
mytargetobject = pickObject prompt:"Select target object" filter:geomFilt
if mytargetobject != undefined do
(
ObjectSelectButton.caption = mytargetobject.name
)
)
)
)
There’s no real function to it right now, i just want to get it working first.
After running this, the modifier loads and is available, the rollout works.
But after some seconds my max freezes and i have to kill it. I have no idea what’s causing this.
Later on i would like to access the selected vertices of the object that holds the modifer.
I know how to get verts of objects, but how to get the object in question?
And last how to make the modifier load automatically? Just put it in startup scripts?
English is not my first language, so i apologize for any mistakes or typos.
I would appreciate any idea how to make this work.
Okay i advanced a bit.
Changing extends:Edit_Mesh to Bend stopped the crashing.
It seems like somehow I’m missing something important. The Scripted modifier example in the mxs help changes the object in this line: (afaik)
on bendamt set val do delegate.angle = val
Full Example:
plugin modifier myMod
name:"Supa Mod"
classID:#(685325,452281)
extends:Bend replaceUI:true version:1
(
parameters main rollout:params
(
bendamt type:#float animatable:true ui:bendamt default:0.0
on bendamt set val do delegate.angle = val
)
rollout params "SupaMod Parameters"
(
spinner bendamt "Bendiness: "
)
)
My modifier is supposed to move vertices, when time is changed or objects get moved.
But i don’t get where to put the code for it.
If i put it after the parameter and rollout block it doesn’t work. Do i have to use callbacks?
I was using Maxscript for quite some time now, but scripted modifiers are quite a new thing for me.
if you want to move vertices you have to write simpleMod type. it doesn’t need any extending. there is a Saddle modifier example in the mxs help
your ‘modifier’ plugin has to extend the modifier you really use on background. as i see Bend doesn’t do anything useful for you. if you don’t need any extended functionality just extend EmptyModifier
Thanks, DenisT!
This already brings me closer. Couldn’t find any information on that. The Maxscript examples show Bend and i tried with the edit_mesh because i guessed something in that Direction.
Aaaaaah perfect, Thank you very much. This seems to be the way.
It’s kinda hard to find if I don’t know what to look for
I’ll have a look into it tmr morning (off time in Germany now).
i don’t have right now… but i can write a simpleMod blind:
plugin simpleMod MoveIt
name:"MoveIt"
classID:#(123321,456654)
(
parameters main rollout:main
(
direction type:#integer ui:ui_direction default:1
)
rollout main "Parameters"
(
radiobuttons ui_direction "Direction:" labels:#("X","Y","Z") columns:3
)
on map i p do
(
p[direction] += currenttime
p
)
)
Thanks to your help i am already much closer to what i want.
Now i ran into some other issues, would be great to have some ideas on solving this.
Code is here:
outdated, look below for the new one
I attached a screenshot of my scene, the testing setup is simple.
There’s a box (green) and a plane on top of it (blue).
Then i selected the upper Vertices of the box and applied my new modifier.
In the modifier i select the plane as target object.
The selected verts get moved up to the plane (i added a noise to clarify).
So far, so good.
Problems:
The Verts are offset, i don’t know why. My guess is that it has to do with local vs. global positions. How can i get rid of this?
Solved
The controls for the ray directions in the modifier don’t work as i want them to. Basically they should define the direction in which i shoot my rays to the collision mesh. It works if i shoot only up in Z, but if i try to shoot sideways in +Y for example it acts weird.
If i move the plane, my box acts properly, means the vertices move according to the noise on the plane. However if i move the box, the vertices dont react. Again i guess it’s about local and global transformations.
Anyway, i made some good progress in this, thank you very much!
I hope you can help me finish this
edit:
After some more testing if found out that moving the plane only works if i do it “live” in viewport. If i animate it with keyframes, the box doesn’t react anymore…
edit2:
Okay my fault, i discoverd some user errors in my script when handling the positions.
Only changing p.z, gonna fix this part…
edit3:
Fixed the RayDirection issue, new code here
plugin simpleMod StickToSurfaceMod
name:"Stick to surface"
classID:#(685325,452281)
version:1
(
parameters main rollout:params
(
RayDirX type:#float animatable:true ui:RayX default:0.0
RayDirY type:#float animatable:true ui:RayY default:0.0
RayDirZ type:#float animatable:true ui:RayZ default:1.0
myCollider type:#node animatable:false ui:ObjectSelectButton
)
fn geomFilt o = (superClassOf o == GeometryClass) --- pickObject Filter
rollout params "StickToSurface"
(
spinner RayX "Ray X: " range:[-1,1,0]
spinner RayY "Ray Y: " range:[-1,1,0]
spinner RayZ "Ray Z: " range:[-1,1,1]
button ObjectSelectButton "Select target object"
on ObjectSelectButton pressed do
(
myCollider = pickObject filter:geomFilt
if myCollider != undefined do
(
ObjectSelectButton.caption = myCollider.name
)
)
)
on map i p do
(
try
(
if myCollider != undefined then
(
p = (intersectRay myCollider (ray p [RayDirX,RayDirY,RayDirZ])).pos
p
)
else
(
--print "collider is undefined"
p
)
)
catch
(
--print (getCurrentException())
p
)
)
)
A good thing to understand is that vertices in the scripted modifier don’t live in world space, they live in local local space, and that local space is calculated from the centerpoint of the modifier. So to calculate the world space you need to go through several spaces.
modifier transform, object offset transform, object transform. If you have done all that, you translated yourself into world space…
-Johan
Hm okay, thanks for your answer.
I guessed in that direction. So I am going to dig deeper there.
Thanks again!