Skip to content

Instantly share code, notes, and snippets.

@Onefabis
Last active October 13, 2018 13:24
Show Gist options
  • Save Onefabis/2916fe6cf4e0048b0ff08d748938dfd5 to your computer and use it in GitHub Desktop.
Save Onefabis/2916fe6cf4e0048b0ff08d748938dfd5 to your computer and use it in GitHub Desktop.
Inserts object inside mesh just in the middle of the of the intersection of the camera ray and all geo in the scene
'''
Instructions:
To run the script just ise the code:
________________________________________________________________
import inMeshPlace
inMeshPlace.start()
________________________________________________________________
This script works in 3 modes:
1. If you run the script without any mesh selected, it will insert object in the approximate point of the ray that intersect all visible meshes in the scene.
2. If you run the script with one/many selected meshes, it will insert object in the approximate point of the ray that intersect all selected meshes in the scene.
3. If you select components and run the script, it will consider in computations only that component, i.e. it will compute approximate point under cursor only that was already selected.
Nota bene:
If you've clicked in the mesh and changed your mind about exact position, you can slide cursor before LMB release
'''
import maya.api.OpenMaya as om2
import maya.OpenMayaUI as omui
import maya.api.OpenMayaUI as omui2
import maya.cmds as mc
from functools import partial
try:
from PySide import QtGui, QtCore
import shiboken as shiboken
from shiboken import wrapInstance
except ImportError:
from PySide2 import QtGui, QtCore
import PySide2.QtWidgets as QtWidgets
import shiboken2 as shiboken
from shiboken2 import wrapInstance
class InMeshPlace( object ):
def __init__( self ):
self.obj = 'joint'
def UI( self ):
winName = 'InMeshPlace'
if mc.window( winName, ex=1 ):
mc.deleteUI( winName )
mainWin = mc.window( winName, s=1, mxb=0, mnb=0 )
mainLayout = mc.formLayout( p=mainWin )
objects = [ 'joint', 'spaceLocator', 'group', 'circle', 'polyCube' ]
self.inplaceTF = mc.textField( cc=partial(self.insetText, 0 ), p=mainLayout )
mc.popupMenu()
for o in xrange( len(objects) ):
exec( 'self.menuItem%i = mc.menuItem( l="%s", c=partial(self.insetText,"%s") ) ' % ( o, objects[o], objects[o] ) ) in globals(), locals()
self.inplaceBN = mc.button( l='Place', h=30, c=lambda *x: self.startContext(1) )
if mc.optionVar( ex='inmeshplace' ):
txt = mc.optionVar( q='inmeshplace' )
mc.textField( self.inplaceTF, e=1, tx=txt )
mainWindow = shiboken.wrapInstance( long( omui.MQtUtil.findControl(mainWin) ), QtWidgets.QWidget )
mainWindow.setStyleSheet( 'QWidget {background-color:#3a404e;}' )
widgets = mainWindow.findChildren(QtWidgets.QWidget)
for w in widgets:
wtType = w.metaObject().className()
if wtType == 'QmayaField':
w.setStyleSheet( 'QmayaField {background-color:#282e35; border: 1px solid #1e2328; border-radius: 3px; color: #9dbfd5 }' )
elif wtType == 'QPushButton':
w.setStyleSheet( 'QPushButton {background-color:#495572; border: 1px solid #4a6288; border-radius: 3px; color: #aac6dc }' )
mc.formLayout( mainLayout, e=1, af=( self.inplaceTF, "top", 15 ) )
mc.formLayout( mainLayout, e=1, af=( self.inplaceTF, "left", 15 ) )
mc.formLayout( mainLayout, e=1, af=( self.inplaceTF, "right", 15 ) )
mc.formLayout( mainLayout, e=1, ac=( self.inplaceBN, "top", 10, self.inplaceTF ) )
mc.formLayout( mainLayout, e=1, af=( self.inplaceBN, "left", 15 ) )
mc.formLayout( mainLayout, e=1, af=( self.inplaceBN, "right", 15 ) )
mc.showWindow(mainWin)
mc.window( winName, e=1, wh=( 150, 90 ) )
def insetText( self, name, part):
if name:
mc.textField( self.inplaceTF, e=1, tx=name )
else:
name = mc.textField( self.inplaceTF, q=1, tx=1 )
mc.optionVar( sv=( 'inmeshplace', name ) )
def startContext( self, mode=0 ):
self.ctx = 'mContext'
if mode == 1:
self.obj = mc.textField( self.inplaceTF, q=1, tx=1 )
if mc.draggerContext(self.ctx, exists=1):
mc.deleteUI(self.ctx)
mc.draggerContext(self.ctx, releaseCommand=self.onRelease, name=self.ctx, cursor='crossHair')
mc.setToolTo(self.ctx)
self.pId = None
self.allMeshTransform = mc.ls( sl=1, v=1 )
if not self.allMeshTransform:
self.allMesh = mc.ls( type='mesh', v=1 )
elif self.allMeshTransform:
vertextCheck = mc.filterExpand( self.allMeshTransform[0], sm=31 )
edgeCheck = mc.filterExpand( self.allMeshTransform[0], sm=32 )
faceCheck = mc.filterExpand( self.allMeshTransform[0], sm=34 )
if vertextCheck or edgeCheck or faceCheck:
self.allMesh = [ mc.listRelatives( x, p=1, typ='mesh' )[0] for x in self.allMeshTransform if mc.listRelatives( x, p=1, typ='mesh' ) ]
borderComp = mc.polyListComponentConversion( self.allMeshTransform, tf=1, border=1 )
allComp = mc.polyListComponentConversion( self.allMeshTransform, tf=1 )
if self.allMeshTransform:
if vertextCheck:
self.pId = [ int( x[x.find("[") + 1:x.find("]")] ) for x in mc.ls( allComp, fl=1 ) if x not in mc.ls( borderComp, fl=1 ) ]
else:
self.pId = [ int( x[x.find("[") + 1:x.find("]")] ) for x in mc.ls( allComp, fl=1 ) ]
else:
return
else:
self.allMesh = [ mc.listRelatives( x, s=1, typ='mesh' )[0] for x in self.allMeshTransform if mc.listRelatives( x, s=1, typ='mesh' ) ]
def onRelease( self ):
allVectors = {}
pos = om2.MPoint()
dir = om2.MVector()
vp = mc.draggerContext( self.ctx, q=1, dp=1 )
omui2.M3dView().active3dView().viewToWorld(int(vp[0]), int(vp[1]), pos, dir)
for mesh in self.allMesh:
selectionList = om2.MSelectionList()
selectionList.add(mesh)
dagPath = selectionList.getDagPath(0)
fnMesh = om2.MFnMesh(dagPath)
if self.pId:
intersection = fnMesh.allIntersections(om2.MFloatPoint(pos), om2.MFloatVector(dir), om2.MSpace.kWorld, 99999, 0, faceIds=self.pId )
else:
intersection = fnMesh.allIntersections(om2.MFloatPoint(pos), om2.MFloatVector(dir), om2.MSpace.kWorld, 99999, 0 )
for i in intersection[0]:
allVectors[ ( om2.MVector( pos ) - om2.MVector( i ) ).length() ] = om2.MVector( i )
if allVectors:
mc.select( cl=1 )
maxLength = max( allVectors, key=float )
minLength = min( allVectors, key=float )
fVec = allVectors[ maxLength ]
sVec = allVectors[ minLength ]
point = [ (x + y) / 2 for x, y in zip( fVec, sVec ) ]
if self.obj == 'group':
newObj = eval( 'mc.' + self.obj + '(em=1)' )
mc.setAttr( newObj + '.displayHandle', 1 )
else:
newObj = eval( 'mc.' + self.obj + '()' )
mc.xform( newObj, ws=1, t=point )
if self.allMeshTransform:
mc.select( cl=1 )
mc.select( self.allMeshTransform, r=1 )
else:
mc.select( cl=1 )
def start():
InMeshPlace().UI()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment