Pipes Generator

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  11 November 2012
Pipes Generator

So I've search around on the inter-web and didn't find to many great pipe generator tools and on top of that I've been unable to find any good ones fore free. I'm going to start a thread here on cgtalk where I will begin to build a develop and free and openly coded tool. Anyone is more than welcome to share their input and ideas as I'm always open to making things as good as we can. I've started a very rough base so far. Take a look.
The download zip is needed.

Right now each pipe is being randomly selected when being created next which is purely for the purpose of quick testing reasons. I will eventually give the control for users to pick which pipe is to be created next as well as having the option to just randomly grow pipes.


try(destroyDialog rlCreate)catch()
rollout rlCreate "Boxes"
(
	local cs = $SmallCornerCtrl
	local s = $SmallCtrl
	local m = $MediumCtrl
	local t = $LargeCtrl
	
	button btnCreate "Create"
	
	on btnCreate pressed do (
		if selection.count >= 1 then
		(
			ends = #()
			for o in selection where classof o == Point AND findString o.name "End" != undefined do 
			(
				pipes = #(cs,s,m,t)
				p = pipes[random 1 pipes.count]
				
				local newPipes
				if not (maxOps.cloneNodes p expandHierarchy:true newNodes:&newPipes) then throw "Not good!"
				pipeCtrl = newPipes[1]
				
				pipeCtrl.transform = copy o.transform
				
				for c in newPipes where classof c == Point AND findstring c.name "End" != undefined do append ends c
			)
			select ends
		)
		else
		(
			pipes = #(cs,s,m,t)
			p = pipes[random 1 pipes.count]
				
			ends = #()
			local newPipes
			if not (maxOps.cloneNodes p expandHierarchy:true newNodes:&newPipes) then throw "Not good!"
			pipeCtrl = newPipes[1]
			
			pipeCtrl.pos = [0,0,0]
			
			for c in newPipes where classof c == Point AND findstring c.name "End" != undefined do append ends c
			select ends
		)
	)
	
)
createDialog rlCreate


Thanks.
Attached Files
File Type: zip 02.zip (27.5 KB, 133 views)
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com

Last edited by JokerMartini : 11 November 2012 at 12:45 AM.
 
  11 November 2012
Update

Rough but working!!

Added parenting so you can rotate pipes and effect the pipes which are growing from that particular one.


try(destroyDialog rlCreate)catch()
rollout rlCreate "Boxes"
(
	local cs = $SmallCornerCtrlStart
	local s = $SmallCtrlStart
	local m = $MediumCtrlStart
	local t = $LargeCtrlStart
	local cros = $CrossCtrlStart
	
	button btnCreate "Create"
	
	on btnCreate pressed do (
		if selection.count >= 1 then
		(
			ends = #()
			
			for o in selection where classof o == Point AND findString o.name "End" != undefined do 
			(
				pipes = #(cs,s,m,t,cros)
				p = pipes[random 1 pipes.count]
				
				maxOps.cloneNodes p expandHierarchy:true cloneType:#copy actualNodeList:&refPipes newNodes:&newPipes
				pipeCtrl = newPipes[1]
				
				pipeCtrl.transform = copy o.transform
				
				--link children
				for p in newPipes where classof p == circle AND findString p.name "Start" !=undefined do p.parent = (o.parent.parent)
				
				for c in newPipes where classof c == Point AND findstring c.name "End" != undefined do append ends c
			)
			select ends
		)
		else
		(
			pipes = #(cs,s,m,t)
			p = pipes[random 1 pipes.count]
				
			newPipes = #()
			maxOps.cloneNodes p expandHierarchy:true cloneType:#copy actualNodeList:&refPipes newNodes:&newPipes
			pipeCtrl = newPipes[1]
			
			pipeCtrl.pos = [0,0,0]
			
			ends = for c in newPipes where classof c == Point AND findstring c.name "End" != undefined collect c
			select ends
		)
	)
	
)
createDialog rlCreate
Attached Files
File Type: zip 02.zip (30.1 KB, 42 views)
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
search this forum. I am pretty sure i remember a pipe generator maxscript project some time ago
 
  11 November 2012
Yeah I had come across it already but in my mind it was not as good as it could be. That is why I'm going to take the concept of pipe generation and make it more user friendly and much more stable.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Originally Posted by JokerMartini: Yeah I had come across it already but in my mind it was not as good as it could be. That is why I'm going to take the concept of pipe generation and make it more user friendly and much more stable.

there is a little addition to your code:

     local rots = #(-90,0,90,180)
 	on btnCreate pressed do (
 		if selection.count > 0 then
 		(
 			ends = #()
 			
 			for o in selection where classof o == Point AND findString o.name "End" != undefined do 
 			(
 				pipes = #(cs,s,m,t,cros)
 				p = pipes[random 1 pipes.count]
 				
 				maxOps.cloneNodes p expandHierarchy:true cloneType:#copy actualNodeList:&refPipes newNodes:&newPipes
 				pipeCtrl = newPipes[1]
 				
 				pipeCtrl.transform = copy (prerotatez o.transform rots[random 1 rots.count])
 
 

Last edited by denisT : 11 November 2012 at 03:14 PM.
 
  11 November 2012
Very cool.

I was just going to add the random rotation to.
I'm going to start building out a UI and from there figure out a good way to make this more useable and give more options. Such as a preview and also the option of having .... auto generate pipes.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Controls?

Does anyone have any particular opinions on what type of controls they would like to have for this.

My ideas were:
1. Ability to use custom pipes.
2. Ability to Auto generate pipe system (grow)
3. Auto generate next pipe (with collision detection)
4. Option to generate specific pipes at any given time
5. Rotation Controls

As far as anything else that is all I can think up.
It would be cool to somehow grow pipes around and object but that may be for another day haha.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Pipes Generator Update

Hey guys. Things are coming together nicely here. In the newest update you'll see a UI now.
To try it out download the attached file and run the script. Once the script is up and running select all the objects in the scene and hit 'Add'. Then clear your selection and hit Generate.

Workings:
Based on the items selected in your list that controls which pipe type will be created. If you have more than one item selected it will randomly pick one of the pipes to create.

Things I'd like to add.
A control which drives the rotation of the pipes to limit their rotation. So users can grow pipes just on the X but with slight rotation say -30 to +30. If users use 360 then it will create it all directions.

Secondly I need to create a script which selects the last children of the entire pipe tree so users can quickly select the ends and continue building. In short a script which selects only children whom don't have children. But the initial selection before running the script could take place anywhere in the hierarchy.

Lastly I'd like to add some sort of preview option and raycast intersection detection system to help drive which pipe gets randomly generated. Which that would come an option where users could pick whether or not they care if it intersects.

I'd love to get some feedback and ideas from you guys. Thanks again for the help so far guys.


try(destroyDialog rlPipesGenerator)catch()
rollout rlPipesGenerator "Pipes Generator"
(
	local pipeList = #()
	local rots = #(-90,0,90,180)
	
	fn getChildren node = (
		local tmpArr = #()
		for c in node.children do
		(
			append tmpArr c
			join tmpArr (getChildren c)
		)
		tmpArr
	)

	fn checkStart node = (if classof node == Point AND findString node.name "Start" != undefined then true else false)
	
	fn checkEnd node = (
		children = getChildren node
		endNodes = for o in children where classof o == Point AND findString o.name "End" != undefined collect o
		if endNodes.count >= 1 then true else false	
	)
	
	fn getEnds arr = (
		local tmpArr = #()
		tmpArr = if arr.count >= 1 then (for o in arr where classof o == Point AND findString o.name "End" != undefined collect o) else #()
		tmpArr
	)		
	
	fn fnAddItmsLst lst arr = ( -- add Objects to list if they meet requirements
		curSel = getCurrentSelection() as array
		tmpArr = for p in curSel where (checkStart p) AND (checkEnd p) collect p
		
		if tmpArr.count >= 1 do
		(
			for o in tmpArr do (appendIfUnique arr o)
			lst.items = for i in arr collect i.name -- update list with array
		)
	)
		
	fn fnRemoveItmsLst lst arr = ( -- remove objects from list
		local currSel = lst.selection
		for i = lst.items.count to 1 by -1 where currSel[i] do (deleteItem arr i)
		lst.items = for i in arr collect i.name -- update list with array
		lst.selection = #{}
	)
	
	label lbPipes "Available Pipes:" pos:[10,10]	
	multilistbox lstPipes "" items:#() width:140 height:10 pos:[10,30]
	button btnInfo "Info ?" height:20 width:60 pos:[150,30]
	button btnAdd "Add" height:58 width:60 pos:[150,50]
	button btnRemove "Remove" height:58 width:60 pos:[150,108]
	button btnGeneratePipes "Generate Pipes" width:200 height:30
	
	on btnInfo pressed do (
		infoMessage = stringStream ""
		format "%\n" "Items which are added to the list must meet the following requirements:" to:infoMessage
		format "\n%" "1. The object being added must be a Point Helper." to:infoMessage
		format "\n%" "2. The object's name must contain the word 'Start'." to:infoMessage
		format "\n%" "3. The object added must contain atleast one children 'Point Helper' object." to:infoMessage
		format "\n%" "4. The child object's names must contain the word 'End'." to:infoMessage
		format "\n\n%" "NOTE: There can be more than one child point helper object." to:infoMessage
		messagebox infoMessage
	)
	
	on btnAdd pressed do (fnAddItmsLst lstPipes pipeList)
	on btnRemove pressed do (fnRemoveItmsLst lstPipes pipeList)
	
	on btnGeneratePipes pressed do (
		
		if selection.count >= 1 then
		(
			prevEnds = getEnds (selection as array)
			newEnds = #()
			
			for o in prevEnds do (
				
				--Randomly choose a pipe based on list selection
				items = if (lstPipes.selection) != undefined then (lstPipes.selection) as array else 1
				idx = items[random 1 items.count]
				_pipe = pipeList[idx]
				
				maxOps.cloneNodes _pipe expandHierarchy:true cloneType:#copy actualNodeList:&refPipes newNodes:&newPipes
				pipeCtrl = newPipes[1]
				
				pipeCtrl.transform = copy (prerotatez o.transform rots[random 1 rots.count])
				
  				for p in newPipes where (checkStart p) do p.parent = o --link children
				
 				join newEnds (getEnds newPipes)
			)
			select newEnds
			
		)else(
			--Randomly choose a pipe based on list selection
			items = if (lstPipes.selection) != undefined then (lstPipes.selection) as array else 1
			idx = items[random 1 items.count]
			_pipe = pipeList[idx]
				
			maxOps.cloneNodes _pipe expandHierarchy:true cloneType:#copy actualNodeList:&refPipes newNodes:&newPipes
			pipeCtrl = newPipes[1]
			
			pipeCtrl.pos = [0,0,0]
			
			pipeCtrl.transform = (prerotatez  (matrix3 1) rots[random 1 rots.count])
			
			select (getEnds newPipes)
		)
	)
)
createDialog rlPipesGenerator 220 210 style:#(#style_SysMenu, #style_ToolWindow)
Attached Files
File Type: zip 05.zip (46.5 KB, 89 views)
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
if i would build anything using 'blocks' i do it by using containers. that will give me automatic updates and enabling of proxy display.
 
  11 November 2012
Making each pipe into a container? Seems like that would make it a bit harder to track the start and ends of the pipes though.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Originally Posted by JokerMartini: Making each pipe into a container? Seems like that would make it a bit harder to track the start and ends of the pipes though.

no difference. you can check selected container and use any object from its hierarchy to get a connection point.

collision detection... you really don't need it. if you use 'multiple of N' block size you can setup the 3d grid, and mark it's cells as taken every time when you generate a new piece. if cell on the way of growing is taken try to turn on free way or stop growing this branch (set some 'ending' piece for example).
 
  11 November 2012
Yeah I was thinking about adding an end cap piece to then help make sense of a pipe suddenly ending.

I'll have to look into the container stuff as its new to me and I've never even looked at it before.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Originally Posted by JokerMartini: I'll have to look into the container stuff as its new to me and I've never even looked at it before.

i think that the main goal of the pipe generator for you is to learn anything new. that's why i throw you containers...
 
  11 November 2012
Very true,
I'll look over it during the holiday break over the next few days and see what it's all about. Hopefully it contains the abilities to instance as I'm eventually going to add the option for geo to be copies or instances of the reference pipes. I'm going to implement a preview option as well which will be nice.

This is a fun little project to do, which can easily turn into something bigger.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
  11 November 2012
Originally Posted by JokerMartini: This is a fun little project to do, which can easily turn into something bigger.

i'm trying to play with every idea on this forum, and almost every one sooner or later comes to me and helps me in one of my tasks.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 05:39 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.