Multi-Rivet

by BFXTD posted 106 days ago | 3 comments

Just testing the waters with my first post. This is a rivet simliar to others you might find with three major differences:

  1. This rivet is built with the "Matrix-constraint" setup found on bindpose.com
  2. This tool creates multiple rivets at once
  3. You can move the rivets both in free space, and by changing the influences edges after creation.

import maya.cmds as cmd import re

def bRivet():

input = cmd.filterExpand(sm = 32)
if not (cmds.pluginInfo('matrixNodes', q=True, l=True)):
    cmds.loadPlugin( 'matrixNodes' )
if input and len(input) >=2:  
    ob = input[0].split('.')[0]
    edgeMax = cmd.polyEvaluate(ob, e=True)
    shape = cmds.listRelatives(ob, shapes=True)
    count = len(input)
    cmds.undoInfo( state=False )  
    try:
        bRivet_Build(input,ob,edgeMax,shape, count)
    except:
        cmd.warning('Something is not right')
    cmds.undoInfo( state=True ) 
else:
    cmd.warning('bRivet requires at least 2 edges to be selected')

def bRivet_Build(input, ob, edgeMax, shape, count):

cA = cmd.connectAttr
sA = cmd.setAttr
aA = cmd.addAttr
cN = cmd.createNode
var = [['pointOnSurfaceInfo','pos'],['loft','loft'],['fourByFourMatrix','mat'],['decomposeMatrix','dcp']]
pnt = ['normal', 'tangentU.tangentU', 'tangentV.tangentV', 'position.position']
xyz = ['X','Y','Z']
io = ['input', 'output']
uv = 'UV'        
doublet = zip(range(count-1),range(1, count))
locs = []
node = 1

for pair in doublet:
    for n in range(4):
        var[n][1] = cN(var[n][0], name = var[n][1])
    gp = cmd.group(em = True, name = 'rivet%s_GP' % node )
    loc = cmd.spaceLocator(name = 'rivet%s' % node)   
    sA('%s.turnOnPercentage' % var[0][1], 1)
    sA('%s.degree' % var[1][1], 1)
    aA(loc[0], at = 'float2', ln= uv) 
    cmd.parent(loc, gp)
    node+=1

    for one in [0,1]:    
        num = int(re.findall("\[(.*?)\]", input[pair[one]])[0])
        aA(loc[0], at = 'short' , ln = 'edgeIndex%d' % one, min = 0, max = edgeMax, k = True, dv = num)
        ed = cN('curveFromMeshEdge', name = 'cFM')
        sA('%s.edgeIndex[0]' % ed, num)   
        cA('%s.edgeIndex%d' % (loc[0],one), '%s.edgeIndex[0]' % ed)   
        cA('%s.worldMesh[0]' % shape[0] , '%s.%sMesh' % (ed,io[0]))
        cA('%s.outputCurve' % ed, '%s.%sCurve[%s]' % (var[1][1],io[0],one))
        aA(loc[0], at = 'float' , ln = uv[one], k = True, p= uv, min = 0, max = 1)   
    print 'ok%s'%node

    for UV in uv:
        cA('%s.UV.%s' % (loc[0], UV), '%s.parameter%s' % (var[0][1], UV))
        sA('%s.UV.%s' % (loc[0], UV), 0.5)

    for i in range(4):
        for j in range(3):
            o =  xyz[j]
            if i in [1,2]: o = o.lower()
            cA('%s.%s%s' %(var[0][1], pnt[i], o), '%s.in%s%s' % (var[2][1], i, j))

    cA('%s.%sSurface' % (var[1][1],io[1]), '%s.%sSurface' % (var[0][1],io[0]))
    cA('%s.%s' %  (var[2][1],io[1]), '%s.%sMatrix' % (var[3][1],io[0]))
    cA('%s.%sTranslate' % (var[3][1],io[1]), '%s.t' % gp)
    cA('%s.%sRotate' % (var[3][1],io[1]), '%s.r' % gp)

    locs.append(loc[0])

cmd.select(locs)

bRivet()

by Orkah posted 105 days ago

Definetly gonna test this one =), thx

by sskey posted 19 days ago

you can improve it, you can work with locator placed at the center of the object you want to rvt and then launch the proc.

When you use rvt it is otfen to attach something, so i think it could be nice to have also the possiblity to select the object and then create a rivet based on the center worldspace position of this object directly, so you don't have to create the rivet then have another proc to attach object.

Order selection would be ojbects to me be attach and then the geo driver. You take the worldpace position, determine the closest point on poly, extract edge and create rivet --> matrix constraint or parent constraint the object. ??