From KokkugiaWiki
Option Explicit
'------------------------------------------------------------------------------
' Subroutine: scaleBySurface
' Purpose: scales muliple objects based on z height of surface - UV coords
' Author: Roland Snooks | 2006 | www.kokkugia.com
'------------------------------------------------------------------------------
Sub scaleBySurface
Dim arrObjects, ctrlSrf, arrObjBBox, bboxX, bboxY, arrDomU, arrDomV, arrSrfBBox, srfZ, i, arrBBox, objCenter, NobjCenter, arrPoint, zScale, scaleF
' input
arrObjects = Rhino.GetObjects("pick objects to scale", 0)
ctrlSrf = Rhino.GetObject("pick control surface", 8)
scaleF = Rhino.GetReal("scale factor", 3)
Rhino.Print "i'm working on it"
' get objects bbox
arrObjBBox = Rhino.BoundingBox(arrObjects)
bboxX = Abs(arrObjBBox(0)(0) - arrObjBBox(2)(0))
bboxY = Abs(arrObjBBox(0)(1) - arrObjBBox(2)(1))
' get srf domain
arrDomU = Rhino.SurfaceDomain(ctrlSrf, 0)
arrDomV = Rhino.SurfaceDomain(ctrlSrf, 1)
'srf bounding boxes
arrSrfBBox = Rhino.BoundingBox(ctrlSrf, , vbTrue)
srfZ = Abs(arrSrfBBox(0)(2) - arrSrfBBox(4)(2))
' loop through each object
For i = 0 To UBound(arrObjects)
arrBBox = Rhino.BoundingBox(arrObjects(i))
objCenter = Array((((arrBBox(2)(0)) + (arrBBox(0)(0))) / 2), (((arrBBox(2)(1)) + (arrBBox(0)(1))) / 2), 0)
NobjCenter = Array(((1/bboxX) *(Abs(objCenter(0) - arrObjBBox(0)(0)))), ((1/bboxY) *(Abs(objCenter(1) - arrObjBBox(0)(1)))), 0)
arrPoint = Rhino.EvaluateSurface(ctrlSrf, Array((NobjCenter(0) * Abs(arrDomU(1) - arrDomU(0))), (NobjCenter(1) * Abs(arrDomV(1) - arrDomV(0)))))
zScale = scaleF*(1-((1 / srfZ) * Abs(arrPoint(2)-arrSrfBBox(0)(2))))
' scale object
Rhino.ScaleObject arrObjects(i), objCenter, array(zScale,zScale,zScale)
Next
Rhino.Print "done"
End Sub
scaleBySurface