For anyone else who looks at this thread (as it's fairly old):
Although the manual methods are probably useful for other software, (eg. Blender), in Maya there are already nodes that do this. I use the 'follicle' node. There is another one called 'pointOnSurfaceInfo' (nurbsSurfaces only) and another for muscle attachments ('cMuscleSurfAttach', which I haven't really tried - but apparently sticks to a nurbsSurface or a specific mesh face with adjustable UV.)
The follicle node has U and V parameters, and can take either a mesh or a nurbsSurface as input. (Note: It treats the UVs of a nurbsSurface as normalised (0.0 to 1.0) even if they aren't.) It also aligns itself to the normal and U tangent of a surface.
The easiest way to create one of these nodes is to create a hair via the menu Dynamics/Hair/Create hair, then delete the hair nodes. Otherwise the node can be created directly, using 'createNode', and manually connected up; my example is using Python (PyMel) as I took it from one of my scripts but the main commands can transfer to MEL easily enough.
import pymel.core as pm
patch = pm.PyNode("pCube1")
patchIsNurb = False
useSmoothedMesh = False
name = "TestFollicle1"
# Create a follicle and name the transform
fol = pm.createNode('follicle', ss=1)
folXform = pm.rename(fol.getParent(), name)
#fol = folXform.getShape() # This line is not required in PyMel; fol updates itself when renamed.
# Set up the follicle
pm.connectAttr(fol.outTranslate, folXform.t)
pm.connectAttr(fol.outRotate, folXform.r)
pm.connectAttr(patch.worldMatrix[0], fol.inputWorldMatrix)
if patchIsNurb:
pm.connectAttr(patch.local, fol.inputSurface)
elif useSmoothedMesh:
pm.connectAttr(patch.outSmoothMesh, fol.inputMesh)
else:
pm.connectAttr(patch.outMesh, fol.inputMesh)
# For testing on a default pCube (otherwise it misses the UVs)
fol.parameterU.set(0.5)
fol.parameterV.set(0.375)