Notifications
Clear all

[Closed] Pipes Generator

Superb Denis. I sadly don’t have a computer near me most of today as I’ll be spending it playing halo 4 for the holiday break. I look forward to messing with your snippet first thing when I get home tonight.

one comment… max allows probably any long hierarchy chain, but some tools are limited. for example mxs recursive function (like getchirdren) will crash on ~100-300th recursion. we did some tests and showed results on this forum.

Pretty cool script! Do you guys have pics of it in action using some pipe models?

1 Reply
(@jokermartini)
Joined: 11 months ago

Posts: 0

That is an interesting note to be aware of. Thank you for that. I shall have an update here on Monday with some new controls and fixes.

A friend has suggested adding the ability to grow pipes from the start position to a targeted point helper position/end.

His method to do this was .

Have each pipe link rotate around 0 to 359 and check the distance between the end dummy of the pipe link and target object (mid or end) at each rotation and store the best value

I was curios to know if anyone else I ideas on ways of doing something like this.

John

i have a different concept. unfortunately i can’t show it earlier than Monday. it’s based on 3D virtual grid. every time when we add new pipe segment we know what cell were taken. so… on Monday i will try to show something.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

here is my idea based on 3D grid. as you see the system never takes already taken cells.


  try(destroydialog PipeGen) catch()
  rollout PipeGen "Pipe Generator" width:200
  (
  	fn roundFloat d pre:1.0 =
  	(
  		local d = (d as float)/pre
  		local v = if (d - (v1 = floor d)) > ((v2 = ceil d) - d) then v2 else v1 
  		v*pre
  	)
  	fn roundPoint3 p = 
  	(
  		p.x = roundFloat p.x
  		p.y = roundFloat p.y
  		p.z = roundFloat p.z
  		p
  	)
  
  	button begin_bt "Begin" width:190 align:#left offset:[-8,0]
  	label info_lb "" --across:2
  	--spinner limit_sp type:#integer range:[0,5,3] fieldwidth:44 align:#right offset:[4,-1]
  	button grow_bt "Grow" width:190 align:#left offset:[-8,0]
  	
  	local size = 1.0
  	local grid_size = 100
  	local block, joint
  	local ends = #(), joints = #()
  	local shifts = #([-1,0,0],[1,0,0],[0,-1,0],[0,1,0],[0,0,-1],[0,0,1])
  	
  	fn getSplits = 
  	(
  		k = random 1 100
  		case of
  		(
  			(k < 85): 1 
  			(k < 94): 2 
  			(k < 98): 3 
  			(k < 100): 4 
  			 default: 5
  		)
  	)
  	
  	local taken = #()
  	fn takePoint p = 
  	(
  		d = p + grid_size
  		if taken[d.x] == undefined do taken[d.x] = #() 
  		if taken[d.x][d.y] == undefined do taken[d.x][d.y] = #{}
  		taken[d.x][d.y][d.z] = on
  	)
  	fn isFree p limit:0 = 
  	(
  		d = p + grid_size
  		taken[d.x] == undefined or taken[d.x][d.y] == undefined or not taken[d.x][d.y][d.z]
  	)
  	fn getAvailable p =
  	(
  		for s in shifts where isFree (p+s) collect s
  	)
  	on begin_bt pressed do undo "Begin Pipe" off
  	(
  --		seed 0
  		delete objects
  		block = box width:(size/4) length:(size/4) height:size widthsegs:1 lengthsegs:1 heightsegs:1 wirecolor:orange showFrozenInGray:off isselected:on
  		joint = box width:(size/2) length:(size/2) height:(size/2) widthsegs:1 lengthsegs:1 heightsegs:1 wirecolor:yellow showFrozenInGray:off 
  		centerpivot joint
  		block.objectoffsetpos -= [0,0,1]
  		taken = #()
  		takePoint block.center
  		ends = #(block)
  		joints = #(joint)
  		info_lb.text = "1 / 1"
  		gc()
  	)
  	fn getEnds = for node in objects where not node.isFrozen collect node
  	on grow_bt pressed do undo "Grow Pipe" on
  	(
  		max create mode
  		new = #()
  		for b in selection do 
  		(
  			added = off
  			turned = off
  			for k=1 to getSplits() do
  			(
  				ss = getAvailable b.pos 
  				d = roundPoint3 b.dir
  --				format "% %
" d ss
  				if finditem ss d != 0 do for i=1 to 20 do append ss d
  				if ss.count > 0 then
  				(
  					s = ss[random 1 ss.count]
  					if s != d do
  					(
  						turned = on
  						j = instance joint pos:b.pos dir:d showFrozenInGray:off
  						append joints j
  					)
  					p = roundPoint3 (b.pos + s)
  					d = roundPoint3 (p - b.pos)
  
  					added = on
  					n = instance block pos:p dir:d showFrozenInGray:off
  					append new n
  					takePoint p
  				)
  				else added = on
  			)
  			if not added do append new b
  		)
  		objects.wirecolor = green
  		joints.wirecolor = yellow
  		new.wirecolor = orange
  		select new
  		info_lb.text = objects.count as string + " / " + new.count as string
  		completeredraw()
  	)
  )
  createdialog PipeGen
  

every time you can change selection to start new branch

I see, this is great. I will have to play around with this a bit more and dive into the code a bit to see what you’re doing. I’ll then mix the previous version I had posted with this one you posted and the two can then have a baby pipe generator! Which should yield some very cool results.

I’m going to see if I can come up with a cleaner way of giving users the ability to make custom pipes and easily add them to the system.

i’ve checked some ‘plumbing’ resources…
there are five standard pipe connectors. which are:

Alright,
That is good to know. I’ll probably just include some super basic pipes like the ones your have shown in the picture posted within the script. So if the users want to use them as a base they can. But I’m also going to make it possible for users to create curly twisting fun pipes.

I’ll post my progress throughout the day as I get freetime to show the direction I’m going with the UI and tool concept. That way if there are any ideas we can easily make those adjustments early on.

Page 3 / 12