Reputation: 23
I am currently trying to give each subobject of a DAG node a different color. It works when I am selecting each of those subobject/elements (but not all)in the component select mode and then run the script over it. But selecting the mesh as whole, does not work for me. I already tried different kinds of listRelatives but none worked. I can get into the object and get each vertices, but they are not grouped by connectivity.
def assignDMat(self,*args):
#selection = self.selector()
selection = cmds.ls(selection=True)
for j in range(0, len(selection)):
cmds.polyColorPerVertex(selection[j], r=0, g=0, b=0, cdo=True)
cmds.polyColorPerVertex(selection[j], r=random.uniform(0,1), cdo=True)
New code:
import maya.cmds as cmds
import random
selection = cmds.ls(selection=True)
cmds.polySeparate(selection)
for i in range(0,len(selection)):
obj=cmds.listRelatives(selection[i])
print(len(obj))
for j in range(0,len(obj)-1):
cmds.polyColorPerVertex(obj[j], r=0, g=0, b=0, cdo=True)
cmds.polyColorPerVertex(obj[j], r=random.uniform(0,1), cdo=True)
cmds.polyUnite(("polySurface*"), n="Result", ch=False)
Upvotes: 1
Views: 3145
Reputation: 4783
Using separate then re-merging the meshes can cause a lot of unexpected issues, some which you have already ran into, so it's best to avoid that.
Instead we can create a function that will return all separate shells of an object by returning a bunch of lists of their face indexes. This can be done with cmds.polySelect
to pass a face index to it, then it'll select the whole shell. Since the shell is now selected we can now just collect the new selection and continue on to get the next shell. Then with that it's easy to just loop through each of them and color them with cmds.polyColorPerVertex
.
Here's an example that will create a random amount of poly spheres, combine them all, then set a random color to each shell:
import random
import maya.cmds as cmds
# Just makes a bunch of random spheres, combines them, then returns the new mesh.
def make_bunch_of_spheres():
meshes = []
for i in range(random.randint(20, 50)):
meshes.append(cmds.polySphere()[0])
cmds.move(random.randint(-20, 20), random.randint(-20, 20), random.randint(-20, 20), meshes[-1])
return cmds.polyUnite(meshes, constructionHistory=False)[0]
def get_shell_faces():
shells = [] # We'll be putting in lists of face indexes in here later. Each sub-list will represent a separate shell.
sel = cmds.ls(sl=True)
for obj in sel:
faces = cmds.ls(obj + ".f[*]", flatten=True) # Get all face indexes from the object.
for face in faces:
index = int(face.split("[")[1].rstrip("]")) # Extract the faces index number.
cmds.polySelect(obj, extendToShell=index) # Use the face's index to select the whole shell.
new_faces = cmds.ls(sl=True, flatten=True) # Now that the shell is selected, capture its faces.
shells.append(new_faces) # Append the face's as a new shell.
# Remove indexes from the new shell from this current loop, to optimize, and to avoid adding duplicate shells.
for new_face in new_faces:
if new_face in faces:
faces.pop(faces.index(new_face))
cmds.select(sel) # Restore selection.
return shells
# Create a bunch of combined spheres then select it.
new_mesh = make_bunch_of_spheres()
cmds.select(new_mesh)
shells = get_shell_faces() # Get shells from selection.
# Color each shell!
for shell in shells:
cmds.polyColorPerVertex(shell, r=random.random(), g=random.random(), b=random.random(), cdo=True)
Upvotes: 3
Reputation: 23
Currently workling solution. It does not have any failsafes or so. For example if the object does not have a parent, it will probably give an error. In my case this works. Thanks a lot for the input, DrWeeny.
import maya.cmds as cmds
import random
par=cmds.listRelatives(cmds.ls(selection=True),p=True)
selection = cmds.ls(selection=True)
cmds.select(selection)
pivotTranslate = cmds.xform (selection[0], q = True, ws = True, rotatePivot = True)
print(piv)
cmds.polySeparate(selection)
for i in range(0,len(selection)):
obj=cmds.listRelatives(selection[i])
print(len(obj))
for j in range(0,len(obj)-1):
cmds.polyColorPerVertex(obj[j], r=0, g=0, b=0, cdo=True)
cmds.polyColorPerVertex(obj[j], r=random.uniform(0,1), cdo=True)
cmds.polyUnite(("polySurface*"), n=selection[0], ch=False)
cmds.xform (selection[0], ws = True, pivots = pivotTranslate)
cmds.select(par)
cmds.parent(selection[0])
Upvotes: 1
Reputation: 2512
import random
obj = cmds.ls(selection=True)
obj_vtx = [cmds.ls(o + '.vtx[*]', fl=True) for o in obj]
for obj in obj_vtx:
color_id = random.uniform(0,1)
for vtx in obj:
cmds.polyColorPerVertex(vtx, r=0, g=0, b=0, cdo=True)
cmds.polyColorPerVertex(vtx, r=color_id, cdo=True)
EDIT : put the color in the object loop
Upvotes: 1