New UI Combined Tree Gen

 avatar
JO00
plain_text
4 months ago
57 kB
2
No Index
rollout bob_ross "Stylised Tree Generator" width:430 height:466
(	
	----------------"There are no mistakes, only happy accidents. - Bob Ross"
	
	groupBox 'grp1' "Getting Started" pos:[5,21] width:415 height:54 align:#left
	hyperlink 'hyperlink_documentation' "Click here for documentation!" pos:[278,7] width:145 height:13 align:#left address:"https://www.jolchawa.site/tree-generator-maxscript"
	label 'lbl2' "Any changes will need to regenerate mesh. Save your work frequently to avoid crashes. Generation may pause max do not quit during this time!" pos:[13,39] width:405 height:32 align:#left
	groupBox 'grp2' "Generation Settings" pos:[5,78] width:415 height:235 align:#left
	slider spin_tree_thickness "Tree Thickness" pos:[16,101] width:187 height:44 range:[1,20,2] ticks:10 align:#left
	slider 'sld_branch_amount' "Branch Removal Amount" pos:[16,151] width:187 height:44 range:[2,9.5,5] ticks:10 align:#left
	slider 'sld_leaf_dens' "Leaf Density" pos:[16,205] width:187 height:44 range:[2,20,3] ticks:10 align:#left
	slider 'sld_vertex_color' "Red Vertex Color Contrast" pos:[16,257] width:187 height:44 range:[1,100,3] ticks:10 align:#left
	label 'lbl3' "Left - Less" pos:[215,111] width:60 height:15 align:#left
	label 'lbl4' "Right - More" pos:[215,130] width:61 height:15 align:#left
	label 'lbl5' "Scale Control" pos:[278,95] width:81 height:15 align:#left
	label 'lbl6' "Hover over slider for tooltip value breakdowns" pos:[287,114] width:123 height:32 align:#left
	groupBox 'grp3' "" pos:[206,85] width:209 height:70 align:#left
	groupBox 'grp4' "Auto Generate" pos:[206,164] width:209 height:143 align:#left
	checkbox 'chk_final_merge' "Enable Roots" pos:[217,181] width:65 height:28 enabled:true checked:true align:#left
	spinner spin_weld "Leaf Weld" pos:[290,191] width:70 height:20 range:[1,40,2] align:#left
	button 'btn2' "Auto Generate Tree" pos:[217,235] width:193 height:30 align:#left
	progressBar 'pb_auto_gen' "ProgressBar" pos:[218,284] width:191 height:12 align:#left
	label 'lbl7' "Ensure line is drawn and selected!" pos:[233,215] width:172 height:16 align:#left
	label 'lbl8' "Auto Generation Progress Bar" pos:[217,269] width:192 height:13 align:#left
	groupBox 'grp5' "Manual Generation (Step by Step)" pos:[4,316] width:415 height:146 align:#left
	label 'lbl9' "Select component (listed below button) and press button to manually generate parts of the tree. To view Vertex Paint add the modifier. Combine when done." pos:[11,340] width:402 height:30 align:#left
	button 'btn_make_trunk' "1) MAKE TRUNK" pos:[18,374] width:101 height:21 align:#left
	label 'lbl10' "Select Line" pos:[42,396] width:61 height:15 align:#left
	button 'btn_make_leaves' "3) MAKE LEAVES" pos:[156,374] width:101 height:21 align:#left
	label 'lbl11' "Select Branches + Trunk" pos:[146,396] width:128 height:17 align:#left
	button 'btn_combine_selected' "5) Combine Selected" pos:[295,374] width:111 height:21 align:#left
	button 'btn_seperate_mat_id' "Seperate using (Mat ID)" pos:[318,407] width:94 height:31 align:#left
	button 'btn_make_branches' "2) MAKE BRANCHES" pos:[17,417] width:101 height:21 align:#left
	label 'lbl12' "Select Trunk" pos:[42,439] width:61 height:15 align:#left
	button 'btn_set_vertex' "4) VERTEX PAINT" pos:[163,417] width:101 height:21 align:#left
	label 'lbl13' "Select Leaves" pos:[183,439] width:178 height:17 align:#left
	
	global height_multiply=1
	global big_branch_spline_1=#([0,0,0], [-154.07*height_multiply,2*height_multiply,8.37563*height_multiply], [-179.202*height_multiply,-1.13597*height_multiply,9.5075*height_multiply])
	global big_branch_spline_2=#([0,0,0], [-57.3178*height_multiply,-35.9423*height_multiply,6.6734*height_multiply], [-83.065*height_multiply,-50.8251*height_multiply,8.83417*height_multiply])
	global big_branch_spline_3=#([0,0,0], [-127.016*height_multiply,47.7717*height_multiply,-48.1469*height_multiply], [-185.251*height_multiply,1.23668e-05*height_multiply,-60.5816*height_multiply])
	global big_branch_spline_4=#([0,0,0], [-61.9032*height_multiply,33.8817*height_multiply,-78.5175*height_multiply], [-87.757*height_multiply,3.28714e-06*height_multiply,-90.314*height_multiply])
	global big_branch_spline_5=#([0,0,0], [-26.1369*height_multiply,-43.5873*height_multiply,-84.3717*height_multiply], [-14.2148*height_multiply,-43.5873*height_multiply,-105.992*height_multiply])
	global big_branch_spline_6=#([0,0,0], [64.1959*height_multiply,51.8444*height_multiply,-43.6494*height_multiply], [98.85*height_multiply,51.8443*height_multiply,-59.3278*height_multiply])
	global big_branch_spline_7=#([0,0,0], [22.9271*height_multiply,-71.7837*height_multiply,-112.9082*height_multiply], [61.6205*height_multiply,-71.7837*height_multiply,-152.31*height_multiply])
	global big_branch_spline_8=#([0,0,0], [131.143*height_multiply,63.4003*height_multiply,-35.04396*height_multiply], [155.182*height_multiply,63.4003*height_multiply,-47.4936*height_multiply])
	
	global override_check=false
	
	global selected_spline_saving=#()
	
	global tree_trunk=undefined
	global rand_trunk_no=1
	global looking_branch=undefined
	global looking_trunk=undefined
	
	global delete_crash_arr=#()
	
	global arr_face_normals=#()
	global arr_face_normal_centre=#()
	global small_branch_list=#()
	global verts_on_branch_for_smaller_branches=#()
	global leaf_counter=0
	global leaf_array_all=#()
	global type=0
	global arr_vertext_to_select=#()
	
	global leaf_search_override=false
	
	
	global arr_spline_for_del=#()
	global arr_spline_sides=0
	
	global spline_reverse=false
	
	global tallest_height=0
	global shortest_height=0
	global height_sizeing=1
	
	fn check_spline_order spline_input=
	(
		int_total_knot_count=numKnots spline_input 1
		--checking if the spline is drawn upside down
		pos_first_knot=getKnotPoint spline_input 1 1
		pos_last_knot=getKnotPoint spline_input 1 int_total_knot_count
		if pos_first_knot[3]>pos_last_knot[3] then
		(
			--print"spline drawn upside down"
			spline_reverse=true
		)
		else
		(
			--print"spline drawn correctly"
			spline_reverse=false
		)
	)
	
	
	----------vertex painting leaves
	fn Vert_Paint_Leaves leaf_input=
	(
		total_faces=polyop.getNumFaces leaf_input
		for i=1 to total_faces do
		(
			try
			(
				rand_flipper=random 1 2
				---the smaller the contrast number the more likely itll land on 1 e.g. 1 in 3 chances
				rand_red=random 1 sld_vertex_color.value
				
				if rand_flipper==1 do
				(
					randomGreen = color 0 (random 0 255) 0
					
					if rand_red==1 then
					(
						randomGreen = color 255 (random 0 255) (random 0 255)
					)
					
					else
					(
						randomGreen = color 0 (random 0 255) (random 0 255)
					)
					polyop.setFaceColor leaf_input 0 i randomGreen
				)
				
				if rand_flipper==2 do
				(
					randomGreen = color (random 0 255) 0 (random 0 255)
					polyop.setFaceColor leaf_input 0 i randomGreen
				)
			
			)
			catch
			(
				print"failed vertex col"
			)
		)
	)
	
	
	fn making_trunk splineinput =
		(
			print"starting make trunk"
			tree_location=getKnotPoint splineinput 1 1
			splineinput.render_renderable=true
			splineinput.render_displayRenderMesh =true
			float_length=splineinput.render_length 
			if float_length<10 then
			(
				float_length=12
			)
			non_select_tree=false
			print"madae past number checks"
			if non_select_tree==false then
			(	
				
				print"in false"
				obj=selected_spline_saving[1]
				no_knots=numKnots obj
				spline_make=line transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] tree_location) isSelected:on
				addnewSpline spline_make
				first_knot=getKnotPoint selected_spline_saving[1] 1 1
				for i=1 to no_knots do
				(
					addKnot spline_make 1 #smooth #curve (getKnotPoint selected_spline_saving[1] 1 i)
					
				)
				
				first_knot=getKnotPoint spline_make 1 1
				spline_make.pivot=first_knot
				updateshape spline_make
				weldSpline spline_make 6.0
			)
			
			if non_select_tree==true then
			(
				print"itstrue"
				spline_make=line transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] tree_location) isSelected:on
				addnewSpline spline_make
				pos_trunk_point_1=spline_make.pos
				pos_trunk_point_2=[spline_make.pos.x+20,spline_make.pos.y,spline_make.pos.z+86]
				pos_trunk_point_3=[spline_make.pos.x+90,spline_make.pos.y,spline_make.pos.z+160]
				pos_trunk_point_4=[spline_make.pos.x+80,spline_make.pos.y-22,spline_make.pos.z+225]
				
				addKnot spline_make 1 #smooth #curve pos_trunk_point_1
				addKnot spline_make 1 #smooth  #curve  pos_trunk_point_2
				addKnot spline_make 1 #smooth  #curve  pos_trunk_point_3
				addKnot spline_make 1 #corner  #line pos_trunk_point_4
				
				updateshape spline_make
				weldSpline spline_make 6.0
				
			)
			
			
			print"prior append"
			append arr_spline_for_del spline_make
			spline_make.pos=tree_location
			rand_trunk_no=random 1 200
			name_tree="Tree Trunk"+rand_trunk_no as string
			spline_make.name=name_tree
			print"named now"
			spline_make.render_renderable=true
			spline_make.render_displayRenderMesh =true
				
			spline_make.render_thickness=1.2*spin_tree_thickness.value
			spline_make.render_sides=16
			
			updateshape spline_make
			arr_spline_sides=spline_make.render_sides
			format "mesh had this many sides % \n" arr_spline_sides
			
			print"made spline"
			updateshape spline_make
			max modify mode
			--convertToMesh spline_make Editable_Mesh
			convertTo spline_make PolyMeshObject
			convertTo spline_make Editable_Poly
			--print (classOf spline_make) as string
			subobjectLevel = 0
			---making the trunk more and less thick depending on its scale
			int_verts_total=polyop.getNumVerts spline_make
			tallest_height=polyop.getVert spline_make int_verts_total
			shortest_height=polyop.getVert spline_make 1
			ring_count=int_verts_total/arr_spline_sides
			--format "mesh ring count is % \n" ring_count
			float_half_selection=ring_count/3*arr_spline_sides as integer
			--format "mesh float_half_selection is % \n" float_half_selection
			arr_vertext_to_select=#()
			
			for i=1 to float_half_selection do
			(
				append arr_vertext_to_select i
			)
			print "done the append vertex select i"
			subobjectLevel = 1			
			try
			(
				polyop.setVertSelection spline_make arr_vertext_to_select
			)
			
			catch
			(
				--print "failed selection"
			)
			
			print"soft selecting now"
			spline_make.useSoftSel = on
			spline_make.falloff=spline_make.max.z-spline_make.min.z
			--print"min and all done pinching"
			spline_make.pinch=0.4
			
			try
			(
				--print"pushing mesh"
				modPanel.addModToSelection (Push ()) ui:off
			)
			
			catch 
			(
				--print"failed to push"
			)
			--print spin_tree_thickness.value as string
			
			spline_make.modifiers[#Push].Push_Value = spin_tree_thickness.value*1.5
			print"modifier done"
			convertTo spline_make PolyMeshObject
			--print"converted and alll"

			--now selecting the very bottom and pushing it a bit more plus it again
			
			print"selecting the very bottom and pushing it a bit more plus it again"
			arr_vertext_to_select=#()
			
			for i=1 to arr_spline_sides do
			(
				append arr_vertext_to_select i
			)
			polyop.setVertSelection spline_make arr_vertext_to_select
			spline_make.useSoftSel = on
			spline_make.falloff=(spline_make.max.z-spline_make.min.z)*1.5
			--spline_make.pinch=0.4
			subobjectLevel = 1
			modPanel.addModToSelection (Push ()) ui:off
			spline_make.modifiers[#Push].Push_Value = spin_tree_thickness.value*2.5
			convertTo spline_make PolyMeshObject
			--maxOps.CollapseNode spline_make ui:off
				
			print"selecting bottom"

			polyop.setVertSelection spline_make arr_vertext_to_select
			subobjectLevel = 1
			modPanel.addModToSelection (Push ()) ui:off
			spline_make.modifiers[#Push].Push_Value = spin_tree_thickness.value*3
			subobjectLevel = 0
			convertTo spline_make Editable_Poly
			--print"complete making the trunk"
			tree_trunk=spline_make
			looking_trunk=spline_make
			append delete_crash_arr spline_make
				
			
			---debug its crashing again
			print"made it here"


				
			--top_final_face=polyop.getNumFaces spline_make
			--bottom_final_face=top_final_face-2
			
			--faces_sel_unwrap=#()
			--for i=1 to bottom_final_face do
			--(
			--	append faces_sel_unwrap i
			--)
			
			print"got a bit lower"	
			addModifier spline_make (Uvwmap ()) ui:on
			just_uvw=spline_make.modifiers[#uvw_map]
			just_uvw.maptype = 4
				
			--modPanel.setCurrentObject (just_uvw)
			just_uvw.utile = 1
			just_uvw.vtile = 1
			just_uvw.wtile = 1
			just_uvw.axis = 0
			just_uvw.length = 5
			just_uvw.width=5
			just_uvw.height=5
				
				print"completed height"
			--just_uvw.realWorldMapSize = false
			convertTo spline_make Editable_Poly
			
			
				
				
			if chk_final_merge.checked==true do
			(
				print"making roots"
				maxOps.cloneNodes spline_make cloneType:#copy newNodes:&d_trunk
				backup_trunk=d_trunk[1]
				try
				(
					---adding roots to trunk
						
					arr_faces_to_root=#()
					for i=1 to 16 do
					(
						append arr_faces_to_root i
					)
					
					polyop.setFaceSelection spline_make arr_faces_to_root
					subObjectLevel=4
					spline_make.extrusionType = 1
					spline_make.faceExtrudeHeight = 102
					spline_make.extrude_bias = 1
					spline_make.faceExtrudeHeight = 10
					spline_make.EditablePoly.buttonOp #Extrude
					
					spline_make.ConvertSelection #Face #Vertex
					subobjectLevel = 1
					sel_verts_to_sort=polyop.getVertSelection spline_make as array
					first_vert=polyop.getVert spline_make sel_verts_to_sort[1]
					last_vert=polyop.getVert spline_make sel_verts_to_sort[sel_verts_to_sort.count]
					new_vert_list=#()
					if first_vert[3]>last_vert[3] do
					(
						--print"first vert is higher"
						count_begin=1
					)
					if first_vert[3]<last_vert[3] do
					(
						--print"last vert is higher"
						count_begin=16
					)
					for i=count_begin to (sel_verts_to_sort.count/2) do
					(
						append new_vert_list sel_verts_to_sort[i]
					)
					
					--print new_vert_list as string
					--1polyop.setVertSelection spline_make new_vert_list
					
					spline_make.ConvertSelection #Vertex #Edge
					subobjectLevel = 2
					
					sel_edges=polyop.getEdgeSelection spline_make as array
					--print sel_edges as string
					--print"now selectin edges to del"
					--sort sel_edges
					new_edges=#()
					for i=17 to 32 do
					(
						append new_edges sel_edges[i]
					)
					--print new_edges as string
					
					--subobjectLevel = 1
					
					--this finally removes it collapses
					--polyop.setVertSelection spline_make new_vert_list
					polyop.setEdgeSelection spline_make new_edges
					spline_make.remove()
					
					
					subobjectLevel = 1
					polyop.setVertSelection spline_make new_vert_list
					spline_make.remove()
					
					
					---now to select each "root"
					
					subObjectLevel=4
					faces_to_ext=#(3, 5, 7, 9, 11, 14, 16)
					polyop.setFaceSelection spline_make faces_to_ext
					spline_make.faceExtrudeHeight = 20
					spline_make.extrusionType = 1
					spline_make.EditablePoly.buttonOp #Extrude
					
					save_extrud=polyop.getFaceSelection spline_make
					
					
					--should be 7 top ones
					spline_make.ConvertSelection #Face #Edge
					subobjectLevel = 2
					get_top_root_edge=polyop.getEdgeSelection spline_make as array
					--now to sort it for highest edges based on location of edge (vert average)
					top7edges=#()
					amount_to_check=get_top_root_edge.count
					copy_remove=get_top_root_edge
					edge_z_list = #()

					for i = 1 to copy_remove.count do
					(
						edge = copy_remove[i]
						verts = polyop.getVertsUsingEdge spline_make edge
						avg_z = 0.0
						
						for v in verts do
						(
							avg_z += (polyop.getVert spline_make v).z
						)
						avg_z /= verts.count

						append edge_z_list #(edge, avg_z)
					)

					for i = 1 to 7 do
					(
						total_count = 1
						for j = 2 to edge_z_list.count do
						(
							if edge_z_list[j][2] > edge_z_list[total_count][2] do
							(
								total_count = j
							)
						)

						append top7edges edge_z_list[total_count][1]
						deleteItem edge_z_list total_count
					)

					----selects top edges now can collapse
					polyop.setEdgeSelection spline_make top7edges
					
					
					spline_make.ConvertSelection #Edge #Vertex
					subobjectLevel = 1
					verts_del_too=polyop.getVertSelection spline_make
					
					
					subObjectLevel=2
					polyop.setEdgeSelection spline_make top7edges
					spline_make.remove()
					
					subobjectLevel = 1
					polyop.setVertSelection spline_make verts_del_too
					spline_make.remove()
					
					------now to slice bottom off a bit
					addModifier spline_make (SliceModifier ()) ui:on
					slice_mod=spline_make.modifiers[#Slice]
					slice_mod.PlanarY = on
					slice_mod.PlanarZ = off
					slice_mod.PlanarX = off
					slice_mod.Slice_Type = 3
					convertTo spline_make Editable_Poly
					
					
					---to make root all same smoothing group
					subobjectLevel = 4
					polyop.setFaceSelection spline_make faces_to_ext
					
					spline_make.GrowSelection()
					spline_make.GrowSelection()
					to_smooth=polyop.getFaceSelection spline_make

					polyop.setFaceSmoothGroup spline_make to_smooth 1
					polyop.setFaceSelection spline_make #()
					delete backup_trunk
				)
				
				catch
				(
					print"failed roots resuming"
					delete spline_make
					spline_make=backup_trunk
				)
			)
			
			
				
			global the_final_trunk=spline_make
			
		) 
	
	
	-----the types are either 0 for trunk making from curve, 1 for large branches, 2 for twigs or 3 for leaves	
	fn building_cons type mesh_insert =
	(
		try
		(
			if type==0 then
			(
				try
				(
					spline_picked=mesh_insert
					--print spline_picked as string
					if spline_picked!=undefined do
					(
						print spline_picked as string
						making_trunk(spline_picked)
					)
				)
				catch
				(
					--print "Nothing is selected! Trying again" 
					delete arr_spline_for_del[1]
					arr_spline_for_del=#()
					try
					(
						spline_picked=mesh_insert
						--print spline_picked as string
						if spline_picked!=undefined do
						(
							print spline_picked as string
							making_trunk(spline_picked)
						)	
					)
					catch
					(
						print"Failure again"
						delete arr_spline_for_del[1]
						arr_spline_for_del=#()
					)
				)
				
			)
			
			if type==1 then
			(
				--obj=mesh_insert
				--print"start making large branches on trunk"
				---this resets balues and gets size of spline
				int_sides_no_surface=16
				arr_face_normals=#()
				local vert_list_high=#()
				local height_of_vert=#()
				format "mesh insert is % \n"mesh_insert
				obj=mesh_insert
				
				if obj==undefined do
				(
					print"looking as undefined"
					the_name="Tree Trunk"+rand_trunk_no as string
					obj=getNodeByName the_name
				)
				--print "before float local"
				local float_object_size=obj.max[3]-obj.min[3]
				--print "after float local"
				int_vertex_count=polyop.getNumVerts obj
				--print int_vertex_count as string
				int_face_count=polyop.getNumFaces obj
				
				--for dividing later on
				int_branch_number_cap=3
				
				--getting top faces only, height point
				lower_point_list=float_object_size/2
				--format "you need to be higher than $\n" lower_point_list
				branch_counting_added=0
				
				for i=1 to int_vertex_count do
				(
					pos_get_vert_location=polyop.getVert obj i
					--format"i'm vert % and my position is %\n"i pos_get_vert_location[3]
					if pos_get_vert_location[3]>lower_point_list do
					(
						--print"appended also its loc data"
						append vert_list_high i
						append height_of_vert pos_get_vert_location[3]
					)
				)
				--print vert_list_high as string
				
				--------getting rid of too many branches
				amount_to_reduce=floor(int_sides_no_surface/int_branch_number_cap)
				--print amount_to_reduce as string
				reduction_number=floor(vert_list_high.count-(vert_list_high.count/amount_to_reduce))
				-- debug value reduction_number=30
				--print reduction_number as string
				
				total_no_on_list=vert_list_high.count
					
				------------------------------------------hereherehere	
				format"there are going to be % branches placed before \n"total_no_on_list
				invert_slider=sld_branch_amount.value/10
				reduction_no=floor(total_no_on_list*invert_slider)
				format"reducing by branch count by % \n"reduction_no
				
				if reduction_no>total_no_on_list do
				(
					print"bigger than list"
					reduction_no=floor(total_no_on_list/2)
				)
				
				--breakit=half_it_all-2-3-4
				--reduction_no=0
					
					
				--format "List has total % items\n" total_no_on_list
				removal_no=floor(total_no_on_list-(total_no_on_list/1.5))
				bitofaboost=floor(removal_no*1)
				final_removal=total_no_on_list-45
				--format "Removal number is %\n" final_removal
				
					for i=1 to reduction_no do
				(
					
					selected_item_rand=random 1 vert_list_high.count
					deleteItem vert_list_high selected_item_rand
					deleteItem height_of_vert selected_item_rand
					--format "Removed number % from list \n"selected_item_rand
				)
				format "after removal there are now % of verts \n"vert_list_high.count
				
				subObjectLevel=1
				--getting the normals of the faces and centre
				--print vert_list_high.count as string
				--print "before polyop"
				face_using=polyop.getFacesUsingVert obj vert_list_high
				total_face_using=face_using.count
				array_face=face_using as array
				--print array_face as string
				total_no=array_face.count
				counting=1
				better_face_array=#()
				for i=1 to total_no do
				(
					if counting>4 then
					(
						counting=1
					)
					if counting==2 then
					(
						--deleteItem array_face i
						append better_face_array array_face[i]
						--format"Deleted object % \n"i
					)
					counting+=1

				)
				
				format "there will be actually % branches spawned due to faces\n" better_face_array.count
				
				---reducing the face array finally
				total_face_arr=better_face_array.count
				reduction_faces=floor(total_face_arr*invert_slider)
				clean_face_arr=#()
				for i=1 to reduction_faces do
				(
					face_sel_to_del=random 1 total_face_arr
					appendIfUnique clean_face_arr better_face_array[face_sel_to_del]
				)
				
				--overwrrite for below
				--print clean_face_arr as string
				
				--format "finally rhere are % branches being placed on faces \n"total_face_arr
			
				
				--print better_face_array as string
				--print face_using as string
				--print"after polyop"
				--convertTo obj Editable_Poly
				subObjectLevel=4
				--polyop.setFaceSelection obj clean_face_arr
				--facestoact=polyop.getFaceSelection obj
				--print facestoact as string
				arr_face_normals=#()
				arr_face_normal_centre=#() 
				--print int_face_count as string
				print obj.name as string
				--print"got this far"
				
				for face in clean_face_arr do
				(
					--printing"starting"
					pos_face_normal=polyop.getFaceNormal obj face
					pos_face_normal_centre=polyop.getFaceCenter obj face
					--print pos_face_normal as string
					append arr_face_normals pos_face_normal
					append arr_face_normal_centre pos_face_normal_centre
					--print"success for normal"+i as string
					print"done"
				)
				--print"made it here?"
				----
				--try spawning that branching
				higher_branches=int_face_count/2 as integer
				total_faces_selected=arr_face_normals.count
				--print"total faces selected"+total_faces_selected as string
				--print total_faces_selected as string
				small_branch_list=#()
				
				
				height_multiply=((obj.max[3]-obj.min[3])*1.3)/360
				print height_multiply as string
				
				for i=1 to total_faces_selected do
				(
					--choosing a random spline branch from my list
					spline_branch_selected=random 1 8

					set_command="selected_arr_spline=big_branch_spline_"+spline_branch_selected as string
					execute set_command
					--format "Selected spline % \n" spline_branch_selected
					--creating this spline
					--total_knots_in_arrspline=selected_arr_spline.count
					--print selected_arr_spline as string
					local box_branch_demo=line transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [0,0,0]) isSelected:on
					addnewSpline box_branch_demo
					--print"made spline"
						
					for i=1 to 3 do
					(
						---#smooth #curve #line #corner
						addKnot box_branch_demo 1 #smooth #line selected_arr_spline[i]
						--format"added knot % \n" i
							
					)
						
					updateshape box_branch_demo
					weldSpline box_branch_demo 6.0
					updateshape box_branch_demo
						
					box_branch_demo.render_renderable=true
					box_branch_demo.render_displayRenderMesh =true
					
					box_branch_demo.render_thickness=spin_tree_thickness.value--*height_sizeing
					box_branch_demo.render_sides=6
						
					--print "render set"
					updateshape box_branch_demo
						
					--print"made spline"
					--updateshape box_branch_demo
					max modify mode
					convertTo box_branch_demo PolyMeshObject
					convertTo box_branch_demo Editable_Poly
					--print "converted"
		
					box_branch_demo.name="Demo_branch_"+i as string
		
					-----setting some UVS
					addModifier box_branch_demo (Uvwmap ()) ui:on
					just_uvw=box_branch_demo.modifiers[#uvw_map]
					just_uvw.maptype = 4
						
					--modPanel.setCurrentObject (just_uvw)
					just_uvw.utile = 1
					just_uvw.vtile = 1
					just_uvw.wtile = 1
					just_uvw.axis = 0
					just_uvw.length = 1
					just_uvw.width=1
					just_uvw.height=1
					--just_uvw.realWorldMapSize = false
					convertTo box_branch_demo Editable_Poly
				
					
					vert_pos_1=polyop.getVert box_branch_demo 1
					vert_pos_3=polyop.getVert box_branch_demo 4
					halfway_verts=(vert_pos_1+vert_pos_3)/2
					box_branch_demo.pivot=halfway_verts
				
					--print"made it here"
					box_branch_demo.pos=arr_face_normal_centre[i]
						
					vector_upwards=normalize arr_face_normals[i]
						
					vector_right=normalize (cross vector_upwards [0,1,0])
					--print "made it here?"
					if (length vector_right) < 0.001 then vector_right = normalize (cross vector_upwards [1,0,0])
					vector_forward= cross vector_right vector_upwards
					--print"made it end end"
					final_maxtrix=matrix3 vector_right vector_forward vector_upwards arr_face_normal_centre[i]
					offset_into_tree=-vector_upwards * 5
					final_maxtrix.row4+= offset_into_tree
					box_branch_demo.transform=final_maxtrix
					
					append small_branch_list box_branch_demo
					--print"appended"
					--print"DONE DUSTED NOW PLACED"
					
					---checking if it is facing downwards
					--branch_transform=box_branch_demo.objecttransform
					pos_first_vert=(polyop.getVert box_branch_demo 1)--*branch_transform
					total_verts=polyop.getNumVerts box_branch_demo
					top_vert=(polyop.getVert box_branch_demo total_verts)--*branch_transform
					if top_vert.z<pos_first_vert.z do
					(
						--print"facing wrong way!!"
						rotate box_branch_demo (angleaxis 180 [1,0,0])
						
					)
			
					--print"selecting the very bottom and pushing it a bit more plus it again"
					arr_vertext_to_select=#()
					
					for i=1 to 4 do
					(
						append arr_vertext_to_select i
					)
					polyop.setVertSelection box_branch_demo arr_vertext_to_select
					box_branch_demo.useSoftSel = on
					box_branch_demo.falloff=(box_branch_demo.max.z-box_branch_demo.min.z)*1.5
					--spline_make.pinch=0.4
					subobjectLevel = 1
					modPanel.addModToSelection (Push ()) ui:off
					box_branch_demo.modifiers[#Push].Push_Value = spin_tree_thickness.value
					convertTo box_branch_demo PolyMeshObject
					--maxOps.CollapseNode spline_make ui:off
						
					--print"selecting bottom"

					polyop.setVertSelection box_branch_demo arr_vertext_to_select
		
					subobjectLevel = 1
					modPanel.addModToSelection (Push ()) ui:off
					box_branch_demo.modifiers[#Push].Push_Value = spin_tree_thickness.value
					subobjectLevel = 0
					convertTo box_branch_demo Editable_Poly
					--convertToMesh spline_make
						
						
					--ends_sel=polyop.setFaceSelection box_branch_demo #(13,14)
					subObjectLevel = 4
					polyop.deleteFaces box_branch_demo #(13,14)
					--actionMan.executeAction 0 "40021"  -- Selection: Select All
					face_count=polyop.getNumFaces box_branch_demo
					faces_all=#()
					for i=1 to face_count do
					(
						append faces_all i
					)
					--print faces_all as string
					polyop.setFaceSmoothGroup box_branch_demo faces_all 1
					
					
					rand_z_rot=random -180 180
					rotate box_branch_demo (angleaxis rand_z_rot [0,0,1])
	
				)
				
				--select rand branches
				total_branches=small_branch_list.count
				half=floor(total_branches/2)
				
				--print total_branches as string
				--print "now trying to rotate here"
				
				--format "now running for %\n times" half
				for i=1 to half do
				(
					--rand_y_rotation=random 0 45
					rand_branch_selection=random 1 total_branches
					--format "i have selected branch %\n" rand_branch_selection
					branchsel = small_branch_list[rand_branch_selection]
					--print"now moving"
					try
					(
						rotate branchsel (angleaxis 10 [0,1,0])
					)
					catch
					(
						print"failed the rotation oof"
					)
					
					--format "my branch rotation is %\n" branch.rotation
					--print small_branch_list[rand_branch_selection].rotation as string
					--small_branch_list[i]
				)
				
				
				---checking if meshes in array actually still exist before this check after!
				small_branch_list = for branch in small_branch_list where isValidNode branch collect branch
				--print"finished cleanup small branch"
				--print small_branch_list as string
				--print"cleaned meshes"
				
				
				-----for deleting intersecting branches
				-----checks using vol select modifier
				--can break
				
				try
				(
					global tocheck_list = small_branch_list
					intersect_list = #()

					for i = 1 to tocheck_list.count do
					(
						obj_tocheck = tocheck_list[i]
						select obj_tocheck
						subObjectLevel = 0
						
						for j = i+1 to tocheck_list.count do
						(
							local obj_check_against = tocheck_list[j]

							if classof obj_tocheck.modifiers[1] != Vol__Select do
							(
								addModifier obj_tocheck (Vol__Select()) ui:on
							)
							--format "checking if % intersects with % \n" tocheck_list[i].name tocheck_list[j].name
							vol_item = obj_tocheck.modifiers[#Vol__Select]
							vol_item.level = 1
							vol_item.volume = 3
							vol_item.node = obj_check_against
							vol_item.type = 1
							--print "done with vol selecct"
							convertTo obj_tocheck Editable_Poly
							--print"after conversion"
							max modify mode
							subObjectLevel = 1
							selected_verts=#()
							try
							(
								selected_verts = getVertSelection obj_tocheck as array
								--print selected_verts as string
							)
							catch
							(
								print"nothing to select"
							)
							

							if selected_verts.count > 1 do
							(
								--format "Intersection found between % and %\n" obj_tocheck.name obj_check_against.name
								
								appendIfUnique intersect_list obj_check_against
								--print"appended"
							)
							subObjectLevel = 0
							
							--convertTo obj_tocheck Editable_Poly
							--print"deleted mod"
						)
					)
					
				)
				catch
				(
					print "Failed intersect check oops"
				)
				
				--print"after intersect"
				select intersect_list
				delete intersect_list
				
				----deleting delted nodes as uncean list
				-----from here https://forums.autodesk.com/t5/3ds-max-programming-forum/error-msg-attempt-to-access-deleted-nodes/td-p/4001193
				
				tocheck_list = for o in tocheck_list where isValidNode o collect o
				
				append delete_crash_arr tocheck_list
				
				small_branch_list=tocheck_list
				global another_check=tocheck_list
				--looking_branch=small_branch_list
				tocheck_list=#()
				--print"completed branches"
			)
			
			---this makes leaves
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			if type==2 then
			(
				
				branches_merged=#()
				print"on leaf"
				--branches_merged=looking_branch
				--print branches_merged as string
				looking_trunk=undefined
				
				format "the count for another check array is % \n"another_check.count
				
				
				if the_final_trunk!=undefined then
				(
					looking_trunk=the_final_trunk
					print "trunk is defined now from beforee"
				)
				
				if another_check.count>2 then
				(
					branches_merged=another_check
					small_branch_list=another_check
					print "branches are defined now from beforee"
				)
				else
				(
					print"there isnt enough branches"
				)
				
				current_selecton=$
				--print current_selecton as string
				
				--print looking_trunk as string
				-----this is for looking for branch and trunk
				checked=0
				
				if looking_trunk == undefined or branches_merged.count < 2 or override_check==true do
				(
					for obj in current_selecton do
					(
						get_name=obj.name as string
						--print get_name
						looking_branch=matchPattern (toLower get_name) pattern:"*Branch*"  ignoreCase:true
						check_trunk=matchPattern (toLower get_name) pattern:"*Trunk*"  ignoreCase:true
						if looking_branch==true then
						(
							print"found branch"
							append branches_merged obj
						)
						if check_trunk==true then
						(
							print"found trunk"
							trunk_mesh=obj
							looking_trunk=obj
							
						)
						else
						(
							print"neither"
						)
						checked+=1
					)
				)
				
					
				---cleaning old branch if it no longer exists
				
				branches_merged = for branch in branches_merged where isValidNode branch collect branch
				
				
				
				
				
				
				-----lowest_branch and tallest
				position_arr=#()
				print branches_merged as string
				--adding branches
				
				for item in branches_merged do
				(
					branch_posit=item.pos
					append position_arr branch_posit[3]
					
				)
				
				print "made it here nows"
				--print position_arr as string
				to_sort=position_arr
				sort to_sort
				--print to_sort as string
				lowest_branch_ind=findItem position_arr to_sort[1]
				lowest_branch_obj=branches_merged[lowest_branch_ind]
				
				highest_branch_ind=findItem position_arr to_sort[position_arr.count]
				highest_branch_obj=branches_merged[highest_branch_ind]
				
				--format "the lowest branch is % \n" lowest_branch_obj.name as string
				
				--format "the tallest branch is % \n" highest_branch_obj.name as string
				
				
				
				---now both are found i need to get distance between them
				--this will be scale of centre of ball just need to offset a bit
				spawn_loc=lowest_branch_obj.pos
				offset_bit=lowest_branch_obj.pos[3]*1.2
				spawn_loc_lowest=[lowest_branch_obj.pos[1],lowest_branch_obj.pos[2],offset_bit]
				
				start_radius=50*1.7
				height_multiply=((looking_trunk.max[3]-looking_trunk.min[3])*1.3)/360
				start_radius=start_radius*height_multiply
				spherespawn= sphere radius:start_radius pos:spawn_loc_lowest isSelected:on 
				spherespawn.hemisphere = 0.44
				
				convertTo spherespawn Editable_Poly
				
				
				---for detection this will be turbosmoothed vers
				turbo_mesh_intersect= copy spherespawn
				addModifier turbo_mesh_intersect (TurboSmooth())
				turbo_mesh_intersect.modifiers[#TurboSmooth].iterations = 4
				convertTo turbo_mesh_intersect Editable_Poly
				
				sphere_spawn_small= sphere radius:start_radius pos:spawn_loc_lowest isSelected:on 
				sphere_spawn_small.hemisphere = 0
				
				--delete spherespawn
					
				------intersections for random ball spawn location
				
				density_multiply=floor(sld_leaf_dens.value/6)
				number_of_ball_spawn=branches_merged.count*7*density_multiply
				spawn_extra_points=#()
				--format "there needs to be % spawned extra balls \n" number_of_ball_spawn
				--print branches_merged as string
				
				
				small_ball_list=#()
				if number_of_ball_spawn>10 do
				(
					number_of_ball_spawn=9
				)
				
				for i=1 to number_of_ball_spawn do
				(
					branch_sel_no=random 1 branches_merged.count
					if classof turbo_mesh_intersect.modifiers[1] != Vol__Select do
					(
						addModifier turbo_mesh_intersect (Vol__Select()) ui:on
					)
					
					--print"now trying"
					try
					(
						obj_tocheck = turbo_mesh_intersect
						select obj_tocheck
						subObjectLevel = 0
						obj_check_against = branches_merged[branch_sel_no]
						--format "now trying against this branch % \n"obj_check_against.name
						
						vol_item = obj_tocheck.modifiers[#Vol__Select]
						vol_item.level = 1
						vol_item.volume = 3
						vol_item.node = obj_check_against
						vol_item.type = 1
						--print "done with vol selecct"
						convertTo obj_tocheck Editable_Poly
						--print"after conversion"
						
						max modify mode
						subObjectLevel = 1
						selected_verts=#()
						
						try
						(
							selected_verts = getVertSelection obj_tocheck as array
							--print selected_verts as string
						)
						catch
						(
							print"nothing to select"
						)
						

						if selected_verts.count > 1 do
						(
							--format "Intersection found between % and %\n" obj_tocheck.name obj_check_against.name
							location_from_vert=polyop.getVert obj_tocheck selected_verts[1]
							append spawn_extra_points location_from_vert
							size_rand_small=random 20 90
							spawn_spher= sphere radius:size_rand_small pos:location_from_vert isSelected:on
							spawn_spher.segs = 20
							spawn_spher.hemisphere = 0
							spawn_spher.name="Ball_"+i as string
								
							rand_move_x=random -100 100
							rand_move_y=random -100 100
							rand_move_z=random -100 100
							move spawn_spher [rand_move_x,rand_move_y,rand_move_z] 
							append small_ball_list spawn_spher
							--appendIfUnique intersect_list obj_check_against
							--print"appended"
						)
						
						subObjectLevel = 0
						--convertTo obj_tocheck Editable_Poly
						--print"deleted mod"
					)
					catch (print"failed somehow")
				)
				
				--print spawn_extra_points as string
				
				--------editing to remove bottom and more wavey
				for obj in small_ball_list do
				(
					--format "NOW WIGGLING MESH % \n" obj.name
					adding_to=obj
					convertTo adding_to Editable_Poly
					addModifier adding_to (Noisemodifier ()) ui:on
					noise_mod=adding_to.modifiers[#Noise]
					noise_mod.strength = [20.8,20,20]	
					noise_mod.scale = 9.9	
					noise_mod.frequency = 2.96	
					rand_seed=floor(random 1 3000)
					noise_mod.seed = rand_seed
					
					--move adding_to [-10,-10,-10] 
					
					try
					(
						max modify mode
						subObjectLevel=0
						select adding_to
						--maxOps.CollapseNode adding_to off
						convertTo adding_to EditablePolyMesh	
						convertTo adding_to Editable_Poly
						subObjectLevel=0
						
					)
					
					catch
					(
						print"failed to convert down"
					)
					
					--faces are 141 to 200
					face_to_del_list=#()
					for i=141 to 200 do
					(
						append face_to_del_list i
					)
					
					polyop.deleteFaces adding_to face_to_del_list
				)
				
				
				
				
				---the delete pile
				delete turbo_mesh_intersect
				
				delete spherespawn
				
				delete sphere_spawn_small
				
				
				
				
				
				to_add_sphere= sphere radius:start_radius pos:spawn_loc_lowest isSelected:on 
				to_add_sphere.hemisphere = 0
				to_add_sphere.segs = 16

				
				convertTo to_add_sphere Editable_Poly
				
				
				
				--to_add_sphere=selection[1]
				remove_list=#()
				for i=97 to 128 do
				(
					append remove_list i
				)
				
				--wiggle this sphere and delete bottom face then rot
				
				
				--format "now wiggling primary mesh \n"
				
				addModifier to_add_sphere (Noisemodifier ()) ui:on
				noise_mod=to_add_sphere.modifiers[#Noise]
				noise_mod.strength = [20.8,20,20]	
				noise_mod.scale = 9.9	
				noise_mod.frequency = 2.96	
				rand_seed=floor(random 1 3000)
				noise_mod.seed = rand_seed
				
				max modify mode
				subObjectLevel=0
				select to_add_sphere
				--maxOps.CollapseNode adding_to off
				convertTo to_add_sphere EditablePolyMesh	
				convertTo to_add_sphere Editable_Poly
				subObjectLevel=0

				
				primary_sphere_bot = #()
				total_faces=polyop.getNumFaces to_add_sphere

				polyop.deleteFaces to_add_sphere remove_list
				
				--this combines using boolean into one big spawn zone
				addModifier to_add_sphere (BooleanMod ()) ui:on
				bool_mod=to_add_sphere.modifiers[#Boolean]
				for obj in small_ball_list do
				(
					--format "adding no % \n" obj.name
					convertTo obj Editable_Poly
					bool_mod.useLiveReference = on
					bool_mod.appendOperand #single operandNode:obj operationType:#union				
				)
				
				bool_mod.DisplayType=0
				
				convertTo to_add_sphere Editable_Poly
				
				--maxOps.CollapseNode first_small_sphere off 
				
				
				-----weld nearby verts to prevent failing next check elemn	

				try
				(
					all_verts = #{1..(polyop.getNumVerts to_add_sphere)}
					polyop.setVertSelection to_add_sphere all_verts
					
					
					to_add_sphere.weldThreshold = spin_weld.value
					polyop.weldVertsByThreshold to_add_sphere all_verts
					--to_add_sphere.weldFlaggedVertices ()
							
					print "welded"
				)
				
				catch
				(
					print"failed welding?"
				)
				
				--------check element no after welding
				
				total_no_faces=polyop.getNumFaces to_add_sphere
				todelete_face_list=#()
				all_faces_checked=false
				
				-----bend overrarching balls
				addModifier to_add_sphere (Bend ()) ui:on
				bend_mod_on=to_add_sphere.modifiers[#Bend]
				rand_bending=random -44 44
				bend_mod_on.bendangle = rand_bending
				convertTo to_add_sphere Editable_Poly
					
					
					
				local elementFaces = polyop.getElementsUsingFace to_add_sphere 1
				max modify mode
				subObjectLevel = 4 
				polyop.setFaceSelection to_add_sphere elementFaces
				--polyop.deleteFaces to_add_sphere elementFaces
				max select invert
				curr_select=polyop.getFaceSelection to_add_sphere
				polyop.deleteFaces to_add_sphere curr_select
				

				--add more top facing smaller balls using Normals
				--- they need to only be top facing spawning 4-6 max at varyig heights
				--will intersect closer to ref
				
				
				top_faces_only = #()
				total_faces=polyop.getNumFaces to_add_sphere
				
				for i=1 to total_faces do
				(
					face_norm = normalize (polyop.getFaceNormal to_add_sphere i)
					if dot face_norm [0,0,1] > 0.5 do
					(
						append top_faces_only i
					)
				)

				--polyop.setFaceSelection to_add_sphere top_faces_only
				
				total_up_face=top_faces_only.count
				smaller_just_top_balls=#()
				
				density=sld_leaf_dens.value
				format"the density of leaf value is % \n"density
				
				for i = 1 to density do
				(
					random_face_up=random 1 total_up_face
					get_face_pos=polyop.getFaceCenter to_add_sphere random_face_up
					size_balls=random 5 20
					size_balls=size_balls*height_multiply
					smaller_sphere=sphere radius:size_balls pos:get_face_pos isSelected:on
					smaller_sphere.hemisphere=0
					smaller_sphere.segs = 20
						
					convertTo smaller_sphere Editable_Poly
					orb_name="Smaller_orb_"+random_face_up as string
					
					smaller_sphere.name=orb_name
					
					--sel_small_orb=getNodeByName orb_name
					sel_small_orb=smaller_sphere
					
					
					--format "NOW WIGGLING MESH % \n" sel_small_orb.name
					convertTo sel_small_orb Editable_Poly
					addModifier sel_small_orb (Noisemodifier ()) ui:on
					noise_mod=sel_small_orb.modifiers[#Noise]
					noise_mod.strength = [20.8,20,20]	
					noise_mod.scale = 9.9	
					noise_mod.frequency = 2.96	
					rand_seed=floor(random 1 3000)
					noise_mod.seed = rand_seed
					
					--move adding_to [-10,-10,-10] 
					
					try
					(
						max modify mode
						subObjectLevel=0
						select sel_small_orb
						--maxOps.CollapseNode adding_to off
						convertTo sel_small_orb EditablePolyMesh	
						convertTo sel_small_orb Editable_Poly
						subObjectLevel=0
						
						--random rot
						random_rot=random -45 45
						rotate sel_small_orb (angleaxis random_rot [1,1,0])
						
						append smaller_just_top_balls sel_small_orb
						--print"appended to small list"
						
					)
					
					catch 
					(
						print"failed small ball add"
					
					)
					
					
					
				)
				
				
				face_to_del_list=#()
				for i=141 to 199 do
				(
					append face_to_del_list i
				)
				
				---attaching all leaf spawn areas together finally!!
				--selecting lower faces
				tot_faces=smaller_just_top_balls.count
				
				for obj in smaller_just_top_balls do
				(
					try
					(
						print smaller_just_top_balls.name as string
						max modify mode
						select obj
						polyop.deleteFaces obj face_to_del_list
						polyop.attach to_add_sphere obj
					)
					catch
					(
						--print"failed to add smaller balls"
						polyop.attach to_add_sphere obj
					)
					
				)
				
				print "complete all final complete merge for spawn leaf"
				
				--always spawns bit low so shuffle up
				move to_add_sphere [0,0,85]
				
				final_no_checker=polyop.getNumFaces to_add_sphere
				
				if final_no_checker<8500 do
				(
					print "mesh has low faces redo generation"
				)
				
				
				-----prevent mesh clip past the trunk intiital
				--dont have time do it another
				
				
				--print branches_merged as string
				--print trunk_mesh as string
				trunk_mesh=looking_trunk
				----combine the branches into one lot
				for i=1 to branches_merged.count do
				(
					--print"attaching branch 1 to trunk"
					polyop.attach looking_trunk branches_merged[i]
				)
				
				
			
				-----then spawn leaves
				spawn_leaves=true
				
				if spawn_leaves do
				(
					obj=to_add_sphere
					
					---this makes plane for leaf
					--obj=selection[1]
					--place_branches obj
					length_rand=random 30 40
					pivot_offset=(length_rand/2)*2
					length_longer=length_rand*1.5
					--local leaf_plane= Plane length:length_rand width:60 transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [716.428,0,380.843]) isSelected:on
					
					
					local leaf_plane= Plane length:length_rand width:length_longer transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [719.282,-27.3379,0]) widthsegs:1 lengthsegs:1 isSelected:on
					rotate leaf_plane (angleaxis -90 [1,0,0])
					--math_one=leaf_plane.max.x*0.8
					end_leaf_pos=[leaf_plane.max.x,leaf_plane.pos[2],leaf_plane.pos[3]]
					start_leaf_pos=[leaf_plane.min.x,leaf_plane.pos[2],leaf_plane.pos[3]]
					right_leaf_plane=copy leaf_plane
					left_leaf_plane=copy leaf_plane
					
					rotate right_leaf_plane (angleaxis 30 [0,1,0])
					rotate left_leaf_plane (angleaxis -30 [0,1,0])
					
					right_leaf_plane.pos=end_leaf_pos
					left_leaf_plane.pos=start_leaf_pos
					
					move right_leaf_plane [-4,0,0]
					move left_leaf_plane [3,0,0]
					
					convertTo leaf_plane Editable_Poly
					convertTo left_leaf_plane Editable_Poly
					convertTo right_leaf_plane Editable_Poly
					
					leaf_plane.attach left_leaf_plane leaf_plane
					leaf_plane.attach right_leaf_plane leaf_plane
					
					ResetXForm leaf_plane
					convertTo leaf_plane Editable_Poly
					
					
					backup_leaf_plane=copy leaf_plane
					
					
					leaf_plane.pivot=leaf_plane.center
					leaf_plane.pivot=[leaf_plane.pivot[1],leaf_plane.pivot[2],leaf_plane.pos[3]-pivot_offset]
				
					--this is for covering a surface rather than ball
					
					amount_to_cover=polyop.getNumFaces obj
					reduce_amount=floor(amount_to_cover*0.4)
					
					leaf_copies_on_sphere=#()
					first_leaf=undefined
					
					for i=1 to reduce_amount do
					(
						face_chosen=random 1 amount_to_cover
						---------
						----------
						random_scalex= random 0.5 3
						random_scaley= random 0.5 3
						random_scalez= random 0.5 3
						new_leaf=copy backup_leaf_plane
						--new_leaf.pos=location
						
						scale new_leaf [random_scalex,random_scaley,random_scalez]
						
						pos_face_normal=polyop.getFaceNormal obj face_chosen
						pos_face_normal_centre=polyop.getFaceCenter obj face_chosen
						
						vector_upwards=normalize pos_face_normal
							
						vector_right=normalize (cross vector_upwards [0,1,0])
						--print "made it here?"
						if (length vector_right) < 0.001 then vector_right = normalize (cross vector_upwards [1,0,0])
						vector_forward= cross vector_right vector_upwards
						--print"made it end end"
						final_maxtrix=matrix3 vector_right vector_forward vector_upwards pos_face_normal_centre
						
						rand_moving=random -3 3
						--offset_into_tree=-vector_upwards * 5
						
						--final_maxtrix.row4+= offset_into_tree
						new_leaf.transform=final_maxtrix
						
						move new_leaf [0,rand_moving,0] 
						--------------------
						----------
						if i==1 then
						(
							first_leaf=new_leaf
						)
						
						else
						(
							first_leaf.attach new_leaf first_leaf
						)
						--location=polyop.getVert obj vertpos_chosen
						--append leaf_copies_on_sphere new_leaf
					)
					
					--original_leaf=leaf_copies_on_sphere[1]
					
					--attaching mats to everything
					--making mats
					
					trunk_mat = StandardMaterial name:"Trunk_Mat" diffuse:(color 139 69 19) 
					leaf_mat = StandardMaterial name:"Leaf_Mat" diffuse:(color 34 139 34) 

					tree_multi_mat = MultiMaterial numsubs:2 name:"Tree_Material"

					tree_multi_mat.materialList[1] = trunk_mat 
					tree_multi_mat.materialList[2] = leaf_mat 

					tree_multi_mat.names[1] = "Trunk Mat"
					tree_multi_mat.names[2] = "Leaf Mat"
					
					trunk_faces_store=#()
					for i=1 to (polyop.getNumFaces trunk_mesh) do
					(
						append trunk_faces_store i
					)
					
					leaf_faces_store=#()
					for i=1 to (polyop.getNumFaces first_leaf) do
					(
						append leaf_faces_store i
					)
					
					polyop.setFaceMatID trunk_mesh trunk_faces_store 1
					trunk_mesh.material=tree_multi_mat
					
					polyop.setFaceMatID first_leaf leaf_faces_store 2
					first_leaf.material=tree_multi_mat
					
					-----------------
					--centre the pivot to get location to spawn sphere to steal normals from
					first_leaf.pivot=first_leaf.center
					
					print"dones all"
					delete to_add_sphere
					
					---noising up the leaves so they work better in engine layering more sporatic
					addModifier first_leaf (Noisemodifier ()) ui:on
					noise_mod=first_leaf.modifiers[#Noise]
					rand_seed_noise=floor(random 1 400)
					noise_mod.seed =rand_seed_noise
					noise_mod.scale = 440
					noise_mod.scale = 0.5
					noise_mod.strength = [50,50,50]
					convertTo first_leaf Editable_Poly
					
					
					-------setting normal to be centre
					
					
					convertTo first_leaf Editable_mesh
					----from this thread on polyhaven i dont really know how it works
					----https://polycount.com/discussion/193855/working-normal-thief-for-3ds-max-2018
					centerPos = first_leaf.center
					for vert in first_leaf.vertices do
					(
						setNormal first_leaf vert.index (vert.pos - centerPos)
						--update obj<br>
					)
					
					print"done centering"
					
					convertTo first_leaf Editable_Poly
					
					------vertex painting leaves
					
					----random vertex coloring per every so so leaf
					Vert_Paint_Leaves first_leaf
					
					----final combine into named tree mesh!
					
					polyop.attach trunk_mesh first_leaf
					---creating_name
					name_counter=0
					name_tree="Tree_"+(name_counter as string)
					
					find_name_same_tree=getNodeByName name_tree
					while find_name_same_tree!=undefined or name_counter==6 do
					(
						name_counter+=1
						name_tree="Tree_"+(name_counter as string)
						find_name_same_tree=getNodeByName name_tree
					)
					
					trunk_mesh.name=name_tree
					--tocheck_list=#()
	
				)
				
			)
		)
		
		catch
		(
			print"Failed to build mesh branch or leafs"
		)
	)
	

	
	on btn2 pressed do
	(
		try
		(
			pb_auto_gen.value=0
			selected_spline_saving=#()
			if (classof $ == Line) then
			(
				check_spline_order($)
				if spline_reverse==true then
				(
					messageBox "Spline must be draw from the root!"
				)
				if spline_reverse==false then
				(
					pb_auto_gen.value=25
					print "spline drawn correctly contuining"
					append selected_spline_saving $
					building_cons 0 $
					pb_auto_gen.value=40
					print"now onto branches"
					--it fails on initital one if first clicked so try again
					try
					(
						building_cons 1 tree_trunk
					)
					catch
					(
						building_cons 1 tree_trunk
					)
					building_cons 1 tree_trunk
					pb_auto_gen.value=60
					print"now going ono leaf"
					building_cons 2 tree_trunk
					pb_auto_gen.value=100
				)
			)
			else
			(
				messageBox "Not selecting spline!"
			)
			
		)
		catch
		(
			print"Unable to start not"
			-----deleting whatever state it got up to
		)
	)
	-------if just making trunk
	on btn_make_trunk pressed do
	(
		if (classof $ == Line) then
		(
			try
			(
				spline_picked=selection[1]
				append selected_spline_saving spline_picked
				--print spline_picked as string
				if spline_picked!=undefined do
				(
					print spline_picked as string
					making_trunk(spline_picked)
				)
			)
			catch
			(
				--print "Nothing is selected! Trying again"
			)
		)
	)
	
	---------if just making branches
	on btn_make_branches pressed do
	(
		if (classof $ == Editable_Poly) then
			(
				print"now onto branches"
				tree_sel=selection[1]
				try
				(
					building_cons 1 tree_sel
				)
				catch
				(	
					building_cons 1 tree_sel
				)
			)
			else
			(
				messageBox "Not selecting trunk!"
			)
	)
	
	------------------just to make leaves
	on btn_make_leaves pressed do
	(
		try
		(
			looking_branch=undefined
			looking_trunk=undefined
			another_check=#()
			override_check=true
			building_cons 2 sel_trunk_branch
			override_check=false
		)
		catch
		(
			print"failure to add leaves"
		)
	)
	
	------------PAINTING VERTEX 
	on btn_set_vertex pressed do
	(
		leaf_sel=selection[1]
		Vert_Paint_Leaves leaf_sel
	)
	
	-------combine meshes to trunk for pivot
	on btn_combine_selected pressed do
	(
		all_sel=getCurrentSelection()
		get_trunk=undefined
		get_trunk=selection[1]
		for obj in all_sel do
		(
			if obj!=get_trunk do
			(
				polyop.attach get_trunk obj
			)
		)
	)
	
	-------select using mat id then seperate or detach
	on btn_seperate_mat_id pressed do
	(
		all_sel=selection[1]
		subObjectLevel=4
		all_sel.EditablePoly.selectByMaterial 2
		leaf_sel=polyop.getFaceSelection all_sel
		random_no=random 1 120
		rand_name="Leaf_Ball_"+random_no as string
		polyop.detachFaces all_sel leaf_sel asNode:true name:rand_name
		
	)
	
	----this forces rounding as otherwise itll break the functions they use
	
	on sld_branch_amount changed val do
	(
		--rounding=floor(val)
		--sld_branch_amount.value=rounding
	)
	
	on sld_leaf_dens changed val do
	(
		rounding=floor(val)
		sld_leaf_dens.value=rounding
	)
	
	
)

CreateDialog bob_ross
Editor is loading...
Leave a Comment