def __generateMesh( self, mesh, height, radius, sideLength, positions, iteration ): instanceGroup = pm.group( empty = True, name = "meshInstanceGroup" ) x = 0 y = positions[ 0 ].y z = 0 # vertex indices's # [ 0 ] is right # [ 1 ] is left # [ 2 ] is front # [ 3 ] is top backVtx = positions[ 1 ] # Top meshInstance1 = pm.PyNode( mesh[ 0 ] ) meshInstance1.setTranslation( [ x, y + height, z ] ) # Right meshInstance2 = pm.instance( mesh[ 0 ] ) meshInstance2[ 0 ].setTranslation( [ backVtx.x, y, -backVtx.z ] ) # Left meshInstance3 = pm.instance( mesh[ 0 ] ) meshInstance3[ 0 ].setTranslation( [ backVtx.x, y, backVtx.z ] ) # Front meshInstance4 = pm.instance( mesh[ 0 ] ) meshInstance4[ 0 ].setTranslation( [ radius, y, z ] ) pm.parent( [ meshInstance1, meshInstance2[ 0 ], meshInstance3[ 0 ], meshInstance4[ 0 ] ], instanceGroup, add = True ) return combineClean( instanceGroup, "Sierpinski_Iteration_%i" % iteration )
def __generateMesh( self, mesh, height, radius, iteration ): instanceGroup = pm.group( empty = True, name = "meshInstanceGroup" ) x = 0 y = 0 z = 0 # Top meshInstance1 = mesh meshInstance1[ 0 ].setTranslation( [ x, height, z ] ) # Right meshInstance2 = pm.instance( mesh[ 0 ] ) meshInstance2[ 0 ].setTranslation( [ radius, y, z ] ) # Back meshInstance3 = pm.instance( mesh[ 0 ] ) meshInstance3[ 0 ].setTranslation( [ x, y, -radius ] ) # Left meshInstance4 = pm.instance( mesh[ 0 ] ) meshInstance4[ 0 ].setTranslation( [ -radius, y, z ] ) # Front meshInstance5 = pm.instance( mesh[ 0 ] ) meshInstance5[ 0 ].setTranslation( [ x, y, radius ] ) # Bottom meshInstance6 = pm.instance( mesh[ 0 ] ) meshInstance6[ 0 ].setTranslation( [ x, -height, z ] ) pm.parent( meshInstance1[ 0 ], meshInstance2[ 0 ], meshInstance3[ 0 ], meshInstance4[ 0 ], meshInstance5[ 0 ], meshInstance6[ 0 ], instanceGroup, add = True ) return combineClean( instanceGroup, "Sierpinski_Iteration_%i" % iteration )
def locInst_locSel(self): ''' Function: Takes a locator and instances it's target (set as an extra attr) Then sets the location of the instance. If the instance already exists it uses that Returns: None ''' locs = pm.ls(sl=True) grp_name = "_".join(locs[0].getParent().split('_')[:-2])+"_INST_GRP" print grp_name print pm.objExists(grp_name) if pm.objExists(grp_name): pm.PyNode(grp_name) else: grp=pm.group(em=True, n=grp_name) for loc in locs: #if the target isn't an instance create it targetExists = pm.ls(loc.target.get().split('_')[:-1][0]!='GEO', r=True, type='transform')[0] instanceExists = pm.ls(loc.target.get().split('_')[:-1][0]!='INST', r=True, type='transform')[0] if not instanceExists and targetExists: matchObj = pm.ls(loc.target.get(), r=True, type='transform')[0] instance = pm.instance(matchObj, n=('_'.join(matchObj.split('_')[:-1])+'_INST'))[0] #set the target to the new instance since it was created loc.target.set(instance) elif pm.objExists(loc.target.get()) and pm.objExists('_'.join(target.split('_')[:-1])+'_INST'): pm.error('Neither a GEO nor an INST object exists with this name') #otherwise initialize the instance variable else: instance = pm.PyNode('_'.join(arg.split('_')[:-1])+'_INST') loc.t.connect( instance.t ) loc.r.connect( instance.r ) loc.s.connect( instance.s ) instance.setParent(grp)
def __generateMesh(self, mesh, positions, radius, iteration): instanceGroup = pm.group(empty=True, name="meshInstanceGroup") positionsLength = len(positions) instances = [None] * positionsLength for i in range(0, positionsLength): position = scaleVector(positions[i], radius) if i == 0: meshInstance = mesh meshInstance[0].setTranslation(position) else: meshInstance = pm.instance(mesh[0]) meshInstance[0].setTranslation(position) instances[i] = meshInstance[0] pm.parent(instances, instanceGroup, add=True) return combineClean(instanceGroup, "Sierpinski_Iteration_%i" % iteration)
def __generateMesh( self, mesh, positions, radius, iteration ): instanceGroup = pm.group( empty = True, name = "meshInstanceGroup" ) positionsLength = len( positions ) instances = [ None ] * positionsLength for i in range(0, positionsLength): position = scaleVector( positions[ i ], radius ) if i == 0: meshInstance = mesh meshInstance[ 0 ].setTranslation( position ) else: meshInstance = pm.instance( mesh[ 0 ] ) meshInstance[ 0 ].setTranslation(position) instances[ i ] = meshInstance[ 0 ] pm.parent( instances, instanceGroup, add = True ) return combineClean( instanceGroup, "Sierpinski_Iteration_%i" % iteration )
def meshGenerator(self, meshList): rangeNum = self.getTargetInstances() for num in range(rangeNum * rangeNum): objInst = pm.instance(random.choice(meshList))[0] objInst.setParent(self.locList[num]) pm.xform(objInst, translation=[0, 0, 0], rotation=[0, 0, 0])
def __generateMesh(self, mesh, height, radius, iteration): instanceGroup = pm.group(empty=True, name="meshInstanceGroup") x = 0 y = 0 z = 0 # Top meshInstance1 = mesh meshInstance1[0].setTranslation([x, height, z]) # Right meshInstance2 = pm.instance(mesh[0]) meshInstance2[0].setTranslation([radius, y, z]) # Back meshInstance3 = pm.instance(mesh[0]) meshInstance3[0].setTranslation([x, y, -radius]) # Left meshInstance4 = pm.instance(mesh[0]) meshInstance4[0].setTranslation([-radius, y, z]) # Front meshInstance5 = pm.instance(mesh[0]) meshInstance5[0].setTranslation([x, y, radius]) # Bottom meshInstance6 = pm.instance(mesh[0]) meshInstance6[0].setTranslation([x, -height, z]) pm.parent(meshInstance1[0], meshInstance2[0], meshInstance3[0], meshInstance4[0], meshInstance5[0], meshInstance6[0], instanceGroup, add=True) return combineClean(instanceGroup, "Sierpinski_Iteration_%i" % iteration)
def bake(self): self.updateDynState(3) self.instancer = pm.PyNode(self.instancer) if not pm.objExists(self.worldParentBake): self.worldParentBake = pm.group(n=self.worldParentBake, em=1, w=1) if pm.ls("FGpass_*"): pad = str( int(sorted(pm.ls("FGpass_*"), reverse=True)[0].split('_')[1]) + 1).zfill(4) else: pad = "1".zfill(4) prefix = "FGp_" + pad self.worldPassBake = pm.parent( pm.group(em=1, w=1, name="FGpass_" + pad), self.worldParentBake) arbo = {} for i, x in enumerate(self.instancer.allInstances()[1]): id = self.instancer.allInstances()[2][i] inst = self.instancer.allInstances()[0][ self.instancer.allInstances()[3][i]] instT = inst.listRelatives(p=1)[0] mesh = instT.getAttr("originalMesh") instParamater = self.getRowByName(mesh) typeInst = instParamater["type"].lower() if not typeInst in arbo: arbo[typeInst] = {} if not mesh.name() in arbo[typeInst]: arbo[typeInst][mesh.name()] = [] meshTmp = pm.instance(mesh, n=prefix + "_" + str(mesh) + "_" + str(id) + "_inst")[0] meshTmp.setTransformation(x) arbo[typeInst][mesh.name()].append(meshTmp) self.connectOriginaleMesh(mesh, meshTmp) #loc = pm.spaceLocator(n=str(mesh)+"_"+str(id)+"_loc") #arbo[typeInst][mesh.name()].append(loc) #loc.setTransformation(x) #self.connectOriginaleMesh(mesh, loc.listRelatives(s=1,c=1)[0]) for x in arbo: typeGrp = pm.group(n=prefix + "_" + x, em=1, w=1) typeGrp = pm.parent(typeGrp, self.worldPassBake) for y in arbo[x]: pm.select(cl=1) pm.select(arbo[x][y]) grptmp = pm.group(w=1, n=prefix + "_" + y + "_locGrp") pm.parent(grptmp, typeGrp)
def cbsStart(*args, **kwargs): base = kwargs.setdefault('base', pm.ls(sl=True)[0]) # (string) The base model for the character shape = kwargs.setdefault('shape') # (string) The shape node of the base model tweak = kwargs.setdefault('tweak') # (string) The tweak node of the base model that is being skinned skin = kwargs.setdefault('skin') # (string) The skinCluster node that is driving the base model #gather some info base, shape, tweak, skin = gatherInfo(base, shape, tweak, skin) verts = pm.polyEvaluate(base, v=True) #do a quick check to make sure this part hasn't been done before if base.hasAttr('baseTransform'): pm.error('You have already run the "Start" function on this model, so it is already ready to go.' + 'If corrections have already been made, click "Extract Shape to finish the process"') for i in pm.listHistory(base, lv=1): if i.type() == 'polySmoothFace': pm.error('The selected shape is connected to a smooth modifier. This hinders the ability to track edits. %s must be deleted.' % i) #turn off a couple things that might mess with things pm.symmetricModelling(e=True, symmetry= False) pm.softSelect(e=True, softSelectEnabled=False) for i in range(verts): x = pm.getAttr(('%s.vlist[0].vertex[%i].xVertex'%(tweak, i))) y = pm.getAttr(('%s.vlist[0].vertex[%i].yVertex'%(tweak, i))) z = pm.getAttr(('%s.vlist[0].vertex[%i].zVertex'%(tweak, i))) if not (x+y+z) == 0: pm.error('You have used the tweak node. No me gusta. If you really wanna clear it, run clearTweaks and try again. It will save what you have') #ok, let's get started, first instance the original mesh sculptTrans = pm.instance(base, n=('%s_corrective_sculpt'%base))[0] pm.reorderDeformers(skin, tweak, base) pm.setAttr('%s.v'%base, False) #Here, we'll make a duplicate of the base to look back on later if need be (for instance, using sculpt geometry tends to not register on tweak) baseRef = pm.duplicate(base, n='%s_editReference'%base)[0] pm.connectAttr(('%s.outMesh' %baseRef.getShapes()[1]), ('%s.inMesh' %baseRef.getShape())) #We'll also hook up the original so we can get it later pm.addAttr(sculptTrans, ln='baseTransform', at='message') pm.addAttr(sculptTrans, ln='baseReference', at='message') pm.connectAttr('%s.message'%base, '%s.baseTransform'%sculptTrans) pm.connectAttr('%s.message'%baseRef, '%s.baseReference'%sculptTrans) #now to keep things from changing between functions, we'll lock the three nodes involved in the #other script so our pesky little user won't delete or rename anything pm.lockNode(base, l=True) pm.lockNode(sculptTrans, l=True)
def faceLocators(): """ Iterates through faces on surface, attaches locators and objects """ aimLoc = pm.spaceLocator(n="aimLoc") # Selects all faces, puts average center coordinates in a list pm.select(nameOfSurface) fc = pm.polyEvaluate(face=True) faceLocCount = 0 for x in range(0, fc): numGen = r.random() bBox = pm.xform(nameOfSurface + '.f[' + str(x) + ']', ws=True, q=True, bb=True) transX = (bBox[0] + bBox[3]) / 2 transY = (bBox[1] + bBox[4]) / 2 transZ = (bBox[2] + bBox[5]) / 2 # Creates locators if (numGen <= num): faceLoc = pm.spaceLocator(n="faceLoc{0}".format(1), p=(transX, transY, transZ)) pm.xform(centerPivots=True) pm.delete( pm.aimConstraint(aimLoc, faceLoc, aimVector=[0, -1, 0], upVector=[0, 1, 0], worldUpVector=[0, 1, 0])) duplicatedObject = pm.instance(selectedObject, lf=True) rotVal = pm.getAttr(faceLoc + '.rotate') pm.setAttr(duplicatedObject[0] + '.translate', transX, transY, transZ) pm.setAttr(duplicatedObject[0] + '.rotate', rotVal[0], rotVal[1], rotVal[2]) if setToNormals is False: pm.setAttr(duplicatedObject[0] + '.rotate', 0, 0, 0) pm.setAttr(faceLoc + '.rotate', 0, 0, 0) pm.parent(faceLoc, duplicatedObject[0], duplicateGroup) faceLocCount += 1 pm.delete(aimLoc) totalFace = round(float(faceLocCount) / fc * 100.0, 2) _logger.debug("Generated " + str(faceLocCount) + " locators at faces for " + str(fc) + " possible surfaces.(" + str(totalFace) + "%) ")
def instanceObjectsGroup(self, *args): list = pm.ls(sl=True, tr=True) input_numberOfInstances = pm.intField( self.widgets['numberOfInstances'], q=True, v=True) groupName = '' instanceList = [] for i in range(input_numberOfInstances): instanceList = [] for object in list: objectName = object searchName = objectName.rpartition('GEO')[2] searchName = searchName.rpartition('_0')[0] groupSearchName = 'GRP' + searchName + '*' pm.select('*' + searchName + '*', r=True) if pm.objExists('GRP' + searchName + '*'): pm.select('*' + 'GRP_' + '*', d=True) ListExsistingDuplicates = pm.ls(sl=True, tr=True) numberExsistingDuplicates = len(ListExsistingDuplicates) instanceName = 'INST' + objectName.rpartition('GEO')[2] instanceName = instanceName.rpartition('_0')[0] + '_' + str( numberExsistingDuplicates) groupName = 'GRP' + instanceName.rpartition('INST')[2] pm.select(object, r=True) pm.instance(n=instanceName) name = pm.ls(sl=True) # add identifier pm.addAttr(name[0], ln="Instance", dt="string", h=True) instanceList.append(name[0]) pm.group(instanceList, n=groupName) pm.parent(groupName, self.rootObject) self.objectList.append(groupName) pm.select(list, r=True) return self.objectList
def bake(self): self.updateDynState(3) self.instancer = pm.PyNode(self.instancer) if not pm.objExists(self.worldParentBake): self.worldParentBake = pm.group(n=self.worldParentBake, em=1, w=1) if pm.ls("FGpass_*"): pad = str(int(sorted(pm.ls("FGpass_*"), reverse=True)[0].split("_")[1]) + 1).zfill(4) else: pad = "1".zfill(4) prefix = "FGp_" + pad self.worldPassBake = pm.parent(pm.group(em=1, w=1, name="FGpass_" + pad), self.worldParentBake) arbo = {} for i, x in enumerate(self.instancer.allInstances()[1]): id = self.instancer.allInstances()[2][i] inst = self.instancer.allInstances()[0][self.instancer.allInstances()[3][i]] instT = inst.listRelatives(p=1)[0] mesh = instT.getAttr("originalMesh") instParamater = self.getRowByName(mesh) typeInst = instParamater["type"].lower() if not typeInst in arbo: arbo[typeInst] = {} if not mesh.name() in arbo[typeInst]: arbo[typeInst][mesh.name()] = [] meshTmp = pm.instance(mesh, n=prefix + "_" + str(mesh) + "_" + str(id) + "_inst")[0] meshTmp.setTransformation(x) arbo[typeInst][mesh.name()].append(meshTmp) self.connectOriginaleMesh(mesh, meshTmp) # loc = pm.spaceLocator(n=str(mesh)+"_"+str(id)+"_loc") # arbo[typeInst][mesh.name()].append(loc) # loc.setTransformation(x) # self.connectOriginaleMesh(mesh, loc.listRelatives(s=1,c=1)[0]) for x in arbo: typeGrp = pm.group(n=prefix + "_" + x, em=1, w=1) typeGrp = pm.parent(typeGrp, self.worldPassBake) for y in arbo[x]: pm.select(cl=1) pm.select(arbo[x][y]) grptmp = pm.group(w=1, n=prefix + "_" + y + "_locGrp") pm.parent(grptmp, typeGrp)
def makeInstance( levels, rows, columns, index ): x = ( size * 1 ) - ( rows * size ) y = ( size * 1 ) - ( levels * size ) z = ( size * 1 ) - ( columns * size ) if index == 0: meshInstance = mesh else: meshInstance = pm.instance( mesh[ 0 ] ) meshInstance[ 0 ].setTranslation( [ x, y, z ] ) instances.append( meshInstance[ 0 ] )
def attach(source, target, p): """Instances source, and attaches it to mesh target as close as it can on the surface to point p. """ n = _getMeshNode(target) inst = pm.instance(source) constraint = pm.pointOnPolyConstraint(target, inst) uvs = n.getUVAtPoint(p, space="world") transform = n.firstParent() constraint.attr("%sU0" % transform.nodeName()).set(uvs[0]) constraint.attr("%sV0" % transform.nodeName()).set(uvs[1])
def vertLocators(): """ Iterates through vertices on surface, attaches locators and objects """ aimLoc = pm.spaceLocator(n="aimLoc") # Selects all vertices, puts all vertice coordinates in a list pm.select(nameOfSurface) vs = pm.polyEvaluate(v=True) verts = [] vertLocCount = 0 for i in range(0, vs): verts += (pm.pointPosition(nameOfSurface + '.vtx[' + str(i) + ']'), ) # Creates locators for v in verts: numGen = r.random() if (numGen <= num): vertLoc = pm.spaceLocator(n="vertexLoc{0}".format(1), p=(v[0], v[1], v[2])) pm.xform(centerPivots=True) pm.delete( pm.aimConstraint(aimLoc, vertLoc, aimVector=[0, -1, 0], upVector=[0, 1, 0], worldUpVector=[0, 1, 0])) duplicatedObject = pm.instance(selectedObject, lf=True) rotVal = pm.getAttr(vertLoc + '.rotate') pm.setAttr(duplicatedObject[0] + '.translate', v[0], v[1], v[2]) pm.setAttr(duplicatedObject[0] + '.rotate', rotVal[0], rotVal[1], rotVal[2]) if setToNormals is False: pm.setAttr(duplicatedObject[0] + '.rotate', 0, 0, 0) pm.setAttr(vertLoc + '.rotate', 0, 0, 0) pm.parent(vertLoc, duplicatedObject[0], duplicateGroup) vertLocCount += 1 pm.delete(aimLoc) totalVerts = round(float(vertLocCount) / vs * 100.0, 2) _logger.debug("Generated " + str(vertLocCount) + " locators at vertices for " + str(vs) + " possible vertices. (" + str(totalVerts) + "%) ")
def ExchangeProxy(self, prx_type, trg_type, ifAll=None):#执行替换 sel_prxs_dict = self.list_prxys_dict(self.get_prxs(prx_type, ifAll)) need_prxs_date = self.nessesary_prxDcit(sel_prxs_dict) # src_type = 'AR' # trg_type = 'VR' im_objs = self.imp_all_prxs(need_prxs_date, trg_type) #print im_objs rpl_cnt = 0 for ea_prx_type in sel_prxs_dict: # pass for eaPrxShp in sel_prxs_dict[ea_prx_type]: # pass if prx_type == 'VRayMesh': eaPrxShp = eaPrxShp.attr('output').listConnections(sh=True,type='mesh')[0] trns_nd = eaPrxShp.getParent() grp_nd = trns_nd.getParent() insToggle = False cp_prx_trn = "" if eaPrxShp.isInstanced(): cp_prx = pm.instance(im_objs[ea_prx_type]['needRep'],st=True) cp_prx_trn = cp_prx[0] print ('instance object {}'.format(cp_prx)) if grp_nd:# instance 的物体有时候在场景中不能被P到其他节点下,没有报错,就是P不进去,所以加了个判断,如果P不进去,就改成普通的duplicate try: cp_prx_trn.setParent(grp_nd) insToggle = True except: pm.delete(cp_prx_trn) insToggle = False if not insToggle: cp_prx = pm.duplicate(im_objs[ea_prx_type]['needRep'], rr=True) cp_prx_trn = cp_prx[0] if trg_type == 'VR': get_vrmsh = im_objs[ea_prx_type]['needRep'].attr('inMesh').listConnections(type='VRayMesh',p=True)[0] get_vrmsh >> cp_prx_trn.getShape().attr('inMesh') if grp_nd: try: cp_prx_trn.setParent(grp_nd) except: raise Exception("TD Check") print ("rename =========ok") trns_nd.translate >> cp_prx_trn.translate trns_nd.rotate >> cp_prx_trn.rotate trns_nd.scale >> cp_prx_trn.scale pm.delete(trns_nd) rpl_cnt += 1 for ea_v in im_objs.values(): pm.delete(ea_v['trans']) return rpl_cnt
def createMirror(selectObj, prevObj, sBbox, sBboxP, pivot, mirrorInfo): # 選択オブジェクトのフリーズ処理 フリーズしたほうが良いのか悪いのか判断難しい。しない方がいい場合もありそう。 pm.makeIdentity(selectObj, apply=True, t=1, r=1, s=1, n=0, pn=1) # 選択オブジェクトのグループ化 grpObj = pm.group(selectObj, n=selectObj + mirrorInfo['sNameTail']) # 選択オブジェクトグループのインスタンスの作成 instanceGrpObj = pm.instance(grpObj, n=selectObj + mirrorInfo['nNameTail']) # 反転(ミラー)処理xormのwsだとオブジェクトのローカル軸基準で変換してるっぽい?何故かわからない。 pm.select(instanceGrpObj) pm.xform(scale=mirrorInfo['mirrorScale'], scalePivot=pivot, ws=True) pm.xform(cp=True) #親グループの作成 あり、なしで選択できるようにした方がいいかも。 pm.group(grpObj, instanceGrpObj, n=prevObj + '_Mirror')
def instanceObjects(self, *args): input_numberOfInstances = pm.intField(self.widgets[''], q=True, v=True) list = pm.ls(sl=True, tr=True) for object in list: objectName = object instanceName = 'INST' + objectName.rpartition('GEO')[2] for i in range(input_numberOfInstances): pm.select(object, r=True) name = pm.instance(n=instanceName) self.objectList.append(name[0]) return self.objectList
def faceLocators(): """ Iterates through faces on surface, attaches Locators """ # Selects all faces, puts average center coordinates in a list pm.select(nameOfSurface) fc = pm.polyEvaluate(face=True) faces = [] faceLocCount = 0 for x in range(0, fc): numGen = r.random() * 10.0 bBox = pm.xform(nameOfSurface + '.f[' + str(x) + ']', ws=True, q=True, bb=True) transX = (bBox[0] + bBox[3]) / 2 transY = (bBox[1] + bBox[4]) / 2 transZ = (bBox[2] + bBox[5]) / 2 # Creates locators if (numGen <= num): faceLocsNames = pm.spaceLocator(n="faceLoc{0}".format(1), p=(transX, transY, transZ)) duplicatedObject = pm.instance(selectedObject, leaf=True) pm.setAttr(duplicatedObject[0] + '.translate', transX, transY + scaleOfItems, transZ) if (randomScale is True): pm.setAttr(duplicatedObject[0] + '.scale', (scaleOfItems * numGen), (scaleOfItems * numGen), (scaleOfItems * numGen)) else: pm.setAttr(duplicatedObject[0] + '.scale', scaleOfItems, scaleOfItems, scaleOfItems) faceLocCount += 1 totalFace = round(float(faceLocCount) / fc * 100.0, 2) print("Generated " + str(faceLocCount) + " locators at faces for " + str(fc) + " possible surfaces.(" + str(totalFace) + "%)")
def vertLocators(): """ Iterates through vertices on surface, attaches Locators """ # Selects all vertices, puts all vertice coordinates in a list pm.select(nameOfSurface) vs = pm.polyEvaluate(v=True) verts = [] vertLocCount = 0 for i in range(0, vs): verts += (pm.pointPosition(nameOfSurface + '.vtx[' + str(i) + ']', world=True), ) # Creates locators for v in verts: numGen = r.random() * 10.0 if (numGen <= num): pm.spaceLocator(n="vertexLoc{0}".format(1), p=(v[0], v[1], v[2])) duplicatedObject = pm.instance(selectedObject, leaf=True) pm.setAttr(duplicatedObject[0] + '.translate', v[0], v[1] + scaleOfItems, v[2]) vertRotations = calculateRotations(node=nameOfSurface, vertPositions=v) if (randomScale is True): pm.setAttr(duplicatedObject[0] + '.scale', (scaleOfItems * numGen), (scaleOfItems * numGen), (scaleOfItems * numGen)) else: pm.setAttr(duplicatedObject[0] + '.scale', scaleOfItems, scaleOfItems, scaleOfItems) vertLocCount += 1 totalVerts = round(float(vertLocCount) / vs * 100.0, 2) print("Generated " + str(vertLocCount) + " locators at vertices for " + str(vs) + " possible vertices. (" + str(totalVerts) + "%)")
def mirrorInstanceTree( tree, root ) : for r in tree.keys() : if tree[r] != None : """ if not isIdentity( r ) : cmds.makeIdentity( r, apply=True, t=True, r=True, s=True, n=False ) cmds.xform( piv=(0,0,0), ws=True ) """ if isDirectParent( r ) : #print( r.split('|')[-1].replace('_L', '_R') ) #new = cmds.instance( r, n=r.split('|')[-1].replace('_L', '_R') )[0] #new = cmds.instance( r, n=r.split('|')[-1].replace('L', 'R') )[0] #new = cmds.instance( r, n=r.split('|')[-1] )[0] #cmds.parent( new, root ) new = pc.instance(r,n=r.split('|')[-1]) pc.parent( new, pc.ls(root)[0] ) else : #subroot = cmds.group(em=True,n=r.split('|')[-1].replace('L','R')) #subroot = cmds.ls(sl=True,long=True)[0] #cmds.parent( subroot, root ) subroot = pc.group(em=True,n=r.split('|')[-1]) pc.parent(subroot,pc.ls(root)[0]) mirrorInstanceTree( tree[r], subroot )
def matchTransform(instance=False): nodes = pm.selected() orig = nodes[-1] targets = nodes[:-1] oobj = MatchObj(orig.name()) for t in targets: ocp = None if instance: ocp = pm.instance(orig)[0] else: ocp = pm.duplicate(orig)[0] if ocp != None: ttemp = pm.duplicate(t)[0] tobj = MatchObj(ttemp.name()) ocp.rename(t.name() + '_matchcopy') m = tobj.getMatrixByBasis() #ocp.setMatrix(m) ocp.setMatrix(m * tobj.matrix) pm.delete(ttemp) if t.getParent(): print(ocp.name()) #pm.parent(ocp, t.getParent(), a=True) pass pass
def faceLocators(): """ Iterates through faces on surface, attaches locators and objects """ # Selects all faces, puts average center coordinates in a list pm.select(nameOfSurface) fc = pm.polyEvaluate(face=True) faceLocCount = 0 for x in range(0, fc): numGen = r.random() bBox = pm.xform(nameOfSurface + '.f[' + str(x) + ']', ws=True, q=True, bb=True) transX = (bBox[0] + bBox[3]) / 2 transY = (bBox[1] + bBox[4]) / 2 transZ = (bBox[2] + bBox[5]) / 2 # Creates locators if (numGen <= num): pm.spaceLocator(n="faceLoc{0}".format(1), p=(transX, transY, transZ)) duplicatedObject = pm.instance(selectedObject, leaf=True) pm.setAttr(duplicatedObject[0] + '.translate', transX, transY, transZ) randomScaleNumber = r.randrange(minRandomScale, maxRandomScale) randomRotationNumber = r.randrange(minRandomRotation, maxRandomRotation) if randomScale is True: pm.setAttr(duplicatedObject[0] + '.scale', randomScaleNumber, randomScaleNumber, randomScaleNumber) if setToNormals is True: poly = PyNode(nameOfSurface + '.f[' + str(x) + ']') normalVector = poly.getNormal() if randomRotation is True: pm.setAttr(duplicatedObject[0] + '.rotate', randomRotationNumber, randomRotationNumber, randomRotationNumber) if randomX is True: pm.setAttr(duplicatedObject[0] + '.rotateX', randomRotationNumber) if randomY is True: pm.setAttr(duplicatedObject[0] + '.rotateY', randomRotationNumber) if randomZ is True: pm.setAttr(duplicatedObject[0] + '.rotateZ', randomRotationNumber) faceLocCount += 1 totalFace = round(float(faceLocCount) / fc * 100.0, 2) _logger.debug("Generated " + str(faceLocCount) + " locators at faces for " + str(fc) + " possible surfaces.(" + str(totalFace) + "%) ")
def locInst_locSel(all): ''' Function: Takes a locator and instances it's target (set as an extra attr) Then sets the location of the instance. If the instance already exists it uses that Returns: None ''' state=pm.promptDialog(t='Prefix', m='Please enter a prefix for your rock group\notherwise default.') if state=='Confirm': prefix=pm.promptDialog(q=True,text=True) locs = pm.ls(sl=True) if len(locs)>0: prefixed=0 if (prefix==''): prefix = locs[0].split('_')[0]+'_' grp_name = "_".join(locs[0].getParent().split('_')[:-2])+"_INST_GRP" else: prefixed=1 prefix+='_' grp_name = prefix+"INST_GRP" if pm.objExists(grp_name): pm.PyNode(grp_name) else: grp=pm.group(em=True, n=grp_name) for loc in locs: targets,targets_toCreate=[],[] original = pm.ls(loc.target.get(), r=True, type='transform')[0] #if the target doesn't exist...then this is f****d so stop the script if pm.ls(loc.target.get(), r=True)==[]: pm.error('Target object doesn\'t exist in scene, please add it') #if the locator doesn't have targets_inst add them + add to an attr + store local as targets if not pm.objExists(loc+'.targets_inst'): print 'adding .targets_inst to %s' % loc loc.addAttr('targets_inst', dt='string') loc.targets_inst.set( prefix+replaceSuffix(loc.target.get(),'INST') ) #compare the list of loc.targets_inst to the ones with the new prefix to see if they should be added to the list if prefixed: target_tmp_create,target_tmp_exist=[],[] target_tmp_create = set(pymelList(0, loc.targets_inst.get())[1]) target_tmp_exist = set(pymelList(0, loc.targets_inst.get())[0]) target_tmp = target_tmp_create.union(target_tmp_exist) target_tmp = list(target_tmp.union(set([prefix+replaceSuffix(loc.target.get(),'INST')]))) loc.targets_inst.set( pymelList(1, target_tmp)) #if it DOES have targets, make sure to update the list of possible targets with all other objects in the scene that match readTargets = pymelList(0, loc.targets_inst.get()) #targets that need updating if readTargets[0]!=[]: targets = list( set(readTargets[0]).union(set(pm.ls(prefix+replaceSuffix(loc.target.get(), 'INST*'), r=True, type='transform'))) ) #targets that need to be instanced/created targets_toCreate = readTargets[1] #if we only want the current one just do that #TODO add a section for modifying existing piles if not all: targets_toCreate=[] targets=[] loc_inst = prefix+replaceSuffix(loc.name(),'INST') if not pm.objExists(loc_inst): targets_toCreate.append(loc_inst) else: targets.append(pm.PyNode(loc_inst)) #create the targets that don't exist now and the append them to the targets list for target_create in targets_toCreate: if target_create != '': if pm.objExists(original): print 'creating missing instance: %s from object: %s' % (target_create, original) instance = pm.instance(original, n=target_create)[0] instance_grp = instance.split('_')[0] + '_INST_GRP' if not pm.objExists(instance_grp): pm.group(em=True, n=instance_grp) instance.setParent(instance_grp) targets.append(pm.PyNode(instance)) else: pm.error('Original object: %s not found...skipping.' % original) for instance in targets: instance.t.set( loc.t.get() ) instance.r.set( loc.r.get() ) instance.s.set( loc.s.get() )
def scatter(self): all_vertexes = [] self.scatter_instances.append([]) for target in self.scatter_targets: if type(target) == pmc.general.MeshVertex: all_vertexes.append(target) else: all_vertexes.extend(target.vtx) vertexes = range(len(all_vertexes)) random.shuffle(vertexes) vertexes = vertexes[:int(self.scatter_density * len(vertexes))] for i in vertexes: vertex = all_vertexes[i] # Get the average normal of the vertex # pmc.select(vertex, r=True) # a = pmc.polyNormalPerVertex(q=True, xyz=True) # num_normals = len(a) / 3 # average_normal = [0, 0, 0] # i = 0 # while i < len(a): # average_normal[i % 3] += a[i] / num_normals # i += 1 # # print(average_normal) new_instance = pmc.instance(random.choice(self.scatter_sources)) self.scatter_instances[-1].append(new_instance) position = pmc.pointPosition(vertex, w=True) pmc.move(position[0], position[1], position[2], new_instance, a=True, ws=True) if self.alignment: pmc.normalConstraint(vertex, new_instance) pmc.normalConstraint(vertex, new_instance, rm=True) scale = random_between_two_vectors( self.attribute_array[0], self.attribute_array[1]) rotation = random_between_two_vectors( self.attribute_array[2], self.attribute_array[3]) position = random_between_two_vectors( self.attribute_array[4], self.attribute_array[5]) pmc.scale(new_instance, scale[0], scale[1], scale[2], r=True) pmc.rotate(new_instance, rotation[0], rotation[1], rotation[2], r=True) pmc.move(position[0], position[1], position[2], new_instance, r=True, os=True, wd=True) # hello = cmds.polyListComponentConversion(tv=True) # print(hello[0]) # vertices = cmds.polyEvaluate(scatter_target, v=True) # i = 0 # while i < vertices: # print(scatter_target.vtx) # i += 1 #print(cmds.filterExpand(selectionMask=31)) #self.scatterTargetsVertices.append(vertices) return
def instanceHair(): sel = pm.selected() for hair in sel: instanceHair = pm.instance(hair) mirrorTransform(instanceHair)
def ph_mainCode(extraHeight, particleRate, getInitialInfo, minSlope, minSlopeVariance, setBoundingBox, maxTilt, objectScale, objectScaleVariance, objectHeightVariance): displayWindow = True windowError = py.window(title="Notice", mxb=False, s=False) errorLayout = py.rowColumnLayout(numberOfColumns=3, parent=windowError) #initialise varibables originalTime = py.currentTime(query=True) deleteCount = 0 decimalPoints = 2 #file validation storeSelection = py.ls(selection=True) try: validFile = True myfile = open('storedobjects.txt') objectList = myfile.readlines() myfile.close() py.select(clear=True) for i in range(len(objectList)): py.select(objectList[i], add=True) 1 / len(objectList) except: validFile = False #get original selection py.select(clear=True) for i in range(len(storeSelection)): py.select(storeSelection[i], add=True) #deselect non polygons if type(storeSelection[i]) != py.nodetypes.Transform: py.select(storeSelection[i], deselect=True) #deselect objects in the text file if getInitialInfo == False: for j in range(len(objectList)): selectionEdit = storeSelection[i] + objectList[j][ -2] + objectList[j][-1] if objectList[j] == selectionEdit: py.select(storeSelection[i], deselect=True) storeSelection = py.ls(selection=True) startTime = time() listOfPoints = [] totalNum = 0 if len(storeSelection) == 0: displayMessage = "Nothing is selected. Please select an object and try again." ph_displayWindow(displayWindow, displayMessage) elif getInitialInfo == True: #write to file selection = py.ls(selection=True) myfile = open('storedobjects.txt', 'w') for i in range(len(selection)): myfile.write("" + selection[i] + "\r\n") myfile.close() if len(selection) > 0: print str(len(selection)) + " object(s) successfully stored." if displayWindow == True: py.text(label=" ") py.text(label=" ") py.text(label=" ") py.text(label=" ") py.text(label=str(len(selection)) + " object(s) successfully stored.", align="center") py.text(label=" ") py.text(label=" ") py.text(label=" ") py.text(label=" ") py.showWindow() else: displayMessage = "Please select the objects you wish to store." ph_displayWindow(displayWindow, displayMessage) for i in range(len(storeSelection)): py.select(storeSelection[i], add=True) elif validFile == False: displayMessage = "Error with stored list. Please choose new object(s) to duplicate." ph_displayWindow(displayWindow, displayMessage) elif len(objectList) == 0: displayMessage = "No objects stored. Please choose new object(s) to duplicate." ph_displayWindow(displayWindow, displayMessage) else: for loops in range(len(storeSelection)): particleID = [] particleLoc = [] particleVelocity = [] #get information about selected object py.select(storeSelection[loops], r=True) originalObj = py.ls(selection=True) originalObjLoc = originalObj[0].getTranslation() originalObjX = originalObjLoc.x originalObjY = originalObjLoc.y originalObjZ = originalObjLoc.z #duplicate object to work on tempObj = py.instance(originalObj) #make emitter particleEmitter = py.emitter(n='tempEmitter', type='surface', r=particleRate * 24, sro=0, speed=0.0001) particles = py.particle(n='emittedParticles') py.connectDynamic('emittedParticles', em='tempEmitter') py.setAttr(particles[1] + '.seed[0]', rd.randint(0, sys.maxint)) #get list from file myfile = open('storedobjects.txt') objectList = myfile.readlines() objectListCopy = [] myfile.close() for i in range(len(objectList)): copyObj = py.duplicate(objectList[i]) objectListCopy.append(copyObj) #fixes the seed always being 0 py.currentTime(originalTime + 1, edit=True, update=True) py.currentTime(originalTime, edit=True, update=True) py.currentTime(originalTime + 1, edit=True, update=True) numOfParticles = particles[1].num() for i in range(numOfParticles): #get particle info particleInfo = particles[1].Point('emittedParticles', i) particleID.append(particleInfo) particleLoc.append(particleInfo.position) particleVelocity.append(particleInfo.velocity) for i in range(len(particleID)): #place objects randomNum = rd.randint(0, len(objectListCopy) - 1) instanceObj = objectListCopy[randomNum] dupObj = py.instance(instanceObj) yDir = particleVelocity[i][1] * 10000 #get height of object py.select(instanceObj, r=True) py.scale(1, 1, 1) height = py.ls(selection=True)[0].getBoundingBox().height() #reselect instance py.select(dupObj[0], r=True) py.move(dupObj[0], particleLoc[i][0], particleLoc[i][1] + extraHeight, particleLoc[i][2]) py.rotate(dupObj[0], rd.uniform(-maxTilt, maxTilt), rd.randint(0, 360), rd.uniform(-maxTilt, maxTilt), os=True) scaleX = rd.uniform(objectScale - objectScaleVariance, objectScale + objectScaleVariance) scaleY = rd.uniform(objectScale - (objectHeightVariance / 2), objectScale + objectHeightVariance) scaleZ = rd.uniform(objectScale - objectScaleVariance, objectScale + objectScaleVariance) py.scale(dupObj[0], scaleX, scaleY, scaleZ) if yDir <= rd.uniform(minSlope - minSlopeVariance, minSlope + minSlopeVariance): py.delete(dupObj) deleteCount = deleteCount + 1 else: listOfPoints.append(dupObj) #display percent completed maxValue = int(pow(len(particleID), 0.5)) if float(i / maxValue) == float(i) / maxValue: print str( int((float(i) * 100 / len(particleID)) * 100.0) / 100.0) + "% completed" totalNum = totalNum + numOfParticles #delete temp objects py.select(tempObj, 'tempEmitter', 'emittedParticles') py.delete() py.currentTime(originalTime, edit=True, update=True) for i in range(len(objectListCopy)): py.delete(objectListCopy[i][0]) #place objects in display layer py.select(clear=True) if len(listOfPoints) > 0: if setBoundingBox == True: displayLayerName = 'duplicatedObjectsBB' else: displayLayerName = 'duplicatedObjectsMesh' #add to display layer try: for i in range(len(listOfPoints)): py.editDisplayLayerMembers(displayLayerName, listOfPoints[i]) #create display layer first except: py.createDisplayLayer(noRecurse=True, name=displayLayerName) for i in range(len(listOfPoints)): py.editDisplayLayerMembers(displayLayerName, listOfPoints[i]) #display objects as bounding box if setBoundingBox == True: py.setAttr(displayLayerName + '.levelOfDetail', 1) py.setAttr(displayLayerName + '.color', 17) #add to group for i in range(len(listOfPoints)): py.select(listOfPoints[i][0], add=True) py.group(n='duplicatedObjectsGroup') #output time taken endTime = time() ph_timeOutput(startTime, endTime, decimalPoints) secondsDecimal, sec = ph_timeOutput(startTime, endTime, decimalPoints) displayMessage = str(totalNum - deleteCount) + " objects created in " + str( secondsDecimal) + str(sec) ph_displayWindow(displayWindow, displayMessage) #select original selection py.select(clear=True) for i in range(len(storeSelection)): py.select(storeSelection[i], add=True)
def createTargetIcons(self): self.deleteTargetIcons() panel = getCurrentPannel() isolateState = pymel.isolateSelect(panel, query=True, state=True) radius = 1 if not self.targetIconsShaderA: # make lambert for A spheres lambertA = pymel.shadingNode('lambert', asShader=True, name='DELETE_ME__TEMP_rightLambert') lambertA.addAttr('createColoredVertexSpheres_tempType', dt='string') lambertA.color.set( [0,0,0] ) lambertA.transparency.set( [0.5,0.5,0.5] ) shadingEngineA = pymel.sets(renderable=True, noSurfaceShader=True, empty=True, name='DELETE_ME__TEMP_rightshadingEngine') shadingEngineA.addAttr('createColoredVertexSpheres_tempType', dt='string') pymel.connectAttr(lambertA+".outColor", shadingEngineA+".surfaceShader", force=True) self.targetIconsShaderA = (lambertA, shadingEngineA) if not self.targetIconsShaderB: # make lambert for B spheres lambertB = pymel.shadingNode('lambert', asShader=True, name='DELETE_ME__TEMP_rightLambert') lambertB.addAttr('createColoredVertexSpheres_tempType', dt='string') lambertB.color.set( [0,0,0] ) lambertB.transparency.set( [0.5,0.5,0.5] ) shadingEngineB = pymel.sets(renderable=True, noSurfaceShader=True, empty=True, name='DELETE_ME__TEMP_rightshadingEngine') shadingEngineB.addAttr('createColoredVertexSpheres_tempType', dt='string') pymel.connectAttr(lambertB+".outColor", shadingEngineB+".surfaceShader", force=True) self.targetIconsShaderB = (lambertB, shadingEngineB) # create Icon A targetIconAOrig = pymel.sphere(name='DELETE_ME__targetASpheres', radius=radius, sections=1, startSweep=180, spans=2)[0] #targetIconAOrig = pymel.torus(axis=(0,0,-1), radius=radius*.666, heightRatio=0.33, sections=1, startSweep=20, endSweep=160, spans=4)[0] targetIconAOrig.rename('DELETE_ME__targetASpheres') targetIconAOrig.overrideEnabled.set(1) targetIconAOrig.drawOverride.overrideColor.set(2) targetIconAOrig.addAttr('createColoredVertexSpheres_tempType', dt='string') pymel.sets( shadingEngineA, forceElement=targetIconAOrig, ) # create Icon B targetIconBOrig = pymel.sphere(name='DELETE_ME__targetBSpheres', radius=radius, sections=1, startSweep=180, spans=2)[0] #targetIconBOrig = pymel.torus(axis=(0,0,-1), radius=radius*.666, heightRatio=0.33, sections=1, startSweep=20, endSweep=160, spans=4)[0] targetIconBOrig.rename('DELETE_ME__targetBSpheres') targetIconBOrig.overrideEnabled.set(1) targetIconBOrig.drawOverride.overrideColor.set(2) targetIconBOrig.addAttr('createColoredVertexSpheres_tempType', dt='string') pymel.sets( shadingEngineB, forceElement=targetIconBOrig, ) for shapeID in self.strandSequenceDict: for strandID in self.strandSequenceDict[shapeID]: for point in self.strandSequenceDict[shapeID][strandID]['targetSequences']: targetPointSets = self.strandSequenceDict[shapeID][strandID]['currentTargetSequence'][point] targetPointSetsA = targetPointSets[0] targetPointSetsB = targetPointSets[1] # Instance Sphere A targetIcons = [] for targetA in targetPointSetsA: if targetA is not None: targetIconA = pymel.instance(targetIconAOrig,)[0] targetIconA.rename('DELETE_ME__targetASpheres') targetIcons.append(targetIconA) if isolateState: pymel.isolateSelect(panel, addDagObject=targetIconA) else: targetIcons.append(None) self.strandSequenceDict[shapeID][strandID]['iconsA'][point] = tuple(targetIcons) # Instance Sphere B targetIcons = [] for targetB in targetPointSetsB: if targetB is not None: targetIconB = pymel.instance(targetIconBOrig,)[0] targetIconB.rename('DELETE_ME__targetBSpheres') targetIcons.append(targetIconB) if isolateState: pymel.isolateSelect(panel, addDagObject=targetIconB) else: targetIcons.append(None) self.strandSequenceDict[shapeID][strandID]['iconsB'][point] = tuple(targetIcons) targetIconAOrig.v.set(0) targetIconBOrig.v.set(0) self.setTargetIconPositions() #pymel.select(self.pointsInNodesDict.keys()) #pymel.select(clear=True) pymel.select(self.selection) for shapeID in self.strandInfoDict: shapeNode = self.strandInfoDict[shapeID]['componentInfoDict']['pyShape'] mel.eval( 'hilite %s' % str(shapeNode))
if src != None: pm.error('Select only one source object') src = element elif isinstance(element, (pm.MeshFace, pm.MeshVertex, pm.MeshEdge)): dst.append(element) else: pm.error('ERROR') print('src', src) print('dst', dst) # Make instances. group = [] for target in dst: # group.append(pm.instance(src)) clone = pm.instance(src) # getPosition works only with vertices if isinstance(target, pm.MeshVertex): move_to = target.getPosition(space='world') if isinstance(target, (pm.MeshFace, pm.MeshEdge)): pm.select(target, replace=True) faceBox = pm.polyEvaluate(boundingBoxComponent=True) centerX = 0.5 * (faceBox[0][0] + faceBox[0][1]) centerY = 0.5 * (faceBox[1][0] + faceBox[1][1]) centerZ = 0.5 * (faceBox[2][0] + faceBox[2][1]) move_to = pm.datatypes.Point(centerX, centerY, centerZ) print(repr(move_to)) pm.move(move_to.x, move_to.y, move_to.z, clone, absolute=True)
def cbsStart(*args, **kwargs): base = kwargs.setdefault( 'base', pm.ls(sl=True)[0]) # (string) The base model for the character shape = kwargs.setdefault( 'shape') # (string) The shape node of the base model tweak = kwargs.setdefault( 'tweak' ) # (string) The tweak node of the base model that is being skinned skin = kwargs.setdefault( 'skin') # (string) The skinCluster node that is driving the base model #gather some info base, shape, tweak, skin = gatherInfo(base, shape, tweak, skin) verts = pm.polyEvaluate(base, v=True) #do a quick check to make sure this part hasn't been done before if base.hasAttr('baseTransform'): pm.error( 'You have already run the "Start" function on this model, so it is already ready to go.' + 'If corrections have already been made, click "Extract Shape to finish the process"' ) for i in pm.listHistory(base, lv=1): if i.type() == 'polySmoothFace': pm.error( 'The selected shape is connected to a smooth modifier. This hinders the ability to track edits. %s must be deleted.' % i) #turn off a couple things that might mess with things pm.symmetricModelling(e=True, symmetry=False) pm.softSelect(e=True, softSelectEnabled=False) for i in range(verts): x = pm.getAttr(('%s.vlist[0].vertex[%i].xVertex' % (tweak, i))) y = pm.getAttr(('%s.vlist[0].vertex[%i].yVertex' % (tweak, i))) z = pm.getAttr(('%s.vlist[0].vertex[%i].zVertex' % (tweak, i))) if not (x + y + z) == 0: pm.error( 'You have used the tweak node. No me gusta. If you really wanna clear it, run clearTweaks and try again. It will save what you have' ) #ok, let's get started, first instance the original mesh sculptTrans = pm.instance(base, n=('%s_corrective_sculpt' % base))[0] pm.reorderDeformers(skin, tweak, base) pm.setAttr('%s.v' % base, False) #Here, we'll make a duplicate of the base to look back on later if need be (for instance, using sculpt geometry tends to not register on tweak) baseRef = pm.duplicate(base, n='%s_editReference' % base)[0] pm.connectAttr(('%s.outMesh' % baseRef.getShapes()[1]), ('%s.inMesh' % baseRef.getShape())) #We'll also hook up the original so we can get it later pm.addAttr(sculptTrans, ln='baseTransform', at='message') pm.addAttr(sculptTrans, ln='baseReference', at='message') pm.connectAttr('%s.message' % base, '%s.baseTransform' % sculptTrans) pm.connectAttr('%s.message' % baseRef, '%s.baseReference' % sculptTrans) #now to keep things from changing between functions, we'll lock the three nodes involved in the #other script so our pesky little user won't delete or rename anything pm.lockNode(base, l=True) pm.lockNode(sculptTrans, l=True)
def vertLocators(): """ Iterates through vertices on surface, attaches locators and objects """ # Selects all vertices, puts all vertice coordinates in a list pm.select(nameOfSurface) vs = pm.polyEvaluate(v=True) verts = [] vertLocCount = 0 for i in range(0, vs): verts += (pm.pointPosition(nameOfSurface + '.vtx[' + str(i) + ']'), ) # Creates locators for v in verts: numGen = r.random() if (numGen <= num): pm.spaceLocator(n="vertexLoc{0}".format(1), p=(v[0], v[1], v[2])) duplicatedObject = pm.instance(selectedObject, leaf=True) pm.setAttr(duplicatedObject[0] + '.translate', (v[0], v[1], v[2])) randomScaleNumber = r.randrange(minRandomScale, maxRandomScale) randomRotationNumber = r.randrange(minRandomRotation, maxRandomRotation) if randomScale is True: pm.setAttr(duplicatedObject[0] + '.scale', randomScaleNumber, randomScaleNumber, randomScaleNumber) if setToNormals is True: print(v) rotOrder = mc.getAttr(nameOfSurface + '.rotateOrder') pointOrigin = 0 originalPosition = om.MVector(v) print(originalPosition) # poly = PyNode(nameOfSurface) # pos = [v[0], v[1], v[2]] # count = 0 # for point in poly.getPoints('world'): # if dt.Vector(point) == dt.Vector(pos): # poly = PyNode(nameOfSurface + '.vtx[' + str(count) + ']') # normalVector = poly.getNormal() # print("normals: {0}".format(normalVector)) # count += 1 if randomRotation is True: pm.setAttr(duplicatedObject[0] + '.rotate', randomRotationNumber, randomRotationNumber, randomRotationNumber) if randomX is True: pm.setAttr(duplicatedObject[0] + '.rotateX', randomRotationNumber) if randomY is True: pm.setAttr(duplicatedObject[0] + '.rotateY', randomRotationNumber) if randomZ is True: pm.setAttr(duplicatedObject[0] + '.rotateZ', randomRotationNumber) vertLocCount += 1 totalVerts = round(float(vertLocCount) / vs * 100.0, 2) _logger.debug("Generated " + str(vertLocCount) + " locators at vertices for " + str(vs) + " possible vertices. (" + str(totalVerts) + "%) ")