Pipe System


A 3dsMax-Tool written in MaxScript


2017 April 03 - Tommy Dräger


Pipe System is a script that lets you append different elements on each other. The script was originally designed for schoolar purposes. The task was to build a modular system out of pipe-elements from a local industrial area. To achieve this every element got its own root and extension-point where the elements stacks on each other. You simply build your pipesystem by clicking the listed buttons or you can use your own custom meshes.

Download: (presets included)

simply extract it inside the scripts folder of 3dsMax


PipeSystem.zip

Build arrangements with presets

Build arrangements with custom meshes

Hierarchically connected via dummies and points

PipeSystem GUI in 3dsMax


PipeSystemGUI.ms

rollout PipeSystem "PipeSystem v1.0"
(
	groupBox rdo_grp 	"Preset Diameter" 	pos:[8,80]		width:296 	height:48
	radioButtons rdo	""		 			pos:[32,102]	width:249 	height:16 		
							labels:#(	"60cm", 
										"30cm", 
										"20cm") 			
							default:1 	
							columns:3

	label footer		"(c) FenixFox®Studios 2017" 
											pos:[8,376]		width:296 	height:24	
	GroupBox cstm_grp	"Custom"			pos:[8,8]		width:296 	height:64
	pickButton ctm_btn 	"Pick Object" 		pos:[16,24] 	width:184 	height:40
	button ext_btn 		"Extend" 			pos:[208,24] 	width:88 	height:40
	groupBox ele_grp 	"Presets" 			pos:[8,136] 	width:296 	height:160
	button I_Pipe 		"I_Pipe" 			pos:[16,152]	width:88 	height:40
	button I_Cap 		"I_Cap" 			pos:[112,152] 	width:88 	height:40
	button I_Isolation 	"I_Isolation"		pos:[208,152] 	width:88 	height:40
	button L_Pipe_90_2 	"L_Pipe_90_2" 		pos:[16,200] 	width:88 	height:40	
	button L_Pipe_45_2 	"L_Pipe_45_2" 		pos:[112,200] 	width:88 	height:40
	button L_Pipe_90_4 	"L_Pipe_90_4" 		pos:[208,200] 	width:88 	height:40
	button L_Pipe_90_10 "L_Pipe_90_10" 		pos:[112,248] 	width:88 	height:40
	button L_Pipe_90_7 	"L_Pipe_90_7" 		pos:[16,248] 	width:88 	height:40
	button T_V_Hopper 	"T_V_Hopper" 		pos:[208,248] 	width:88 	height:40
	
	GroupBox rot_grp 	"Rotate" 			pos:[8,304] 	width:296 	height:64
	button rot_left 	"Rotate -90" 		pos:[16,320] 	width:136 	height:40
	button rot_right 	"Rotate +90" 		pos:[160,320] 	width:136 	height:40
		
	function append_element picked_ele force_delete =
	(
		print force_delete
		
		--	check whether the extensionobject got an own parent and child!
		if 	picked_ele.parent			== undefined OR 
			picked_ele.children[1] 	== undefined do
		(
			messagebox("Object needs a linked root <dummy> and extension <point>")
			return()
		)
		
		-- if nothing is selected move the element to the origin
		if $ == undefined do
		(
			extender 							= instance picked_ele
			extender.wirecolor					= (color 128 128 128)
			extender.parent.pos 				= [0,0,0]
			extender.pivot						= extender.center
			picked_ele.children[1].parent		= extender
			
			select extender
			delete picked_ele
			return()
		)
		--	check wether the selected object got a root and extensionpoint
		if 	$.parent				== undefined OR 
			$.children[1] 			== undefined do
		(
			messagebox("Selected object needs a linked root <dummy> and extension <point>")
			return()
		)
		
		--	gets the object that needs to be extended
		current_obj				= $
		
		--	creates a copy from the picked objekt
		extender 				= instance picked_ele
		extender.wirecolor		= (color 128 128 128)
		extender.pivot			= extender.center
		
		--	gets the parent and children node of the current selection
		child					= current_obj.children[1]
		parent					= current_obj.parent
		
		--	create a new dummy and point
		ext_child				= Point pos:[0,0,0]
		ext_child.rotation		= picked_ele.children[1].rotation
		ext_child.pos			= picked_ele.children[1].pos
		ext_child.wirecolor		= (color 0 255 0)
		--	throw error  messagebox("text")
		--	try catch block would be nice
		--	to ensure the case of a missing child or parent
		
		ext_parent				= Dummy pos:[0,0,0]
		ext_parent.rotation		= picked_ele.parent.rotation
		ext_parent.pos			= picked_ele.parent.pos
		ext_parent.wirecolor	= (color 0 255 0)
		
		--	the old children becomes the new parent
		extender.parent			= ext_parent
		ext_child.parent		= extender
		
		--	move it to the destinated position
		ext_parent.rotation		= child.rotation
		ext_parent.transform 	= child.transform	
		
		extender.name 			= uniquename(current_obj.name)	
		
		--	the new parent becomes the child of the child
		ext_parent.parent		= child
		
		--	the created extended piece stays in focus
		if force_delete == true do
		(
			delete picked_ele.parent
			delete picked_ele.children[1]
			delete picked_ele
		)
		select extender
	)
	
	function preset_load preset_name =
	(
		vert_array		= #()
		face_array 		= #()
		sgroup_array 	= #()
		matid_array 	= #()
		edge_array 		= #()

		in_name 		= ((GetDir #scripts)+"/PipeSystem/presets/" + preset_name + ".dat")
		if in_name 		!= undefined then
		(
			in_file 		= openFile in_name
			if in_file 		!= undefined then
			(
				dummy_transform 	= readValue in_file 
				point_transform 	= readValue in_file 
				
				num_verts 			= readValue in_file 
				num_faces 			= readValue in_file 
				for v = 1 to num_verts do
					append vert_array (readValue in_file)
				for f = 1 to num_faces do
				(
					append face_array 	(readValue in_file)
					append sgroup_array (readValue in_file)
					append matid_array 	(readValue in_file)
					edge1 				= readValue in_file
					edge2 				= readValue in_file
					edge3 				= readValue in_file
					append edge_array #(edge1, edge2, edge3)
				)
				close in_file
				
				new_mesh = mesh vertices:vert_array faces:face_array
				for f = 1 to num_faces do
				(
					setFaceSmoothGroup new_mesh f sgroup_array[f]
					setFaceMatID new_mesh f matid_array[f]
					setEdgeVis new_mesh f 1 edge_array[f][1] 
					setEdgeVis new_mesh f 2 edge_array[f][2] 
					setEdgeVis new_mesh f 3 edge_array[f][3] 
				)
				update new_mesh
				
				parent				= dummy pos:[0,0,0]
				parent.wirecolor	= (color 0 255 0)
				parent.transform	= dummy_transform
				
				child 				= point pos:[0,0,0]
				child.wirecolor		= (color 0 255 0)
				child.transform		= point_transform
				child.parent		= new_mesh
				
				new_mesh.parent		= parent
				return new_mesh
			)
		)
	)
	
	on I_Pipe pressed  do
	(
		obj = preset_load("I_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on I_Isolation pressed  do
	(
		obj = preset_load("I_Isolatoren_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on I_Cap pressed  do
	(
		obj = preset_load("I_Caps_Rohre_" + (60/rdo.state) as string) 
		append_element  obj true
	)
	
	on L_Pipe_90_2 pressed  do
	(
		obj = preset_load("L_90_2_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on L_Pipe_45_2 pressed  do
	(
		obj = preset_load("L_45_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on L_Pipe_90_4 pressed  do
	(
		obj = preset_load("L_90_4_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on L_Pipe_90_10 pressed  do
	(
		obj = preset_load("L_90_10_Rohre_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on L_Pipe_90_7 pressed  do
	(
		obj = preset_load("L_90_7_Rohre_" + (60/rdo.state) as string) 
		append_element  obj true
	)
	
	on T_V_Hopper pressed  do
	(
		obj = preset_load("T_V_Hopper_" + (60/rdo.state) as string)
		append_element  obj true
	)
	
	on rot_left pressed do
	(
		in coordsys local rotate $.parent (angleaxis -90 [0,1,0])
	)
	
	on rot_right pressed do
	(
		in coordsys local rotate $.parent (angleaxis 90 [0,1,0])
	)
	
	on ctm_btn picked obj do
	(
		fn shape_filt obj = isKindOf obj Geometry
			
		if obj != undefined do
		(
			ctm_btn.text	= obj.name
		)	
	)
	
	on ext_btn pressed do
	(
		if getnodebyname(ctm_btn.text) != undefined do
		(
			obj		= getnodebyname(ctm_btn.text)
			append_element obj false
		)
	)
	
	--	dotnet hack to change the icon of the rollout
	on PipeSystem open do
	(
		d 			= (windows.getChildHWND 0 PipeSystem.title)[1]
		WM_SETICON	= 0x0080
		ICON_SMALL 	= 0
		icon 		= dotnetobject "System.Drawing.Icon" (getdir #scripts + 
											"\PipeSystem\icon\favicon.ico")
		windows.SendMessage d WM_SETICON ICON_SMALL icon.handle
	)
)

--PipeRolloutFloater = newRolloutFloater "PipeSystem v1.0" 312 400
--addRollout PipeSystem PipeRolloutFloater
createdialog PipeSystem 312 400