cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

rivets

rivets

Add rivets.

18 Comments
tj.galda
Alumni
Status changed to: Under Review

We're looking in to this and have something in our beta already.  Would love to get more detail on how you want to see the workflow.  We have some ideas in mind, but the more detail you give here the better.

userX4542
Advocate

Hi Tj,

Thanks for replying. That's great news! I think it should be kept fairly simple. For example, select a vertex/face/edge and click a rivet button t create a rivet on that specific point. 

 

It would be nice if it had a toggle for following the normals. But if you dont want rotation, it should be able to stay fixed. 

 

In theory it could be a locator but like i have said in a previous post, locators have problems when you freeze transformation and then bake its pivot in order to get its SRT values in the channel box. So thats a bit tricky for rigging. But whether it's a group, a locator or something new, i dont mind. 

jwlove
Advocate

I think you could make them function similar to follicles but without all the extra bloat the follicle nodes have for hair systems.  The output should be translate/rotate/scale(?) values that you can then plug into a transform.  PLEASE no shape/transform node inserted into the hierarchy (it does not need to be a DAG node)....

 

For nurbs, inputs would be as simple as a surface, and uv parameters, maybe an additional attribute for whether u or v should be treated as the up axis (the normal would be the aim)

 

For polys a good idea for inputs is a little harder... maybe uv parameters (but that requires uvs)?  Maybe a poly face with some sort of implicit uv parameters within that face for position?  Maybe along an edge?  Maybe a vertex that would give very easy position values.  Maybe several vertices, it would need to keep relative distance between those verts along the surface...  If you attach it anywhere but on a vertex, you need some way to specify it's position (where inside the face? where along the curve? where in relation to multiple verts?).  You would also need some way of getting orientation (uvs, maybe?)  I think follicles work off the uv parameters, so maybe that's fine (although, getting a specific vertex's position data could be nice too)?

 

Essentially, a node that does what the simple 4x4 matrix/decompose matrix node network toward the bottom of this blog post does:

https://bindpose.com/maya-matrix-nodes-part-3-matrix-rivet/

 

As for workflow, I script most things, so I would just create it manually, hook up the inputs, and output it to a transform I also created; however, for interactive use, maybe you could provide a surface/poly and a node (transform) you want to rivet (the transform should be positioned where you want it to "stick"), then you run the command/click the ui rivet button, and it determines the appropriate closest uv values and stuff for you... You could have an option for creating a buffer transform or not - say the user created geometry shaped like a button and wants to rivet it to a shirt - directly driving the button's transform would move/rotate it, so inserting a buffer node and then auto-parenting it could be a nice feature (although unnecessary if you have and empty transform)

forrest.brent
Enthusiast

Until that beautiful day when Maya comes packed with rivets and array math nodes, here you can use this. 

https://www.youtube.com/watch?v=d30hvpxFluU

My free tool allows you to create one or many rivets at once, reposition them after creation and move them freely while still retaining their parent influence.

tj.galda
Alumni
Status changed to: Accepted
 
tj.galda
Alumni
Status changed to: Accepted
 
tj.galda
Alumni
Status changed to: Implemented

Thanks for the awesome idea!  We've taken this & run with it.  Check out what we put into Maya 2020.

 

Keep the comments & good ideas rolling in, we're listening!

 

tj

userX4542
Advocate

Thanks TJ. Great to see this new feature implemented with lots of nice additional options. Big thumbs up

j.victor.ferreira
Enthusiast

Hi TJ!

There is some way to place a rivet in a vertex via python?

thanks!

forrest.brent
Enthusiast

 

 

import maya.cmds
import re
from functools import wraps


def bRivet():

    input = maya.cmds.filterExpand(sm = 32)
    if input and len(input) >=2:  
        ob = input[0].split('.')[0]
        edgeMax = maya.cmds.polyEvaluate(ob, e=True)
        shape = maya.cmds.listRelatives(ob, shapes=True)
        count = len(input)
        try:
            bRivet_Build(input,ob,edgeMax,shape, count)
        except:
            maya.cmds.warning('I don\'t like that mesh')
    else:
        maya.cmds.warning('bRivet requires at least 2 edges to be selected')


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

    cA = maya.cmds.connectAttr
    sA = maya.cmds.setAttr
    aA = maya.cmds.addAttr
    cN = maya.cmds.createNode
    
    doublet = zip(range(count-1),range(1, count))
    locs = []
    
    for pair in doublet:
                    
        var = [['pointOnSurfaceInfo','pos'],['loft','loft'],['fourByFourMatrix','mat'],['decomposeMatrix','dcp']]
        pnt = ['normal', 'tangentU.tangentU', 'tangentV.tangentV', 'position.position']
        xyz = ['X','Y','Z']
        uv = 'UV'        
        
        for n in range(4):
            var[n][1] = cN(var[n][0], name = var[n][1])
            
        loc = maya.cmds.spaceLocator(name = 'rivet')   
        sA('%s.turnOnPercentage' % var[0][1], 1)
        sA('%s.degree' % var[1][1], 1)
        aA(loc[0], at = 'float2', ln= uv) 
                    
        for one in [0,1]:
            num = int(re.findall("\[(.*?)\]", input[pair[one]])[0])
            ed = cN('curveFromMeshEdge', name = 'cFM')
            aA(loc[0], at = 'float' , ln = uv[one], k = True, p= uv, min = 0, max = 1)   
            aA(loc[0], at = 'short' , ln = 'edgeIndex%d' % one, min = 0, max = edgeMax, k = True, dv = num)   
            sA('%s.edgeIndex[0]' % ed, num)   
            cA('%s.edgeIndex%d' % (loc[0],one), '%s.edgeIndex[0]' % ed)   
            cA('%s.worldMesh[0]' % shape[0] , '%s.inputMesh' % ed)
            cA('%s.outputCurve' % ed, '%s.inputCurve[%s]' % (var[1][1], one))
    
        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.outputSurface' % var[1][1], '%s.inputSurface' % var[0][1])
        cA('%s.output' % var[2][1], '%s.inputMatrix' % var[3][1])
        cA('%s.outputTranslate' % var[3][1], '%s.t' % loc[0])
        cA('%s.outputRotate' % var[3][1], '%s.r' % loc[0])

        locs.append(loc[0])

    maya.cmds.select(locs)
    
bRivet()

 

It's not the cleanest - and it's pretty old but this will give you everything you need

 

forrest.brent
Enthusiast

I've edited the code, try runnnig it again - this time select two edges before running bRivet()

when the rivet is made, select the locator and change the U and V value in the channel box until the rivet lies over the vertex you want.

j.victor.ferreira
Enthusiast

Thanks a lot for the help, Forrest. your script is amazing, but unfortunatelly its working with the same behavior of pointOnPoly constraint.. it interprets the normals differently from the rivet command (maya 2020).

I am attaching an image to show you what I mean... one point was created with rivet command, another one with the script you sent me.. I aligned boxes to each of them before translating the vertex..

So when I translate the vertex, the boxes unmatches... 😕

But thanks a lot for your help! 🙂

cheers!Sem Título-1.jpg

forrest.brent
Enthusiast

I see, you want something that approximates the normal of the neighboring points - that's something I'll have to think about for the future

j.victor.ferreira
Enthusiast

No problem, thanks a lot! 🙂

will.telford
Alumni

The following code will create a rivet on the selected components in Maya 2020 and above

from maya import cmds
cmds.Rivet()

 

 

j.victor.ferreira
Enthusiast

hi @will.telford !! thx for replying!!

the command is very useful.. but would you know some faster way to apply rivets? maybe via openmaya api?
Im asking that because I would need to apply the rivets in a 20k times loop.

thanks!!

will.telford
Alumni

@j.victor.ferreira ,

The rivet command works on multiple components at a time, so if you have selected 20k components, the command will create 20k rivets for you.

 

The rivet command is nothing more than a wrapper around the uvPin node creation that uses a simplified set of options. You'll notice that after it is created you have a uvPin node.

 

The uvPin node uses a new python framework for creation, so all the python scripts that create it are available to you for inspection. You'll notice it is wrapped in an "internal" namespace though. This is because it is not yet a public API as we clean some things up. So expect the following code to change on you.

 

To inspect it you can do the following. Turn on echo all commands in your script editor. Then run the rivet command. You'll see it will spit out something like this.

python("import maya.internal.nodes.uvpin.node_interface");python("maya.internal.nodes.uvpin.node_interface.createRivet()");

Which runs the following in python

import maya.internal.nodes.uvpin.node_interface
maya.internal.nodes.uvpin.node_interface.createRivet()

Depending on your install location you will find that modules here

Maya2020/Python/Lib/site-packages/maya/internal/nodes/uvpin

The createRivet method above is defined in this file

Maya2020/Python/Lib/site-packages/maya/internal/nodes/uvpin/node_interface.py

 

You will see it defined at the bottom of the file as

def createRivet():
    import maya.internal.nodes.uvpin.cmd_create as ptguv
    ptguv.Command().execute(setupMode=0, outputConnect=3, allowCreateWithoutInputs=False)

 Following that import takes you to

/mnt/c/Program Files/Autodesk/Maya2020/Python/Lib/site-packages/maya/internal/nodes/uvpin/cmd_create.py

 

In that file you will see all the python logic to create the Rivet.

However since the uvPin node is procedural, you won't need any of the above. You really only need to do

cmds.createNode('uvPin')

followed by some

cmds.setAttr()

and

cmds.connectAttr()

 

j.victor.ferreira
Enthusiast

Hi @will.telford  !

Thanks a lot for sending these information, I will try to understand everything you wrote, and apply these techniques.

I will let you know if it will work fine here!

thanks a lot again!

 

João

Can't find what you're looking for? Ask the community or share your knowledge.

Submit Idea