Could any one write a script: to create a sponge (a new idea)


Hi all, and to rdg:
I had a new idea to create a sponge-like object. Again, need help to realize this idea:
last time I proposed to creat a dot in a defined space, the dot flying around, and we use the trace of the dot to create a sponge-like structure. Then Mr. rdg create a very nice script like the idea.

Thanks for rdg insperation, now I had a new idea in my mind:
First, in a defined space, create many dot (or vertexs), each dot with similiar distance but not exactly the same. Then create spline from two of the vertexs, for each vertexs create a spline. But not all vertexs are connect to each other, set a thresold of distance for vertexs connection. Therefore, for each vertexs, only have few (maybe 5-7) to others vertexs. Finally, set all the spline with mesh, and add noise to the mesh. The final product would be very similar to a real world sponge.

Sorry for my English, I hope you understand my idea. So anyone know how to do it by scripting?


                                            Hammer B. Chen



I think I understand your approach.
I allready had the idea of having the option for multiple strings inside the sponge-thing.
Testing all vertices for a distance against all other vertices could be really slow …
But a VolumeSelect could help.

I will give it a try.



Hi everyone,

It seems to me you could just do exctly as you’ve before, and then select and delete a random selection of segments from your newly created shape, and this would leave you with multiple strings inside your volume like what you’ve described.
And also, as RDG pointed out before, if you want to use a non geometric volumne (ie: any mesh) you could use my laserbeam script from the CGTalk challenge 007, and then select and delete random segments.[u][/u]

Please tell me if I miss-understood!



deleting random segements is a good idea.
having points connected to point with a given distance is not only a more “engineeric” approach, it will give you tendril like dead ends and last but not least will take much much longer

I want to implement all three apprach, so we can see the differneces.
Also the LaserWars-Genesis-Option needs to be implemented finally.

I will just replace my soon to crash harddrive …



Hmmm…deleting random segements will certainly looks different to vertex-linking approach.

For the vertex-linking approach, tendril like dead might give some realism to the sponge. So the three different or combination will represent different species of sponge.:slight_smile:


Hey Hammer,

I’d love to see some pics of these sponges to get a good idea about what you want to create, got any handy?





I am trying to delete random segements. But somehow it won't work.

After creating the sponge I collect random segments and try to delete them. The selection stuff works but no segments are deleted?

   max modify mode
   select sponge
   for i=1 to (numSegments sponge 1) do (
    if (random 0 100) < genPerc_spn.value then (
     append segArray i
   -- print segArray
   setSegSelection sponge 1 segArray
   updateShape sponge
   splineOps.delete sponge
The genesis options are:
continuous: one thing made of one string

rdg: the mysterious value is percentage of the object desitity and controlls max string length. after max string length is reached a new string is added
j_man: one thing made of one string. then each segemtn is deleted by chance of the mysterious value …
Hammer: not implemented yet.

another idea: assign different MatIds to the resulting splines/segments and generate a Multi/Subobject-Material with differnet Hues or Saturations.

The Question is: How to delete those segements ?



this snippet creates a spline selects random segements and deletes them:

	sponge = SplineShape pos:[0,0,0]
	addnewspline sponge
	for i=1 to 10 do (
		addknot sponge 1 #corner #line [(random 0 25), (random 0 25), (random 0 25)]
	updateShape sponge
	for i=1 to (numSegments sponge 1) do (
		if (random 0 100) < 50 then (
			append segArray i
	max modify mode
	select sponge
	setSegSelection sponge 1 segArray
	splineOps.delete sponge

But in my thing-o-string the segements aren’t deleted.

Anybody knows why?




Strange. I wrote this to test, and it works.

s=addnewspline spl
for i=1 to 50 do addknot spl s #corner #line [i*10,(random 0 100),0]
updateshape spl
for i=1 to 10 do (setsegselection spl 1 #((random 1 50)) keep:true)
max modify mode
select spl
splineops.delete spl

It seems though, when placed inside brackets (as your test rig is) or called in a function, it doesn’t. Sorry, I cannot explain why.

fn deleteseg splshp=
max modify mode
select spl
splineops.delete splshp
s=addnewspline spl
for i=1 to 50 do addknot spl s #corner #line [i*10,(random 0 100),0]
updateshape spl
for i=1 to 10 do (setsegselection spl 1 #((random 1 50)) keep:true)
deleteseg spl

How about adding a deletespline modifier to the stack?


It’s probably an update problem.
If you don’t return in subobjectlevel=0, the obliteration occurs.
I’m not familiar with the Splines.


prettyPixel, j_man,

not returning to subobjectlevel=0 works in j_man’s example function.
But in my script the deletion still doesn’t happen.

I never heard of the deleteSpline Modifier before - but it does what I need.
And there is no documentation in the MAXreference … anyway:

stay tuned for more sponges !
**: j_man genesis working
**: enhanced rdg genesis



Maybe it’s a bug. It’s probably a question for Larry or Bobo anyway. Why don’t you post it at the discreet ah-hem AME board.

Anyway, there is always another way!

Well done,



Hi all, and to rdg:

I had another aproach in mind, however maybe need not by scripting:
1)create a solid object, so the object have many vertexs inside its body.
2)apply a lattice modifer to the object (turn on the stick but not ball option)
3)apply a noise modifer

But the problem is: how could I creat a solid obect with a scattered vertexs inside its body.

P.S: I will upload my “real sponge” pictures later.




I modify my idea, and this time almost create the things I want:
1)create a super spray particle
2)set the particle geometry to sphere
3)ajust the size of the sphere and life…this superspray particle will be the body of the sponge, let the particle bump to each other.
4)create a compund object–mesher, select the superspray that we previous create
5)apply a lattice modifer to the mesher
6)in the lattice modifer layout, turn on stick only not ball, change the size of the stick smaller.

that it, but still this method creat many hole and intersecting meshs problem, anyone have suggestion?





Just post some great links about 3d sponge (search keyword: liquid foams, Surface Evolver simulation)

I wish those can inspire you to script something like that! :thumbsup:


Interesting thread :slight_smile:

I am also interested by the creation of structures, particularly the structures in honeycomb.
One moment ago, I had written a script to do that by modifying a plan but the method was limited.
The idea of structure inspired to me an another concept:
The structure is formed gradually. It extends gradually. I adapted the principle of the structures in honeycomb in the script which follows.
After that, I added random factors to move the vectors before they connect itself to the others. That allows to create structures like sponges.
Here is my participation.

rollout honeycombRollout "honeycomb"
group "honeycomb"
	spinner numberLinks_osd "number links: " range:[3,2000,400] type:#integer scale:1.0 fieldWidth:40
	spinner nodeSize_osd "link size: " range:[1.0,10000.0,10.0] type:#float scale:1.0 fieldWidth:40
	spinner nodeLinks_osd "links by node: " range:[1,8,3] type:#integer scale:1.0 fieldWidth:40
	spinner varLength_osd "length var.: %" range:[0.0,250.0,40.0] type:#float scale:0.1 fieldWidth:40
	spinner varAngle_osd "angle var.: deg" range:[0.0,360.0,40.0] type:#float scale:0.1 fieldWidth:40
	spinner weldZone_osd "weld zone: %" range:[0.0001,75.0,60.0] type:#float scale:0.5 fieldWidth:40
	button calculate_osd "create"
group "presets"
	dropdownlist preset_osd "" items:#("studious bees","sponge","oh no") selection:2 height:4
label lb1 "by Olivier Vandecasteele"
label lb2 "email:"

struct geomStructure
	fn count = return node.count,
	fn addNode coord = ( append links #(); append baseVector [0,1,0]; append node coord; append alive node.count; return node.count ),
	fn getPos idx = return node[idx],
	fn setPos idx coord = node[idx]=coord,
	fn getLink idx = return links[idx],
	fn setLink idx idxOtherNode = ( if (idx<=node.count and idxOtherNode<=node.count) then (append links[idx] idxOtherNode; append links[idxOtherNode] idx; append uniqueLinks #(idx,idxOtherNode)) else false ),
	fn getBaseVector idx = baseVector[idx],
	fn setBaseVector idx v = baseVector[idx]=v,
	fn getBasePlane idx = basePlaneNormal[idx],
	fn setBasePlane idx v = basePlaneNormal[idx]=v,
	fn addVector fromNode v p =
		append baseVector -v
		append basePlaneNormal p
		append links #()
		append node (node[fromNode]+v)
		append alive newNode
		append links[fromNode] newNode
		append links[newNode] fromNode
		append uniqueLinks #(fromNode,newNode)
		return newNode
	fn getUniqueLinksCount = return uniqueLinks.count,
	fn getUniqueLinks idx = return uniqueLinks[idx],
	fn isAlive idx = alive[idx],
	fn killLife idx = alive[idx]=false

fn firstAlive structure =
	for currentNode=1 to numberNodes do
		if structure.isAlive currentNode then exit
	return count

fn existNodeInZone structure pos delta =
	for currentNode=1 to numberNodes do
		p=structure.getPos currentNode
		if ((abs(pos.x-p.x))<delta)and((abs(pos.y-p.y))<delta)and((abs(pos.z-p.z))<delta) do (existAtPos=currentNode;exit)

fn randomVector2Dvariation theVector varLength varAngle lengthToConform =
	newLength=random (lengthToConform-var) (lengthToConform+var)
	theVector*=(newLength/(length theVector))
	theVector*=quat (random -(varAngle/2.0) (varAngle/2.0) ) [0,0,1]

fn growNode structure idx share =
	rotShare=360.0/(share as float)
	theBaseVector=structure.getBaseVector idx
	thePlaneNormal=structure.getBasePlane idx
	lengthToConform=length (structure.getBaseVector 1)
	for shareIdx=1 to (share-1) do
		theBaseVector*=quat rotShare thePlaneNormal
		theRealVector=randomVector2Dvariation theBaseVector (varLength_osd.value/200.0) varAngle_osd.value lengthToConform
		pos=(structure.getPos idx)+theRealVector
		delta=(weldZone_osd.value/100.0)*(length theBaseVector)
		otherNode=existNodeInZone structure pos delta
		if otherNode!=0
			then (
				currentLinks=structure.getLink idx
				if (findItem currentLinks otherNode)==0 do
					structure.setLink idx otherNode
					p=structure.getPos otherNode
					structure.setPos otherNode ((pos+p)/2.0)
			else structure.addVector idx theRealVector thePlaneNormal
	structure.killLife idx

fn createGeom structure =
	obj=SplineShape pos:[0,0,0]
	for idx=1 to count do
		thisLink=structure.getUniqueLinks idx
		splineIdx=addNewSpline obj
		addknot obj splineIdx #corner #line ((structure.getPos thisLink[1])*nodeSize_osd.value)
		addknot obj splineIdx #corner #line ((structure.getPos thisLink[2])*nodeSize_osd.value)
	updateShape obj
	return obj

on calculate_osd pressed do
	myStructure.addVector 1 [0,1,0] [0,0,1]
	while myStructure.getUniqueLinksCount()<(numberLinks_osd.value) do
		thisNode=firstAlive myStructure
		growNode myStructure thisNode nodeLinks_osd.value
		if securityCounter>numberLinks_osd.value*8 do ((messageBox("the weld value is too high
program stopped") title:"honeycomb warning");exit)
	obj=createGeom myStructure

on preset_osd selected idx do
	case idx of
		1: (
		2: (
		3: (

try (closerolloutfloater honeycombFloater)catch()
honeycombFloater = newRolloutFloater "honeycomb" 162 260
addRollout honeycombRollout honeycombFloater rolledUp:false

Note: all routines are not yet optimized.

As soon as I would have time, I will adapt this principle in volume.


Here is a screenshot


very cool prettypixel very cool. Can’t wait to see a 3D version!!!


very cool indeed!

I am back from short vacation and will read the links.



To rdg and you all:
Here are the picture of my “sponge”, actually its not a sponge, it is one kind of vegetable–melon like vegetable. We used to use that to wash our body in the old day in Taiwan. We dry the melon under the sun for many days, then the remain are the “bone” of the melon.
Anyway, I am really enjoy this kind of modeling, and really happy to provide idea and discuss in this forum.

I also start another thread in cgtalk:
MasterBercon said the effect I want to creat was called “Implicit Surfaces”. I think it is another direction to creat a sponge.