Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 002: "Split it up"

Hmm, maybe I should make this tool not undoable to prevent the buildup in memory. Then I could use gc() to flush the memory and undo buffer. What do you guys think about that?

3 Replies
(@jhaywood)
Joined: 11 months ago

Posts: 0

I don’t think that’s a problem. You’re probably going to want to run the script on a copy of your model anyway, so you can just delete the chunks if you want to try different settings.

And moving the pieces away from each other is a good idea. That’s a nice solution you came with up for that.

(@galagast)
Joined: 11 months ago

Posts: 0

cool looking scripts! I would have loved to join this challenge, but i already did something similar a few months ago… 🙁 although it still needs a lot of work… (and im still stuck at work, cant squeeze out time to join the challenges…sigh)

Is it ok to suggest posting which version of Max you wrote the script in? It seems like some scripts are giving off errors… which is probably because im still using max6…

yup, i guess so too, i also had similar problems when i performed some undos after slicing, most of the times max would just pop out.

It might also be nice to have most of these scripts compiled onto a single package at the end, and post it to scriptspot, with an author name of CGTalkMaxscriptChallengers or something… could really be usefull for other non-maxscript users who just wanna to blow up stuff.

(@erilaz)
Joined: 11 months ago

Posts: 0

Throw that into the suggestions thread for discussion galagast, and I’ll add it to the rules, as well as extentions used.

Definitly a good idea rivendale. I really wanna blow up the boat i just made – and its like 200k polies.

mmmm blowing stuff up

Wow Rivendale, crazy stuff! Well done indeed!

All these scripts are insane! I’m loving this.

Hi Everyone,

Sorry for the late reply, but I’ve been away. Thank you all for having a look at my script, and well done to everyone on some great scripts! I’m a bit confused as to what happend, seems like the CODE tag is messing with my code a bit.

Here is the offending line, and what happends when I post it in CODE tags:

– ok so it seems to mess up without the code tags also.

pgttl=(zdivisions.valueydivisions.valuexdivisions.value)




pgttl=(zdivisions.value*ydivisions.value*xdivisions.value)


I’ve also updated my original code and changed the variable names to get around the problem.

Thanks again.

J.

Rivendale: :applause:THX man… absolute amazing script and very useful for me. Connection with reactor is great.

I tried make similar script a month ago and now it isn’t finish. :rolleyes:

Heya Rivendale… man, I’d love to get your script running and testing… but every time I hit the SPLIT IT! button it gives me the finger:

-- Error occurred in splitbutt.pressed()
--  Frame:
--   innerf: undefined
--   allaf: undefined
--   suspendEditing: undefined
--   distMin: undefined
--   distMax: undefined
--   allef: undefined
--   splitval: undefined
--   innv: undefined
--   inif: undefined
--   inf: undefined
--   resumeEditing: undefined
--   Selobj: undefined
--   oute: undefined
--   elmf: undefined
--   numval: undefined
--   oute2: undefined
--   ino: undefined
--   allav: undefined
>> MAXScript Rollout Handler Exception: -- Type error: Call needs function or class, got: undefined <<

anyone know why? I’m using max 6, but I don’t think that should make any difference…

Thanks in advance…

Hey Loocas, sorry I have not checked this thread for a while. I believe the error could be that suspendEditing() and resumeEditing() is not available in max 6. Try to remove those lines and see if it works. The modifier panel will flicker like crazy though. I did a bit more work on this script anyway since I posted it here. I will take a look at it once more later and post an updated version.

cheers,
CML

Rivendale, I gotta thank you for this great script, superior time saver.

You just saved a lot of my time! I’m in the middle of one fx job and was desperately splitting things up manually, because have not found any decent script that does the results I need. My own scripting is infernal = none. This surely takes me a bit further in my task, THANK YOU!

Keep em coming!

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
--**********************************************************



You know, I really want to try out rivendales script, but I cant get it to work… When I press the “split” button i get this message: – type error: Call needs function or class, got undefined. Whats wrong??

–Lassjus–

Page 3 / 5