Notifications
Clear all

[Closed] Pipes Generator

so i like to allow my algorithm go on ‘taken’ cells if it makes new and possible connection (means one of these five shapes).

So if it is possible to make another (pipe segment) you’d like it to pick randomly from any of the pictured pipes to create?

This is where I was going with the UI. I wanted to give the users the ability to quickly create controls for the pipes. If you have multiple objects selected and you hit “Segment it will place the controls accordingly. I’ve gotta add the “naming on the controls as well as make it properly link each object so the proper control. When users hit “End” it will create a control for that particular piece of geometry. At the same time that geometry rigged with “End” will be the designated piece that get’s used for the end cap when a pipe has stopped growing.

Any ideas or improvements you guys may have feel free to mention. I want this to be user friendly for all. Well as much as it can be.


try(destroyDialog rlPipeGen)catch()
rollout rlPipeGen "Pipes Generator"
(
	fn fnObjectsToLayer str nodes: = ( --Places given nodes on supplied layer name
		if nodes == unsupplied do nodes = #()--objects as array
			
		layers = for i = 1 to LayerManager.count - 1 collect (LayerManager.getLayer i).name
		
		theLayer = if findItem layers str != 0 then (LayerManager.getLayerFromName str)else(layermanager.newLayerFromName str)
		
		for obj in nodes do (theLayer.addNode obj)
	)
	
	fn fnCreatePipeRigCtrls ctrlSize:(units.decodevalue ".5m") end:false layerName: = (		
		local rigCtrls = #()
		
		pStart = if selection.count >=1 then [selection.center.x,selection.center.y,selection.min.z] else [0,0,0]
		pEnd = if selection.count >=1 then [selection.center.x,selection.center.y,selection.max.z] else [0,0,ctrlSize*3]
			
		append rigCtrls (ctrlStart = point cross:true box:true centerMarker:false axisTripod:false wirecolor:green size:ctrlSize pos:pStart)
		if not end do (append rigCtrls (ctrlEnd = point cross:true box:false centerMarker:false axisTripod:true wirecolor:yellow size:ctrlSize parent:ctrlStart pos:pEnd))
		
		--add to layer
		fnObjectsToLayer layerName nodes:rigCtrls
	)
	
	groupbox gpPipeRigCtrls "Pipe Rig Controls:" width:200 height:95 pos:[10,5]
		label lbGenRigCtrl "Create controls:" pos:[20,30]
		button btnGenSegment "Segment" height:24 width:55 pos:[110,25]
		button btnGenEnd "End" height:24 width:35 pos:[165,25]
		label lbCtrlSize "Control size:" pos:[20,55]
		spinner spCtrlSize "" width:90 pos:[110,55] range:[.1,9999999,(units.decodevalue ".5m")] type:#worldUnits
		label lbAddToLayer "Add to layer:" pos:[20,75]
		edittext etLayerName "" width:95 pos:[106,75] text:"Pipe_ctrls"
	button btnInstructions "?" width:30 height:30 pos:[10,260] 
	button btnGenPipes "Generate Pipes" width:170 height:30 pos:[40,260]
	
	on btnGenSegment pressed do (fnCreatePipeRigCtrls ctrlSize:spCtrlSize.value end:false layerName:etLayerName.text)
	on btnGenEnd pressed do (fnCreatePipeRigCtrls ctrlSize:spCtrlSize.value end:true layerName:etLayerName.text)
)
createDialog rlPipeGen 220 300 style:#(#style_SysMenu, #style_ToolWindow)

I’m adding in some template rigs for users to easily use as a base guide to then create pipes and properly have them rigged and ready for mass generating.

Right now all that works is the Pipe Rig Templates section. When you click a button it creates the controls with the properly linking for later generation. If you have a selection of objects it will properly align and link the corresponding objects as well. You can select multiple objects as well. Check it out. The buttons will be replaced with icons down the road.


try(destroyDialog rlPipeGen)catch()
rollout rlPipeGen "Pipes Generator"
(
	local grpRig = 25
	
	fn fnObjectsToLayer str nodes: = (--Places supplied nodes to given layer
		if nodes == unsupplied do nodes = #()
			
		layers = for i = 1 to LayerManager.count - 1 collect (LayerManager.getLayer i).name
		
		theLayer = if findItem layers str != 0 then (LayerManager.getLayerFromName str)else(layermanager.newLayerFromName str)
		
		for obj in nodes do (theLayer.addNode obj)
	)
	
	fn fnGetParents nodes: = ( --get top most parent node
		if nodes == unsupplied do nodes = #()
		local parentNodes = #()
		
		for i = 1 to nodes.count do (
			o = nodes[i]
			if isvalidnode o do (--Check if the node passed to the function is a valid node.
				while o.parent != undefined do o = o.parent --Loop through the hierarchy until the current node's parent is undefined (i.e. rootnode)
				append parentNodes o --Return the rootnode
			)
		)
		makeUniqueArray parentNodes
		parentNodes
	)
	
	fn fnEndCtrl parent pos = (ctrl = point name:(uniqueName "pipeEnd_") cross:true box:false centerMarker:false axisTripod:true wirecolor:yellow size:rlPipeGen.spCtrlSize.value parent:parent pos:pos)
	
	fn setNodeWorldRotation theNode theRot = (in coordsys (transmatrix theNode.transform.pos) theNode.rotation = theRot)--Sets rotation of objects in world space
	
	fn fnCreatePipeRig type:1 layerName: = (		
		local rigCtrls = #()
		ctrlSize = rlPipeGen.spCtrlSize.value
		
		pStart = if selection.count >=1 then [selection.center.x,selection.center.y,selection.min.z] else [0,0,0]
 		pEnd = if selection.count >=1 then [selection.center.x,selection.center.y,selection.max.z] else [0,0,ctrlSize*3]
		tmMax = if selection.count >=1 then [selection.max.x,selection.max.y,selection.max.z] else [ctrlSize*3,ctrlSize*3,ctrlSize*3]
		tmMin = if selection.count >=1 then [selection.min.x,selection.min.y,selection.min.z] else -[ctrlSize*3,ctrlSize*3,ctrlSize*3]
			
		/*	Template Rigs = 1. Straight , 2. T Shaped 90° , 3. T Shaped , 4. Cross , 5. 90° Curve Corner , 6. 45° Curve Corner , 7. Fork , 8. Y Shaped , 9. End Cap */
 		append rigCtrls (ctrlStart = point name:(uniqueName "pipeStart_") cross:true box:true centerMarker:false axisTripod:false wirecolor:green size:ctrlSize pos:pStart) --required minimum helper
		
		if type == 1 do ( --Straight
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart pEnd)
		)
		if type == 2 do ( --T Shaped 90°
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart pEnd)
			append rigCtrls (ctrlEndB = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z/2])
			setNodeWorldRotation ctrlEndB (eulerangles 0 -90 0)
		)
		if type == 3 do ( --T Shaped
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z])
			append rigCtrls (ctrlEndB = fnEndCtrl ctrlStart [tmMin.x,pStart.y,pEnd.z])
			setNodeWorldRotation ctrlEndA (eulerangles 0 -90 0)
			setNodeWorldRotation ctrlEndB (eulerangles 0 90 0)
		)
		if type == 4 do ( --Cross
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart pEnd)
			append rigCtrls (ctrlEndB = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z/2])
			append rigCtrls (ctrlEndC = fnEndCtrl ctrlStart [tmMin.x,pStart.y,pEnd.z/2])
			setNodeWorldRotation ctrlEndB (eulerangles 0 -90 0)
			setNodeWorldRotation ctrlEndC (eulerangles 0 90 0)
		)
		if type == 5 do ( --90° Curve Corner
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z])
			setNodeWorldRotation ctrlEndA (eulerangles 0 -90 0)
		)
		if type == 6 do ( --45° Curve Corner
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z])
			setNodeWorldRotation ctrlEndA (eulerangles 0 -45 0)
		)
		if type == 7 do ( --Fork
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart pEnd)
			append rigCtrls (ctrlEndB = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z])
			setNodeWorldRotation ctrlEndB (eulerangles 0 -45 0)
		)
		if type == 8 do ( --Y Shaped
			append rigCtrls (ctrlEndA = fnEndCtrl ctrlStart [tmMax.x,pStart.y,pEnd.z])
			append rigCtrls (ctrlEndB = fnEndCtrl ctrlStart [tmMin.x,pStart.y,pEnd.z])
			setNodeWorldRotation ctrlEndA (eulerangles 0 -45 0)
			setNodeWorldRotation ctrlEndB (eulerangles 0 45 180)
		)
		if type == 9 do () -- End Cap
		
		--Make sure to link all parent nodes in selection to the pipe start control
		for o in (fnGetParents nodes:(selection as array)) do o.parent = ctrlStart 
		
 		--Add all pipe rig controls to desired layer
 		fnObjectsToLayer layerName nodes:rigCtrls
		
	)
	
	groupbox gpPipeRigCtrls "Pipe Rig Templates:" width:200 height:140 pos:[10,5]
 		label lbCtrlSize "Size:" pos:[20,grpRig]
		spinner spCtrlSize "" width:90 pos:[110,grpRig] range:[.1,9999999,(units.decodevalue ".5m")] type:#worldUnits
 		label lbAddToLayer "Add to layer:" pos:[20,grpRig+20]
 		edittext etLayerName "" width:95 pos:[106,grpRig+20] text:"Pipe_ctrls"
		button btnPipeA "St8" height:30 width:30 pos:[20,grpRig+45] tooltip:"Straight pipe includes 1 open end"
		button btnPipeB "T 90°" height:30 width:30 pos:[57,grpRig+45] tooltip:"'T' shaped pipe rotated 90° includes 2 open ends"
		button btnPipeC "T" height:30 width:30 pos:[94,grpRig+45] tooltip:"'T' shaped pipe includes 2 open ends"
		button btnPipeD "X" height:30 width:30 pos:[131,grpRig+45] tooltip:"Cross shaped pipe includes 3 open ends"
		button btnPipeE "90°" height:30 width:30 pos:[168,grpRig+45] tooltip:"Corner curve 90° angle inlcudes 1 open end"
		button btnPipeF "45°" height:30 width:30 pos:[20,grpRig+82] tooltip:"Corner curve 45° angle includes 1 open end"
		button btnPipeG "Fork" height:30 width:30 pos:[57,grpRig+82] tooltip:"Straight pipe which forks into another pipe includes 2 open ends"
		button btnPipeH "Y" height:30 width:30 pos:[94,grpRig+82] tooltip:"Y shaped pipe includes 2 open ends"
		button btnPipeI "End" height:30 width:30 pos:[131,grpRig+82] tooltip:"This object gets used as the end cap to any pipe"
	
	button btnInstructions "?" width:30 height:30 pos:[10,260] 
	button btnGenPipes "Generate Pipes" width:170 height:30 pos:[40,260]
	
	on btnPipeA pressed do (fnCreatePipeRig type:1 layerName:etLayerName.text)
	on btnPipeB pressed do (fnCreatePipeRig type:2 layerName:etLayerName.text)
	on btnPipeC pressed do (fnCreatePipeRig type:3 layerName:etLayerName.text)
	on btnPipeD pressed do (fnCreatePipeRig type:4 layerName:etLayerName.text)
	on btnPipeE pressed do (fnCreatePipeRig type:5 layerName:etLayerName.text)
	on btnPipeF pressed do (fnCreatePipeRig type:6 layerName:etLayerName.text)
	on btnPipeG pressed do (fnCreatePipeRig type:7 layerName:etLayerName.text)
	on btnPipeH pressed do (fnCreatePipeRig type:8 layerName:etLayerName.text)
	on btnPipeI pressed do (fnCreatePipeRig type:9 layerName:etLayerName.text)
	--on btnGenSegment pressed do (fnCreatePipeRigCtrls ctrlSize:spCtrlSize.value end:false layerName:etLayerName.text)
	--on btnGenEnd pressed do (fnCreatePipeRigCtrls ctrlSize:spCtrlSize.value end:true layerName:etLayerName.text)
)
createDialog rlPipeGen 220 300 style:#(#style_SysMenu, #style_ToolWindow)

Hi Joker,

when i evaluate your script i got the message “unable to decode value.5m”
when i change to “.5m” to “0.5m” everything is fine…

a pipe generation script where you could define a start and end point would be a really great idea!

Cheers Tommy

I had an image issue posted here but I’ve got that figured out now. Update coming soon.

Yeah, I wasn’t able to get that code working either. Just looking at this though… seems like quite a pain. Have you looked into using Base64 encoded strings? Lonerobot had a nice article on it: http://lonerobot.net/?p=314

I’ll fix that issue

Joker, what was that image issue Id like to see it so i know how you fixed it

I was trying to embed the images into the script using the Base64 encode method but it was not worth doing right now, so for the time being I’ve just attached images to the scripts folder which will have to get placed by the user when downloading. Once I finish the actual workings of the script I will then devote a bit more time to the icons and getting the base64 stuff implemented and working. I figured right now the icons are not what’s important.

Page 4 / 12