obj = Sphere radius:30 segs:4 smooth:off pos:[20,-20,50] dir:[.5,.8,.4] xray:on
xmod = xform name:"XFormResize"
xmod[2][3].track = ScaleXYZ ()
addModifier obj xmod
xholder = attributes "XFR" 
(
	local obj, mody, ratios = #(1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
	fn getMody =  (custAttributes.getOwner this)
	fn getNode =  (refs.dependentnodes (getMody()))
	fn getSize o m = ((getModContextBBoxMax o m) - (getModContextBBoxMin o m)	)
	fn moveModyCenter mody pos = 
	(
		mody.gizmo.pos = mody.center = [0,0,0]
		mody.center = -((mody.gizmo.pos) += pos)
	)
	fn setScaleVal o m val spnSize: spnScale: rat: unif: axis: =
	(
		local size = case axis of (
			(1): (getSize o m).x
			(2): (getSize o m).y
			(3): (getSize o m).z
		)
		if unif then 
		(
			spnSize[1].value = abs(size * val/100)
			spnSize[2].value = spnSize[1].value/rat[1]
			spnSize[3].value = spnSize[1].value/rat[2]
			spnScale[1].value = val/rat[1]
			spnScale[2].value = val/rat[2]
		)
		else (spnSize[1].value = abs(size * val/100))
	)
	fn setSizeVal o m val spnScale: spnSize: rat: unif: axis: =
	(
		local size = case axis of (
			(1): (getSize o m).x
			(2): (getSize o m).y
			(3): (getSize o m).z
		)		
		if unif then 
		(
			spnScale[1].value = (val / size) * 100
			spnScale[2].value = spnScale[1].value/rat[1]
			spnScale[3].value = spnScale[1].value/rat[2]
			spnSize[1].value = val/rat[1]
			spnSize[2].value = val/rat[2]
		)
		else (spnScale[1].value = (val / size) * 100)
	)
	fn collectBBPoints o m idx: =
	(
		local minVal = (getModContextBBoxMin o m)*m.gizmo.scale
		local maxVal = (getModContextBBoxMax o m)*m.gizmo.scale
		local BBPoints = #(
			[minVal.x, minVal.y, maxVal.z], [(maxVal.x+minVal.x)/2, minVal.y, maxVal.z], [maxVal.x, minVal.y, maxVal.z], \
			[minVal.x, minVal.y, (maxVal.z+minVal.z)/2], [(maxVal.x+minVal.x)/2, minVal.y, (maxVal.z+minVal.z)/2], \
			[maxVal.x, minVal.y, (maxVal.z+minVal.z)/2], [minVal.x, minVal.y, minVal.z],	[(maxVal.x+minVal.x)/2, minVal.y, minVal.z], \
			[maxVal.x, minVal.y, minVal.z], [minVal.x, (maxVal.y+minVal.y)/2, maxVal.z], [(maxVal.x+minVal.x)/2, (maxVal.y+minVal.y)/2, maxVal.z], \
			[maxVal.x, (maxVal.y+minVal.y)/2, maxVal.z], [minVal.x, (maxVal.y+minVal.y)/2, (maxVal.z+minVal.z)/2], \
			[(maxVal.x+minVal.x)/2, (maxVal.y+minVal.y)/2, (maxVal.z+minVal.z)/2], [maxVal.x, (maxVal.y+minVal.y)/2, (maxVal.z+minVal.z)/2], \
			[minVal.x, (maxVal.y+minVal.y)/2, minVal.z], [(maxVal.x+minVal.x)/2, (maxVal.y+minVal.y)/2, minVal.z], [maxVal.x, (maxVal.y+minVal.y)/2, minVal.z], \
			[minVal.x, maxVal.y, maxVal.z], [(maxVal.x+minVal.x)/2, maxVal.y, maxVal.z], [maxVal.x, maxVal.y, maxVal.z], \
			[minVal.x, maxVal.y, (maxVal.z+minVal.z)/2], [(maxVal.x+minVal.x)/2, maxVal.y, (maxVal.z+minVal.z)/2], [maxVal.x, maxVal.y, (maxVal.z+minVal.z)/2], \
			[minVal.x, maxVal.y, minVal.z], [(maxVal.x+minVal.x)/2, maxVal.y, minVal.z], [maxVal.x, maxVal.y, minVal.z]
		)
		if idx == #all then BBPoints else BBPoints[idx]
	)
	fn showPointsInView =
	(
		local m = getMody()
		local o = (getNode())[1]
		local pntCoords = collectBBPoints o m idx:#all
		for i = 1 to pntCoords.count do
		(
			markPos = pntCoords[i]*o.transform
			--txt = i as string
			--txtPos = markPos+[0.5,0.5,0]
			gw.Marker markPos #smallCircle color:(green)
			gw.Text (markPos+[0.5,0.5,0]) (i as string) color:[150, 255, 10]
			gw.enlargeUpdateRect #whole
			gw.updateScreen()
		)
	)
	
	parameters main rollout:params (
		--sizeVals type:#floatTab tabSize:3 tabSizeVariable:true
		--scaleVals type:#floatTab tabSize:3 tabSizeVariable:true
		sizeX type:#worldUnits animatable:true ui:sizeX 
		sizeY type:#worldUnits animatable:true ui:sizeY 
		sizeZ type:#worldUnits animatable:true ui:sizeZ 
		scaleX type:#float animatable:true ui:scaleX 
		scaleY type:#float animatable:true ui:scaleY 
		scaleZ type:#float animatable:true ui:scaleZ
		uniform type:#boolean ui:uniformS default:off
		
		on uniform set val do 
		(
			if val do 
			(
				ratios = #(scaleX/scaleY, scaleX/scaleZ, scaleY/scaleX, scaleY/scaleZ, scaleZ/scaleX, scaleZ/scaleY)
				format "%\n" ratios
			)
		)
	)
	rollout params "Parameters" 
	(
		label lbl1 "              Gizmo Settings" pos:[2,5] style_sunkenedge:true width:157 height:18
		label lbl2 "     Size:                  Scale:" pos:[3,25]
		spinner sizeX "X: " fieldwidth:65 range:[0.01,1e9,1] pos:[2,40] type:#worldUnits
		spinner scaleX "" fieldwidth:58 range:[-1e5,1e5,100] pos:[90,40] controller:((getMody())[2][3][1].track)
		spinner sizeY "Y: " fieldwidth:65 range:[0.01,1e9,100] pos:[2,60] type:#worldUnits
		spinner scaleY "" fieldwidth:58 range:[-1e5,1e5,100] pos:[90,60] controller:((getMody())[2][3][2].track)
		spinner sizeZ "Z: " fieldwidth:65 range:[0.01,1e9,1] pos:[2,80] type:#worldUnits 
		spinner scaleZ "" fieldwidth:58 range:[-1e5,1e5,100] pos:[90,80] controller:((getMody())[2][3][3].track)
		checkbox uniformS "Uniform Scale" pos:[2,100]
		button resetS "reset all" width:67 height:18 pos:[93,98] 
		label lbl3 "             Center Settings" pos:[2,120] style_sunkenedge:true width:157 height:18
		label lbl5 "BBox Points:   Show In Viewport:" pos:[3,140]
		dropdownlist pntList "" width:68 pos:[2,156] items:(for i = 1 to 27 collect "point_"+i as string)
		checkbutton showHide "Show" width:88 height:20 pos:[72,156] 

		on params open do
		( 	
			obj = (getNode())[1] ; mody = getMody()
			if mody.name != "XFormResize" do mody.name = "XFormResize"
			local size = getSize obj mody
			scaleX.value = mody[2][3][1].track.value
			scaleY.value = mody[2][3][2].track.value
			scaleZ.value = mody[2][3][3].track.value
			sizeX.value = abs(size.x * scaleX.value/100)
			sizeY.value = abs(size.y * scaleY.value/100)
			sizeZ.value = abs(size.z * scaleZ.value/100)
		)
		on params close do
		(
			unRegisterRedrawViewsCallback showPointsInView
			max views redraw 
		)		
		on resetS pressed do 
		(
			local size = getSize obj mody
			scaleX.value = scaleY.value = scaleZ.value = 100
			sizeX.value = abs(size.x * scaleX.value/100)
			sizeY.value = abs(size.y * scaleY.value/100)
			sizeZ.value = abs(size.z * scaleZ.value/100)
			ratios = #(1.0, 1.0, 1.0, 1.0, 1.0, 1.0)	
		)
		on showHide changed state do
		(
			if state == on then 
			(
					showHide.text = "Hide"
					unRegisterRedrawViewsCallback showPointsInView
					registerRedrawViewsCallback showPointsInView
					max views redraw
			)
			else 
			(
				showHide.text = "Show"
				unRegisterRedrawViewsCallback showPointsInView
				max views redraw 
			)
		)
		on pntList selected itm do 
		(
			local pos = collectBBPoints obj mody idx:itm
			with redraw off moveModyCenter mody (pos*obj.transform)
		)
			
		on sizeX changed val do (setSizeVal obj mody val spnScale:#(scaleX,scaleY,scaleZ) spnSize:#(sizeY,sizeZ) rat:#(ratios[1],ratios[2]) unif:uniform axis:1)
		on sizeY changed val do (setSizeVal obj mody val spnScale:#(scaleY,scaleX,scaleZ) spnSize:#(sizeX,sizeZ) rat:#(ratios[3],ratios[4]) unif:uniform axis:2)
		on sizeZ changed val do (setSizeVal obj mody val spnScale:#(scaleZ,scaleX,scaleY) spnSize:#(sizeX,sizeY) rat:#(ratios[5],ratios[6]) unif:uniform axis:3)
		
		on scaleX changed val do (setScaleVal obj mody val spnSize:#(sizeX,sizeY,sizeZ) spnScale:#(scaleY,scaleZ) rat:#(ratios[1],ratios[2]) unif:uniform axis:1)
		on scaleY changed val do (setScaleVal obj mody val spnSize:#(sizeY,sizeX,sizeZ) spnScale:#(scaleX,scaleZ) rat:#(ratios[3],ratios[4]) unif:uniform axis:2)
		on scaleZ changed val do (setScaleVal obj mody val spnSize:#(sizeZ,sizeX,sizeY) spnScale:#(scaleX,scaleY) rat:#(ratios[5],ratios[6]) unif:uniform axis:3)
	)
) 
custattributes.add xmod xholder #unique
--clearListener()
--$.modifiers[1].XFR.sizeVals
