Hey, this is fun! The only thing more fun than maxscripting (and rigging) is poking your eye with a pencil.
Ok, I just recently got into scripting stuff, and just had my “script related” nightmare a few weeks ago. So pease guys, let me pretend to be a Maxscript master, before “Bobo” shows up. LOL.
Well… first, it only works on Teapots heh heh… and not every teapot too. No, It got to be model Teapot01 or it wont work. (I suppose it’s a very serious bug in core code of 3dsmax hehe) Anyway, I don’t know how to assign a unique name to a selected object, like “my beloved teapot01” so, just open a empty clean scene file and run the script. If it won’t work, it’s your foult.:applause:
Teapot radius:20 smooth:on segs:4 body:on handle:on spout:on lid:on mapcoords:on
$Teapot01.radius = 20
Bomb strength:1 gravity:1 detonation:5f minFragmentSize:1 maxFragmentSize:1 falloff:100 pos:[0,0,0]
bindSpaceWarp $Teapot01 $MeshBomb01
sliderTime = 7f
Mesher radius:10.0 pos:[0,0,0] isSelected:on renderTimeOnly:off
$Mesher01.renderTimeOnly = off
$Mesher01.radius = 10
select $Mesher01
$Mesher01.pick = $Teapot01
macros.run "Modifier Stack" "Convert_to_Poly"
select $Teapot01
max delete
select $MeshBomb01
max[size=2] delete
[/size]
Hey Tughan,
I haven’t actually run the script, but I can see what you’re doing. One really quick scripting tip is to assign objects you create to a variable. That way you can use that variable instead of the object’s name when you want to do anything else with it.
So instead of saying:
Teapot radius:20 smooth:on segs:4 body:on handle:on spout:on lid:on mapcoords:on
$Teapot01.radius = 20 (by the way, you already defined the radius in the first line so you don’t need this one)
You could say:
tPot = Teapot radius:20 smooth:on segs:4 body:on handle:on spout:on lid:on mapcoords:on
tPot.radius = 20
Any place you have “$Teapot01”, you would replace with “tPot”. That way it doesn’t matter what the name is and the script will actually run faster. Probably not noticable with one this small, but it’s a good habit to get into.
Hey good work so far! I have started working on a little somn wich I hope to post tomorrow.
j_man – I couldn’t get yours to work. I get the same errors as JHaywood.
CML
Ok here it goes, my version of Split It Up. Mainly it uses Slice modifiers to split up the mesh. Maybe I did a bit too much but I got caught up in it, heh. Maybe it can be useful.
Here is a screenshot of a model and the interface:
The code(formatting will probably suck):
--Split It Up script by Carl-Mikael Lagnecrantz for CG Talk challenge--
global CGSplitchunks
global CGSplitpos
fn CGSplit_interface =
(
rollout CGSplitroll "Split it"
(
button splitbutt "Split" width: 62 height: 22 align:#center tooltip: "Split up model to chunks."
spinner splitspin "Levels:" range:[1,100,10] type:#integer align:#center fieldwidth:36
checkbox splitcheck "Seperate objects" checked:true
checkbox splitcheck2 "Build inner topology" checked:false
checkbox splitcheck3 "Set Material ID's" checked:true
checkbox splitcheck4 "Mess up inside!" checked:false
radiobuttons splitrad "" labels:#("Type 1","Type 2") default: 1 columns: 2 enabled:false
spinner splitspin3 "Mess amount:" range:[0.0,10000.0,0.0] align:#center fieldwidth:46 enabled:false
group "Check result:"
(
spinner splitspin2 "Move chunks:" range:[0.0,10000.0,0.0] align:#center fieldwidth:46
)
on splitcheck changed state do splitspin2.enabled = state
on splitcheck4 changed state do (splitspin3.enabled = state ; splitrad.enabled = state)
on splitbutt pressed do
(
if selection.count == 1 and classof $ == Editable_Poly then undo off
(
setWaitcursor()
try(suspendEditing())catch()
numval = splitspin.value
polyop.setFaceSelection $.baseobject #all
distMin = $.min-$.pivot
distMax = $.max-$.pivot
for i = 1 to numval do --split up object with slice mod and cap holes
(
addmodifier $ (SliceModifier slice_type:1)
randomrot = quat (random -1.0 1.0) (random -1.0 1.0) (random -1.0 1.0) (random -1.0 1.0)
$.modifiers[#Slice].Slice_Plane.rotation = randomrot
randpos = [(random distMin.x distMax.x),(random distMin.y distMax.y),(random distMin.z distMax.z)]
$.modifiers[#Slice].Slice_Plane.position = randpos
convertTo $ Editable_Poly
polyOp.capHolesByEdge $.baseobject #all
if keyboard.escpressed == true do exit
)
try(resumeEditing())catch()
disablesceneredraw()
if splitcheck2.state == true do --build inner topology by selecting inside verts and connectiong, then removing created edges on the outside
(
inif = polyop.getFaceSelection $.baseobject
allaf = polyop.getNumFaces $.baseobject
innerf = #{1..allaf} - inif
oute = polyop.getEdgesUsingFace $.baseobject inif
polyop.setVertSelection $.baseobject (polyop.getVertsUsingFace $.baseobject innerf)
$.EditablePoly.ConnectVertices ()
oute2 = polyop.getEdgesUsingFace $.baseobject (polyop.getFaceSelection $.baseobject)
polyop.setEdgeSelection $.baseobject (oute2-oute)
$.remove selLevel:#Edge
)
if splitcheck3.state == true do --set material ID's
(
inif = polyop.getFaceSelection $.baseobject
polyOp.setFaceMatID $.baseobject inif 1
allaf = polyop.getNumFaces $.baseobject
inf = #{1..allaf} - inif
polyOp.setFaceMatID $.baseobject inf 2
)
if splitcheck4.state == true do --mess up inside by tesselating the inside faces and moving the resulting verts randomly
(
$.tesselateBy = splitrad.state - 1
inif = polyop.getFaceSelection $.baseobject
allaf = polyop.getNumFaces $.baseobject
inf = #{1..allaf} - inif
polyop.setFaceSelection $.baseobject inf
polyOp.tessellateByFace $.baseobject inf
polyOp.tessellateByFace $.baseobject (polyop.getFaceSelection $.baseobject)
allef = polyop.getNumFaces $.baseobject
ino = #{1..allef} - (polyop.getFaceSelection $.baseobject)
allav = polyop.getNumVerts $.baseobject
innv = #{1..allav} - (polyop.getVertsUsingFace $.baseobject ino)
for w in innv do
(
randvec = normalize ([(random 0.0 10.0),(random 0.0 10.0),(random 0.0 10.0)] - [(random 0.0 10.0),(random 0.0 10.0),(random 0.0 10.0)])
curp = polyop.getVert $.baseobject w node:$
polyop.setVert $.baseobject w (curp + (randvec * splitspin3.value)) node:$
)
)
if splitcheck.state == true then --explode elements to seperate objects
(
Selobj = $
splitval = 0
max select all
while splitval == 0 do --get a random face and detach the element wich the face is on, then select a new random face and so on until there is no faces left
(
elmf = polyop.getElementsUsingFace Selobj.baseobject 1
polyOp.detachFaces Selobj.baseobject elmf delete:true asNode:true node:Selobj
if (polyop.getNumFaces Selobj.baseobject) == 0 do (splitval = 1 ; delete Selobj)
if keyboard.escpressed == true do (splitval = 1 ; delete Selobj)
)
max select invert
CGSplitchunks = selection as array --put all the chunks into an array for later moving
CGSplitpos = for p in CGSplitchunks collect p.pos --put the positions of all chunks into an array
)
else (CGSplitchunks = #() ; CGSplitpos = #())
enablesceneredraw()
setArrowcursor()
gc()
redrawviews()
)
else messagebox "Yes dude...
It needs to be an Editable polygon object!" title:"Split It Up!"
)
on splitspin2 changed value do undo off
(
if CGSplitchunks.count != 0 do --move all chunks
try(
selnum = 0
allpos = [0,0,0]
for d in CGSplitchunks do (selnum += 1 ; allpos += d.center)
midpos = allpos/selnum
for w = 1 to selnum do
(
levec = normalize (CGSplitchunks[w].center-midpos)
CGSplitchunks[w].pos = CGSplitpos[w] + (levec * value)
)
)catch()
)
)
CGSplitfloat = newrolloutfloater "Split It up!" 156 254 790 130
addrollout CGSplitroll CGSplitfloat
)
CGSplit_interface()
Another screenshot showing where the inside is “messed up”:
Here is the script for download too: http://hem.bredband.net/millman/SplitItUp.zip
cheers,
CML
Great work Rivendale. You almost split the viewport itself. Looking cool.
Hey James, thank you very much for the tip man. That was really a big step for me.
Now, an update for “explode it up good!” script.
foo = $
macros.run "Modifier Stack" "Convert_to_Poly"
Bomb strength:1 gravity:1 detonation:5f minFragmentSize:1 maxFragmentSize:1 falloff:100 pos: foo.pos
bindSpaceWarp foo $MeshBomb01
sliderTime = 7f
Mesher radius:10.0 pos:[0,0,0] isSelected:on renderTimeOnly:off
select $Mesher01
max modify mode
$Mesher01.pick = foo
macros.run "Modifier Stack" "Convert_to_Poly"
select foo
max delete
select $MeshBomb01
max delete
By the way, I check out Maxscript documents and some other sample scripts, and I noticed that usually variable assign names are “foo”. What’s up with foo?
Ah ye swines! I wanted to make one of those but rivendale has gone and done it the way I was going to – Looks great folks, looking forward to browsing the source codes and picking up a few nice hints.
Working on automated rigging at the moment with some tasty hand setups that you guys can crit soon
Hehe sorry bout that joconnell:P
I made a little test in reactor with the split up geometry for fun, check it out:
http://hem.bredband.net/millrider/split2.avi
CML
Good job Rivendale! I like it. Can you explain what’s going on with the “Mess up inside” part, and what the types and spinners do? I tried running it once with that option and it worked fine, then I undid that and ran it again with a lower setting, and got a system exception and Max eventually crashed. I’m guessing it’s some sort of memory error. I guess I could read through the script to figure out what’s going on, but I’m lazy.
JHaywood – Thanks. Yeah it has definetly got to do with undo and memory. Not sure if I can do very much about that. When you have high settings there is a whole lot stored in that one undo and when you run the tool a few times that starts adding up. I have noticed that there is not a problem with undo when you have lower settings like up to 10 on a standard cylinder. If you go with higher settings it’s better to perform the splitting on a new clone instead. Turning off undo will not help either since that will most certainly cause a crash. Might be a good idea to add a button to flush undo memory.
The “mess up” part tesselates the inside faces by tesselate type edge or face(just like in edit poly). The it moves the new vertices randomly by the amount in the spinner.
Also note that you can move the chunks away from each other at the bottom after applying the tool to check how the chunks look. This is also really useful when doing a thing like with Reactor since then you will not want to have the chunks interpenetrating each other.
CML