Dont know if the thread starter still messes with getting good seams but meanwhile i also played al ittle bit around with this and put together some lines, maybe others also have use for it, anyway.
It roughly works like described above, although it now uses a locator bound to a motion path which has the world up vector linked to the surface normal of the "cloth" object. The motion paths U parameter handling is set to fractional length so the distribution of seam objects is absolutely even. The locator carries the seam object to all specific curve divisions and creates a duplicate, done.
It outputs the seam objects in two types: as simple copys or as instanced objects (by a particle instancer). However if the instancer is used the seam objects transformations will be set to zero first, and so its harder to adjust rotation afterwards.
Usage:
Parent all members (cloth object, seam curve and seam object) to world space first to avoid unpredictable results (means that seam curves must not be of type curve on surface, convert them into a regular curve first).
Move the seam object to the start(!) position of the seam curve and add select (in this order) "cloth" surface / seam curve / seam object
and execute the script with following switches:
distributeOnSurface(int $numObjects, int $alignToSurface, int $useInstancer)
//example: distributeOnSurface 100 1 0
where $numObjects is obviously the count of seam objects, $useInstancer (meant as bool) does like said above and $alignToSurface (also meant as bool) fixes a the following issue: if creating nurbs curves on a live made surface they become parented under the nurbs surfaces parametric space and thus align perfectly on the surface and make up good seam paths, but using meshes this wont work as precisely. The curves would have different distances to curvy mesh surfaces at different curve locations so the seam objects would submerge into the surface or stand away. So the closest point of the cloth surface is token to set up the seam object location. However the spacing between each neighbour point on surface doesnt match the spacing of the curve divisions so using align to surface might produce uneven seam object distribution. If you want to create prefect seam curves on meshes you can use the "polyNurbsIntersect" script here from maya download section, it can create intersection curves from a nurbs surface with a mesh surface.
global proc distributeOnSurface(int $numObj, int $alignToSurface, int $useInstancer)
{
cycleCheck -e off;
string $sel[] = ls -long -sl
;
string $moLoc[] = spaceLocator
;
string $moPath = pathAnimation -fractionMode true -follow true -worldUpType "vector" $sel[1] $moLoc[0]
;
string $infoNode[], $infoAttr[];
string $shape[] = listRelatives -children $sel[0]
;
if(nodeType $shape[0]
== "nurbsSurface")
{
$infoNode[0] = createNode closestPointOnSurface
;
$infoNode[1] = createNode pointOnSurfaceInfo
;
connectAttr -f ($sel[0] + ".worldSpace[0]") ($infoNode[0] + ".inputSurface");
connectAttr -f ($sel[0] + ".worldSpace[0]") ($infoNode[1] + ".inputSurface");
connectAttr -f ($infoNode[0] + ".parameterU") ($infoNode[1] + ".parameterU");
connectAttr -f ($infoNode[0] + ".parameterV") ($infoNode[1] + ".parameterV");
$infoAttr = {($infoNode[0] + ".inPosition"),($infoNode[0] + ".position"),($infoNode[1] + ".normal")};
}
else if(nodeType $shape[0]
== "mesh")
{
loadPlugin -quiet "nearestPointOnMesh";
if(! pluginInfo -query -loaded "nearestPointOnMesh"
) error("unable to load nearestPointOnMesh.mll");
$infoNode[0] = createNode nearestPointOnMesh
;
connectAttr -f ($sel[0] + ".outMesh") ($infoNode[0] + ".inMesh");
$infoAttr = {($infoNode[0] + ".inPosition"),($infoNode[0] + ".position"),($infoNode[0] + ".normal")};
};
connectAttr -f $infoAttr[2] ($moPath + ".worldUpVector");
vector $rotatePP[];
string $positionPP[], $dObj[];
for($i=0;$i<$numObj;$i++)
{
setAttr ($moPath + ".uValue") ((1.0 / ($numObj - 1)) * $i);
float $p0[] = `xform -q -ws -t $moLoc[0]`;
setAttr $infoAttr[0] $p0[0] $p0[1] $p0[2];
float $p1[] = `getAttr $infoAttr[1]`;
if($i == 0)
{
if($useInstancer) makeIdentity -a 1 -t 1 -r 1 $sel[2];
$dObj = `duplicate -rr $sel[2]`;
parent $dObj[0] $moLoc[0];
};
if($useInstancer)
{
if($i == 0)
{
appendStringArray $dObj `duplicate -rr $sel[2]` 1;
move -r (0 - $p0[0]) (0 - $p0[1]) (0 - $p0[2]) $dObj[1];
makeIdentity -a 1 -t 1 -r 1 $dObj[1];
connectAttr -f ($sel[2] + ".rotate") ($dObj[1] + ".rotate");
connectAttr -f ($sel[2] + ".scale") ($dObj[1] + ".scale");
setAttr ($sel[2] + ".template") 1;
setAttr ($dObj[1] + ".template") 1;
};
$rotatePP[$i] = `xform -q -ws -rotation ("|" + $moLoc[0] + "|" + $dObj[0])`;
if($alignToSurface) $positionPP[$i] = $p1[0] + " " + $p1[1] + " " + $p1[2];
else $positionPP[$i] = $p0[0] + " " + $p0[1] + " " + $p0[2];
}
else if($i >= 1)
{
string $newObj[] = `duplicate -rr ("|" + $moLoc[0] + "|" + $dObj[0])`;
$newObj = `parent -w $newObj[0]`;
if($alignToSurface) move -r ($p1[0] - $p0[0]) ($p1[1] - $p0[1]) ($p1[2] - $p0[2]) $newObj[0];
};
};
if($useInstancer)
{
string $particleObj[] = eval("particle -p " + stringArrayToString $positionPP " -p "
);
addAttr -ln userVector1PP -dt vectorArray $particleObj[1];
addAttr -ln userVector1PP0 -dt vectorArray $particleObj[1];
for($i=0;$i<$numObj;$i++)
{
vector $r = $rotatePP[$i];
particle -e -order $i -at userVector1PP -vv ($r.x) ($r.y) ($r.z) $particleObj[1];
};
saveInitialState $particleObj[1];
particleInstancer -a -obj $dObj[1] -rotationUnits Degrees -rotationOrder XYZ -p worldPosition -r userVector1PP $particleObj[1];
};
delete $moLoc[0] $moPath $infoNode;
select $sel[2];
};
// as always use at your own risk of loosing scene data, exploding workstations etc.