macroscript CG2_ExplodeMesh
category: "Claudes_Attempt"
buttontext: "ExplodeMesh"
Icon: #("SW_GeoDef",1)
tooltip: "Explode Mesh"
(
kRegularMethod = 1;
kPolyMethod = 2;
kPolyClumpMethod = 3;
theWindow;
setupRollout;
methodstrs = #("Regular","Polygon","PolyClump")
gMethod = 1;
gmaxClumpSize = 32;
gsubDivide = false;
gsubDivisions = 1;
gmaxThickness = 10.0;
gXdiv = 4;
gYdiv = 4;
gZdiv = 4;
--**********************************************************************************************
fn minimum a b =
(
if a < b then return a else return b;
)
--**********************************************************************************************
fn GetPolyFromFace theMesh theface =
(
meshop.getPolysUsingFace theMesh theMesh.faces[theface]
)
--**********************************************************************************************
fn GetElementFromFace theMesh theface =
(
meshop.getElementsUsingFace theMesh theMesh.faces[theface]
)
--**********************************************************************************************
-- creates a new mesh based on a single poly
fn DetachPoly theMesh face =
(
-- get the faces with our volume
thefaces = GetPolyFromFace theMesh face
-- detach the trimesh and delete faces from the old mesh
detached_trimesh = meshop.detachfaces theMesh thefaces asmesh:true
-- create an empty node and set its trimesh to our detached trimesh
new_mesh = editable_mesh()
new_mesh.mesh = detached_trimesh
new_mesh.position = theMesh.position
new_mesh.material = theMesh.material
return new_mesh
)
--**********************************************************************************************
-- creates a new mesh based on elements
fn DetachElementToMesh theMesh face =
(
-- get the faces with our volume
thefaces = GetElementFromFace theMesh face
-- detach the trimesh and delete faces from the old mesh
detached_trimesh = meshop.detachfaces theMesh thefaces asmesh:true
-- create an empty node and set its trimesh to our detached trimesh
new_mesh = editable_mesh()
new_mesh.mesh = detached_trimesh
new_mesh.position = theMesh.position
new_mesh.material = theMesh.material
return new_mesh
)
--*************************************************************
fn SplitAt theMesh Axis Position =
(
case Axis of
(
1: (meshop.slice theMesh theMesh.faces [1,0,0] Position separate:true;)
2: (meshop.slice theMesh theMesh.faces [0,1,0] Position separate:true;)
3: (meshop.slice theMesh theMesh.faces [0,0,1] Position separate:true;)
)
)
--*************************************************************
fn RegularCut theMesh xdiv ydiv zdiv =
(
divlen = (theMesh.max.x - theMesh.min.x)/xdiv
for i = 1 to (xdiv - 1) do
(
SplitAt theMesh 1 ((theMesh.min.x + i * divlen) - theMesh.pos.x);
)
divlen = (theMesh.max.y - theMesh.min.y)/ydiv
for i = 1 to (ydiv - 1) do
(
SplitAt theMesh 2 ((theMesh.min.y + i * divlen) - theMesh.pos.y);
)
divlen = (theMesh.max.z - theMesh.min.z)/zdiv
for i = 1 to (zdiv - 1) do
(
SplitAt theMesh 3 ((theMesh.min.z + i * divlen) - theMesh.pos.z);
)
)
--*************************************************************
fn ExplodeTo theMesh explodeMethod =
(
objlist = #();
explode_count = 0;
while theMesh.numfaces != 0 do
(
explodedMesh = explodeMethod theMesh 1;
explodedMesh.name = theMesh.name + "_" + explode_count as string;
explode_count += 1
append objlist explodedMesh;
)
delete theMesh;
theMesh = undefined;
return objlist;
)
--*************************************************************
-- returns all the adjacent faces to the supplied face list
fn GetSurroundingFaces theMesh theFaces =
(
(meshop.getFacesUsingEdge theMesh (meshop.getEdgesReverseEdge theMesh (meshop.getEdgesUsingFace theMesh theFaces))) \
- theFaces as bitarray
)
--*************************************************************
fn RandomFaceExplode theMesh maxClumpSize =
(
objlist = #();
facelist = #();
explode_count = 0;
--loop until there are no faces left
while theMesh.numfaces != 0 do
(
facelist = #()
-- pick a starting face at random and append to our list
firstFace = random 1 theMesh.numfaces;
append facelist firstFace
-- decide how may polys are going to make up our clump
numAdditionfaces = random 1 (minimum (theMesh.numfaces - 1) maxClumpSize);
-- loop till with picked all the poly's in the clump
while numAdditionfaces != 0 do
(
-- randomly pick a surrounding polygon base on the current face list
surrfaces = (GetSurroundingFaces theMesh facelist) as array;
-- this adds a some overprocessing on isolated polys
if surrfaces.count != 0 then
(
append facelist surrfaces[(random 1 surrfaces.count)];
)
numAdditionfaces = numAdditionfaces - 1;
)
-- create a new object from the poly's in the face list
explodedMesh = DetachPoly theMesh facelist;
explodedMesh.name = theMesh.name + "_" + explode_count as string;
explodedMesh.pos = theMesh.pos;
explode_count += 1;
append objlist explodedMesh;
)
-- delete our mesh now that it has zero faces
delete theMesh;
theMesh = undefined;
return objlist;
)
--*************************************************************
fn TessellateTheMesh theMesh subdivisions =
(
for i = 1 to subdivisions do
(
meshop.edgeTessellate theMesh theMesh.faces 0.0
)
)
--*************************************************************
fn AddDepth theMesh depth =
(
shellMod = shell()
shellMod.innerAmount = depth;
shellMod.outerAmount = 0.0;
addModifier theMesh shellMod;
convertToMesh theMesh;
)
--*************************************************************
-- main calling routine
fn ExplodeTheMesh theMesh method subdivide =
(
case method of
(
kRegularMethod:
(
RegularCut theMesh gXdiv gYdiv gZdiv;
objlist = ExplodeTo theMesh DetachElementToMesh;
for i in objlist do
(
meshop.weldVertsByThreshold i i.verts 0.001;
)
)
kPolyMethod:
(
objlist = ExplodeTo theMesh DetachPoly;
)
kPolyClumpMethod:
(
objlist = RandomFaceExplode theMesh gmaxClumpSize;
)
)
if subdivide then
(
for i in objlist do
(
TessellateTheMesh i gsubDivisions ;
subdivObjlist = RandomFaceExplode i gmaxClumpSize;
for j in subdivObjlist do
(
AddDepth j gmaxThickness;
j.pivot = j.center;
)
)
)
else
(
for j in objlist do
(
AddDepth j gmaxThickness;
j.pivot = j.center;
)
)
)
--*************************************************************
rollout setupRollout "Exlpode Setup"
(
fn obj_filter obj = classof obj == Editable_mesh
dropdownlist methodDDL "Method: " items:methodstrs selection:gMethod width:80;
spinner xdivSpnr "X div:" range:[1,32,gxdiv] type:#integer fieldWidth:28 align:#left offset:[0,4];
spinner ydivSpnr "Y div:" range:[1,32,gydiv] type:#integer fieldWidth:28 align:#left offset:[70,-21];
spinner zdivSpnr "Z div:" range:[1,32,gzdiv] type:#integer fieldWidth:28 align:#left offset:[140,-21];
spinner maxClmpSizeSpnr "Max Clump Size:" range:[1,100,gmaxClumpSize] type:#integer fieldWidth:36 align:#left offset:[0,4];
checkbox subdivChkBx "SubDivide" checked:gsubDivide offset:[0,4];
spinner subDivisionSpnr "Sub-divisions:" range:[1,4,gsubDivisions] type:#integer fieldWidth:36 align:#left offset:[88,-19] enabled:subdivChkBx.state;
spinner thicknessSpnr "Object Thickness:" range:[0.0,100.0,gmaxThickness ] type:#float fieldWidth:40 align:#left offset:[0,4];
pickbutton objPicker "Pick Object" width:140 align:#center filter:obj_filter offset:[0,4];
on methodDDL selected item do gMethod = item;
on xdivSpnr changed val do gxdiv = val;
on ydivSpnr changed val do gydiv = val;
on zdivSpnr changed val do gzdiv = val;
on subdivChkBx changed state do
(
gsubDivide = state;
subDivisionSpnr.enabled = state;
)
on subDivisionSpnr changed val do gsubDivisions = val;
on thicknessSpnr changed val do gmaxThickness = val;
-- dooooo it
on objPicker picked obj do
(
undo on
(
ExplodeTheMesh obj gMethod gsubDivide;
)
)
)
--*************************************************************
on execute do
(
try(CloseRolloutFloater theWindow)catch()
theWindow = newRolloutFloater "Explode Mesh" 250 216 8 100
Addrollout setupRollout theWindow
)
)
--end of script
--*************************************************************