def createController(object): # object = pma.ls(sl=True) pivotObj = pma.xform(object, query=True, t=True, worldSpace=True) edges = pma.filterExpand(pma.polyListComponentConversion(te=1), sm=32, ex=1) # convert edges to curve ancd create one object for edge in edges: vtx = pma.ls(pma.polyListComponentConversion(edge, fe=1, tv=1), fl=1) p1 = pma.pointPosition(vtx[0]) p2 = pma.pointPosition(vtx[1]) curves = pma.curve(n="line_ctrl_curve", d=1, p=(p1, p2)) ctrl = pma.curve(n="bool_ctrl", d=1, ws=True, p=pivotObj) pma.xform(centerPivots=True) for curveEdge in pma.ls("line_ctrl*"): pma.parent(curveEdge, ctrl, s=1, r=1) pma.rename(curveEdge, "shapeunused") transforms = pma.ls(type='transform') deleteList = [] for tran in transforms: if pma.nodeType(tran) == 'transform': children = pma.listRelatives(tran, c=True) if children is None: # print '%s, has no childred' %(tran) deleteList.append(tran) if not deleteList: pma.delete(deleteList) return ctrl
def hs_verts(self, f1, f2): """ this function finds the average of the face normals on each side of an edge then adjusts the vtx normals to that average """ average_n = (f1.getNormal(space='world') + f2.getNormal(space='world')) / (2, 2, 2) verts1 = pm.polyListComponentConversion(f1, fromFace=True, toVertex=True) pm.select(verts1) v1 = pm.ls(sl=True, flatten=True) verts2 = pm.polyListComponentConversion(f2, fromFace=True, toVertex=True) pm.select(verts2) v2 = pm.ls(sl=True, flatten=True) sVerts = [i for i in v1 if i in v2] pm.select(sVerts) pm.polyNormalPerVertex(normalXYZ=average_n)
def projectSelection(self): hiliteOrig = pm.ls(hilite=True) selOrig = pm.ls(selection=True) selPre = pm.polyListComponentConversion(selOrig, tv=True) try: pm.select(self.referenceXformNode, replace=True) pm.select(selPre, add=True) selForTransfer = pm.ls(selection=True) pm.transferAttributes( transferPositions=1, transferNormals=0, transferUVs=0, transferColors=0, sampleSpace=0, searchMethod=0 ) objsToAddToSelection = [] for o in selForTransfer: # s = str( type(o) ) # print "y" + s + "y" if str(type(o)) == "<class 'pymel.core.general.MeshVertex'>": n = o.name().split(".")[0] objsToAddToSelection.append(n) for obj in objsToAddToSelection: pm.select(obj, add=True) pm.delete(ch=True) ##was #pm.mel.eval( "DeleteHistory;" ) print(selForTransfer) pm.select(selOrig, replace=True) pm.hilite(hiliteOrig) except: pm.select(selOrig) pm.hilite(hiliteOrig) print( "Please ensure that you have a valid reference mesh selected, and that you have verticies or objects select to project." )
def deleteNegativeSide( self, selectionToFilter = None ): if selectionToFilter == None: selectionToFilter = pm.ls(selection=True) ## Bail early if we have no selected things to operate on! if len(selectionToFilter) == 0: return pm.mel.eval( 'PolySelectConvert 3;') verts = pm.ls(selection=True, flatten=True) vertsToDelete= [] for vert in verts: x,y,z = pm.pointPosition( vert ) if x < -0.0000000001: print( "For vert at:"+str(x) ) vertsToDelete.append( vert ) try: ## fv and tf mean fromVertex, toFace facesToDelete = pm.polyListComponentConversion( vertsToDelete, fv=True, tf=True) faceToDelete = pm.ls(facesToDelete, flatten=True) pm.delete( facesToDelete ) pm.select( selectionToFilter ) except: print("Minor exception. No faces are on negative side to delete.")
def projectSelection(self): hiliteOrig = pm.ls(hilite=True) selOrig = pm.ls(selection=True) selPre = pm.polyListComponentConversion(selOrig, tv=True) try: pm.select(self.referenceXformNode, replace=True) pm.select(selPre, add=True) selForTransfer = pm.ls(selection=True) pm.transferAttributes(transferPositions=1, transferNormals=0, transferUVs=0, transferColors=0, sampleSpace=0, searchMethod=0) objsToAddToSelection = [] for o in selForTransfer: #s = str( type(o) ) #print "y" + s + "y" if str(type(o)) == "<class 'pymel.core.general.MeshVertex'>": n = o.name().split('.')[0] objsToAddToSelection.append(n) for obj in objsToAddToSelection: pm.select(obj, add=True) pm.delete(ch=True) ##was #pm.mel.eval( "DeleteHistory;" ) print(selForTransfer) pm.select(selOrig, replace=True) pm.hilite(hiliteOrig) except: pm.select(selOrig) pm.hilite(hiliteOrig) print( "Please ensure that you have a valid reference mesh selected, and that you have verticies or objects select to project." )
def createRivet(self): """ Create one rivet for each selected vertex """ selObjs = pm.ls(selection=True) if not selObjs: ## Nothing is selected, so print out warning and raise error print( self.emsgPleaseSelect ) return #raise Exception, self.emsgPleaseSelect self.originalSel = selObjs #### Store this step of of the selection in case we want it again later uvs = [] uvs.extend( pm.polyListComponentConversion( selObjs, tuv=True ) ) #### Change this to the full version #uvs.extend( [uv for uv in selObjs if '.uv' in uv] ) #### This is a very good list comprehension, perhaps expand it though ## the extend method of a list adds all items from another given list to the list uvsFromNurbs = [] for i in selObjs: if pm.objectType( i ) == 'nurbsSurface' : uvs.append( i ) ## select our new, smaller/filtered uvs pm.select( uvs ) uvs = pm.ls( flatten = True, selection = True ) ## The flatten command returns each component individually in the list, rather than using strings that specify ranges of selections. It takes more RAM but is often much more suitable to work with. ## Create a group so that we can organize the rivets - **** Note that this should be improved with the MmmmTools upcoming unique naming system if not pm.objExists('_follicle_grp'): #### This line and the next should eventually be improved to not use a hardcoded name group = pm.group( em = True, w=True, n='_follicle_grp' ) #### **** Totally recreate this line, use a variable name or at least a unique one else: group = pm.PyNode('_follicle_grp') rivets = [] pm.select( selObjs ) failCount = 0 ## Give an error msg if the user didn't use the script on a compatible selection if not uvs: failCount += 1 print( self.emsgPleaseSelect ) ## Everything is good, proceed to investigate and create rivets for uv in uvs: ## The commented out print line are simple useful for debugging print pm.objectType( uv ) objShapeName, index = tuple( uv.split( '.', 1 ) ) obj = pm.PyNode( objShapeName ) loc = pm.createNode( 'locator' ) tr = getT( loc ) #print( "Transform was: " + tr ) hair = pm.createNode( 'follicle', parent = tr ) pm.parent( tr, group ) #### This line sucks because it's using a f*****g stupid name again rivets.append( tr ) ## Poly mesh handler if pm.objectType( obj ) == 'mesh': obj.outMesh >> hair.inputMesh uvPos = pm.polyEditUV( uv, query=True ) ## Nurbs surface handler elif pm.objectType( obj ) == 'nurbsSurface': obj.local >> hair.inputSurface ## The index is a messy string, so we need to pull uv data out of it uvTuple = ( index.strip('.uv[]').split('][') ) ## We need to create the tuple as floats, because we got it as strings uvPos = ( float(uvTuple[0]), float(uvTuple[1]) ) #uvPos = ( uvTuple[0], uv[1] )#index.strip('.uv[]').split('][') ## Handle conditions where the uvs aren't normalized, this may not be required often maxU = float( obj.maxValueU.get() ) maxV = float( obj.maxValueV.get() ) uvPos = ( uvPos[0]/maxU, uvPos[1]/maxV ) ## Handle other cases, where this script can't do anything useful else: print( obj + ' with uv: ' + uv + \ ' was incompatible, it much be either polygons or Nurbs' ) failCount += 1 continue u, v = uvPos ## Make the hair follow the model, both by parenting, and by keeping its translate and rotate matched obj.worldMatrix >> hair.inputWorldMatrix hair.outTranslate >> tr.translate hair.outRotate >> tr.rotate ## Note: The hair has no outScale ## Set the u and v parameters of the hair so that it sticks to the correct place on the model hair.parameterU.set( u ) hair.parameterV.set( v ) ## Put the rivet into a group so we can select it afterwards self.lastRivetsCreated.append( loc ) ## Select all the new rivets we created pm.select( self.lastRivetsCreated, replace=True ) if failCount: print( str(failCount) + """ rivets failed to be created. Most likely because the selection was not correct. Try selecting vertices on a nurbs surface or a polygon mesh and running the script again. """) else: print( self.msgSucess ) return
def sd_weight_flat_surface(selection, obj_select=True, min_tolerance=0, max_tolerance=0): """ if obj_select = True, hard surfaces (perfectly flat) will automatically be found and corrected, but only if model properly finished. min_tolerance = the minimum angle that will be selected. max_tolerance = the maximum angle that will be selected. """ sd_test_type(selection, [pm.Transform, pm.MeshFace]) if obj_select: # convert selection to edges mm.eval('ConvertSelectionToEdges;') # constrain the selection to a specific angle pm.polySelectConstraint( mode=3, type=0x8000, angle=True, anglebound=(min_tolerance, max_tolerance) ) # save the selection oSel = pm.ls(sl=True, flatten=True) # turn off polySelectConstraint pm.polySelectConstraint(mode=0) # make sure its selected (just in case) pm.select(oSel) # convert to faces mm.eval('ConvertSelectionToFaces;') fSel = pm.ls(sl=True, flatten=True) # create a good ol' progress bar progWind = pm.window(title='progress') pm.columnLayout() progressControl = pm.progressBar(maxValue=len(fSel), width=300) pm.showWindow(progWind) # run through each object and get the face normal of each face # apply the face normal direction to the connected verts for face in fSel: pm.select(face) face_normal = face.getNormal(space='world') verts = pm.polyListComponentConversion( face, fromFace=True, toVertex=True ) pm.select(verts) pm.polyNormalPerVertex(normalXYZ=face_normal) ff = fSel.index(face) pm.progressBar(progressControl, edit=True, progress=ff) pm.deleteUI(progWind)