home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Maximum 3D 3
/
m3d-p3.iso
/
3DS_MAX
/
3DSMAX.2_0
/
SCRIPTS
/
SUPRSCTR.MS
< prev
next >
Wrap
Text File
|
1997-10-19
|
16KB
|
429 lines
-- ********************************************************************************************
-- * "Super Scatter"
-- * v1.0
-- * a freeware MAXScript scatter utility
-- * by Kyle McKisic
-- * 75542.363@compuserve.com
-- *
-- *
-- * You may distribute this script through any means you see fit,
-- * as long as you do not remove the credits in the 'About' box.
-- *
-- * Please send any bugs or comments to me at the above e-mail
-- * address or fix them yourself if you want... I don't really care :)
-- *
-- * Best viewed when EditorTabWidth = 2 and EditorFont = "Courier"
-- *
-- * Known Problems/Bugs:
-- *
-- * 1. When objects are scattered based on their object centers, rather
-- * than their pivot points, and their orientations are changed, it's
-- * being done based on the object's pivot point, rather than it's
-- * geometrical center.
-- *
-- * 2. When you close the Super Scatter rollout floater window, you have
-- * to close and re-open the utility to get the window back. It should
-- * work a little better than that.
-- *
-- *
-- * Other features I'm planning on implementing:
-- *
-- * - Edge Center placement method.
-- * - Ability to scatter n copies randomly over the distribution object.
-- * - Scatter over selected verts, selected faces, or selected edges.
-- * - Scatter based on a loaded bitmap, interpreted through the distribution
-- * objects UV's.
-- * - Key random scale (uniform and non-uniform), density, and random rotation
-- * from bitmaps.
-- * - Add the ability to have one, single object at the end of scattering. Note
-- * that you can do this manually by collapsing all the scatter objects into one
-- * object through the Collapse Utility.
-- * - Scatter onto multiple objects at one time.
-- * - add support for groups, and other wacky MAX objects - some of these may already
-- * work, I just haven't tested all of them yet.
-- *
-- ********************************************************************************************
Utility ScatterUtil "Super Scatter v1.0"
(
local DistObj, ScatterObj, ScatterRollout, Nth, CDir, DistObjCenter, InitDir, SourceDistObject,
DistObjFaces = #(),
DistObjVerts = #(),
ScatteredObjects = #(),
FaceNormalArray = #(),
VertexNormalArray = #(),
ScatterNormalArray = #()
label title1 "Super Scatter"
label title2 "v1.0"
label title3 "by Kyle McKisic"
label title4 "75542.363@compuserve.com"
on ScatterUtil open do
(
rof = (NewRolloutFloater "Super Scatter v1.0" 320 470)
addrollout ScatterRollout rof
)
rollout ScatterRollout "Super Scatter"
(
button aboutScatter "About" width:35 height:20
group "Scatter Options"
(
label DistLabel "Distribution Object:" align:#left offset:[-5,0]
pickbutton GetDistObj width:170 align:#right offset:[0,-21]
label scatterLabel "Scatter Object:" align:#left offset:[-5,0]
pickbutton GetScatterObj width:170 align:#right offset:[0,-21]
radiobuttons placementMethod "Placement method:" labels:#("Object Pivot","Object Center") align:#left columns:1
spinner PlaceOnEvery range:[1,99999,1] type:#integer fieldwidth:45 offset:[0,-50]
radiobuttons Placement "Place on every Nth:" labels:#("Vertex","Face center") columns:1 align:#right offset:[-74,-21] fieldwidth:35
radiobuttons copytype "Clone method:" labels:#("Copy", "Instance","Reference") align:#left columns:1
button ScatterBtn "Scatter" width:80 height:40 offset:[0,-50]
button ReInitialize "Reinitialize" offset:[95,-45] width:80 height:40
label blank0
)
group "Orientation Options"
(
radiobuttons OrientationType labels:#("Initial orientation","Explicit direction","Cylindrical projection","Spherical projection","Normal to surface") align:#left columns:1
Spinner Xdir "X:" range:[-1,1,0] type:#float fieldwidth:45 offset:[-70,-85] enabled:false
Spinner YDir "Y:" range:[-1,1,0] type:#float fieldwidth:45 offset:[-70,0] enabled:false
Spinner ZDir "Z:" range:[-1,1,1] type:#float fieldwidth:45 offset:[-70,0] enabled:false
pickbutton PickDir "Pick dir" offset:[35,0] enabled:false
label Presetslabel "Presets:" offset:[110,-93] enabled:false
button TopPreset "T" offset:[97,-3] width:25 enabled:false
button BottomPreset "B" offset:[124,-26] width:25 enabled:false
button LeftPreset "L" offset:[97,-3] width:25 enabled:false
button RightPreset "R" offset:[124,-26] width:25 enabled:false
button FrontPreset "F" offset:[97,-3] width:25 enabled:false
button BackPreset "K" offset:[124,-26] width:25 enabled:false
label blank2
checkbox InteractiveUpdate "Interactive Update" checked:true
button UpdateDir "Manual Update" offset:[35,-23] enabled:false height:32
label blank3
)
-- about box
on aboutScatter pressed do
messagebox "Super Scatter\nv1.0\nby Kyle McKisic\n75542.363@compuserve.com" title:"About Super Scatter..."
on GetDistObj picked obj do
(
SourceDistObject = obj
DistObj = (copy obj)
convertToMesh DistObj
DistObj.wireColor = obj.wireColor
-- get the face and vertex data from the distribution object so we don't have keep
-- getting it from the mesh anytime we want to do something
DistObjFaces = for i = 1 to DistObj.numFaces collect (getFace DistObj i)
DistObjVerts = for i = 1 to DistObj.numVerts collect (getVert DistObj i)
DistObjCenter = DistObj.center
FaceNormalArray = for i = 1 to DistObj.numfaces collect (getFaceNormal DistObj i)
VertexNormalArray = for i = 1 to DistObj.numverts collect (getNormal DistObj i)
GetDistObj.text = DistObj.name
-- we've got the data, so get rid of it...
delete DistObj
)
on GetScatterObj picked obj do
(
ScatterObj = obj
GetScatterObj.text = ScatterObj.name
)
on ScatterBtn pressed do
(
if ScatterObj != undefined then
(
undo on
(
-- here, we collect do a quick compare to make sure
-- the user didn't go and modify the mesh after picking it
DistObj = copy SourceDistObject
convertToMesh DistObj
nv = DistObj.numVerts
nf = DistObj.numFaces
delete DistObj
if (nv == DistObjVerts.count) and (nf == DistObjFaces.count) then
(
-- reset these arrays
ScatteredObjects = #()
ScatterNormalArray = #()
-- grab the Initial directional vector from the scatter object
InitDir = ScatterObj.dir
nv = DistObjVerts.count
nf = DistObjFaces.count
Nth = PlaceOnEvery.value
ProgressStart "Generating scattered result...."
if Placement.state == 1 then
(
for i = 1 to nv do
(
if (mod i Nth) == 0 do
(
CVertPos = DistObjVerts[i]
if copytype.state == 1 do
CScatterTempObj = copy ScatterObj
if copytype.state == 2 do
CScatterTempObj = instance ScatterObj
if copytype.state == 3 do
CScatterTempObj = reference ScatterObj
append ScatteredObjects CScatterTempObj
append ScatterNormalArray VertexNormalArray[i]
if PlacementMethod.state == 1 then
CScatterTempObj.pos = CVertPos
else
CScatterTempObj.pos = (CVertPos + (ScatterObj.pivot - ScatterObj.center))
-- update the progress bar
ProgressUpdate ((i / nv as float) * 100)
)
)
) else (
for i = 1 to nf do
(
if (mod i Nth) == 0 do
(
CFace = DistObjFaces[i]
Vert1 = DistObjVerts[CFace.x]
Vert2 = DistObjVerts[CFace.y]
Vert3 = DistObjVerts[CFace.z]
CPos = ((Vert1 + Vert2 + Vert3) / 3)
if copytype.state == 1 do
CScatterTempObj = copy ScatterObj
if copytype.state == 2 do
CScatterTempObj = instance ScatterObj
if copytype.state == 3 do
CScatterTempObj = reference ScatterObj
append ScatteredObjects CScatterTempObj
append ScatterNormalArray FaceNormalArray[i]
if PlacementMethod.state == 1 then
(
CScatterTempObj.pos = CPos
) else (
CScatterTempObj.pos = (CPos + (ScatterObj.pivot - ScatterObj.center))
)
ProgressUpdate ((i / nf as float) * 100)
)
)
)
ProgressEnd()
) else (
MessageBox "Distribution object topology has changed.\nPlease re-pick your distribution object."
)
)
) else (
MessageBox "Necessary Scatter objects are not defined yet!"
)
)
-- cleaning the dialog
on ReInitialize pressed do
(
-- remove the rollout
removeRollout ScatterRollout rof
-- clean out the variables
ScatterObj = undefined
CDir = undefined
DistObjCenter = undefined
InitDir = undefined
DistObjFaces = #()
DistObjVerts = #()
ScatteredObjects = #()
FaceNormalArray = #()
VertexNormalArray = #()
ScatterNormalArray = #()
-- and add the rollout back again
addRollout ScatterRollout rof
)
on InteractiveUpdate changed state do
if state == on then
UpdateDir.enabled = false
else
UpdateDir.enabled = true
on UpdateDir pressed do
(
if OrientationType.state == 1 do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = InitDir
if OrientationType.state == 2 do
(
CDir = [Xdir.value, YDir.value, ZDir.value]
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
if OrientationType.state == 3 do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = normalize (ScatteredObjects[i].pos - [DistObjCenter.x, DistObjCenter.y, ScatteredObjects[i].pos.z])
if OrientationType.state == 4 do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = normalize (ScatteredObjects[i].pos - DistObjCenter)
if OrientationType.state == 5 do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = ScatterNormalArray[i]
)
on OrientationType changed state do
(
if state == 1 do
(
PickDir.enabled = Xdir.enabled = YDir.enabled = ZDir.enabled = Presetslabel.enabled = TopPreset.enabled = BottomPreset.enabled = LeftPreset.enabled = RightPreset.enabled = FrontPreset.enabled = BackPreset.enabled = false
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = InitDir
)
if state == 2 do
(
PickDir.enabled = Xdir.enabled = YDir.enabled = ZDir.enabled = Presetslabel.enabled = TopPreset.enabled = BottomPreset.enabled = LeftPreset.enabled = RightPreset.enabled = FrontPreset.enabled = BackPreset.enabled = true
if InteractiveUpdate.checked do
(
CDir = [Xdir.value, YDir.value, ZDir.value]
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
)
if state == 3 do
(
PickDir.enabled = Xdir.enabled = YDir.enabled = ZDir.enabled = Presetslabel.enabled = TopPreset.enabled = BottomPreset.enabled = LeftPreset.enabled = RightPreset.enabled = FrontPreset.enabled = BackPreset.enabled = false
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = normalize (ScatteredObjects[i].pos - [DistObjCenter.x, DistObjCenter.y, ScatteredObjects[i].pos.z])
)
if state == 4 do
(
PickDir.enabled = Xdir.enabled = YDir.enabled = ZDir.enabled = Presetslabel.enabled = TopPreset.enabled = BottomPreset.enabled = LeftPreset.enabled = RightPreset.enabled = FrontPreset.enabled = BackPreset.enabled = false
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = normalize (ScatteredObjects[i].pos - DistObjCenter)
)
if state == 5 do
(
PickDir.enabled = Xdir.enabled = YDir.enabled = ZDir.enabled = Presetslabel.enabled = TopPreset.enabled = BottomPreset.enabled = LeftPreset.enabled = RightPreset.enabled = FrontPreset.enabled = BackPreset.enabled = false
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = ScatterNormalArray[i]
)
)
on XDir changed state do
(
CDir = [XDir.value, YDir.value, ZDir.value]
CDir = normalize CDir
YDir.value = CDir.y
ZDir.value = CDir.z
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on YDir changed state do
(
CDir = [XDir.value, YDir.value, ZDir.value]
CDir = normalize CDir
XDir.value = CDir.x
ZDir.value = CDir.z
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on ZDir changed state do
(
CDir = [XDir.value, YDir.value, ZDir.value]
CDir = normalize CDir
YDir.value = CDir.y
XDir.value = CDir.x
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on TopPreset pressed do
(
XDir.value = 0
YDir.value = 0
ZDir.value = 1
CDir = [0,0,1]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on BottomPreset pressed do
(
XDir.value = 0
YDir.value = 0
ZDir.value = -1
CDir = [0,0,-1]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on LeftPreset pressed do
(
XDir.value = -1
YDir.value = 0
ZDir.value = 0
CDir = [-1,0,0]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on RightPreset pressed do
(
XDir.value = 1
YDir.value = 0
ZDir.value = 0
CDir = [1,0,0]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on FrontPreset pressed do
(
XDir.value = 0
YDir.value = -1
ZDir.value = 0
CDir = [0,-1,0]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on BackPreset pressed do
(
XDir.value = 0
YDir.value = 1
ZDir.value = 0
CDir = [0,1,0]
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
on PickDir picked obj do
(
CDir = obj.dir
XDir.value = CDir.x
YDir.value = CDir.y
ZDir.value = CDir.z
if InteractiveUpdate.checked do
for i = 1 to ScatteredObjects.count do
ScatteredObjects[i].dir = CDir
)
) -- end rollout
) -- Utility end.....