Hey guys.
Yea I know the title sounds a little negative, but I’m really just curious here.
Why do we have Iterators like MItMeshFace and MItMeshVertex instead of just functions in the functionsets?
Is it to avoid copying out huge lists, editing them and copying them back in?
Do iterators do some kind of magic by the way they are traversing the datastructures?
Is it bad practice to not use next to traverse them, but instead just jump around in the index?
The last question is because I used a MItMeshVertex iterator in parallel with an MItMeshEdge iterator,
to go through all vertices in a mesh, find connected edges and just feed those returned indices into the MItMeshEdge iterator to work on.
Because i could not figure out how to make an iterator only run through a predefined list of indices and because it seemed expensive to initialize a new iterator every time (Not that I know…).
I since realized I could have used the edge indices to query through an MFnMesh and I still feel I did something wrong with not using a iterator “as I should” so I wanted to ask the experts for help.
Thanks!
For those curious, my script is for baking curvature into vertices and though it’s a little messy it works fine. Here it is:
#Color by Curvature
#by Martin Baadsgaard
#v. 0.8.1
import pymel.core as pm
import pymel.core.datatypes as dt
import maya.api.OpenMaya as om
from pymel.all import *
import random as rand
class colorByCurvature ():
def __init__(self, *args):
if pm.window("CbCWin", exists=True):
deleteUI("CbCWin")
self.abortBool = False
def doColoring(self, *args):
#Get vertices and also a clean list of their indices
colorList = []
vertNormal = om.MVector()
length = 0.0
selection = om.MGlobal.getActiveSelectionList()
if not selection.isEmpty():
dag = selection.getDagPath(0)
mesh = om.MFnMesh(dag)
mainList = []
vert_itr = om.MItMeshVertex(dag)
edge_itr = om.MItMeshEdge(dag)
self.progressor.setEnable(True)
self.progressor.setMaxValue(vert_itr.count())
while not vert_itr.isDone():
vertNormal = vert_itr.getNormal()
vertEdges = vert_itr.getConnectedEdges()
#Get edge properties
edgeAngles = []
edgeLengths = []
edgeLenMax = 0
p1 = vert_itr.position()
for ind in vertEdges:
edge_itr.setIndex(ind)
edgeLength = edge_itr.length()
edgeLengths.append(edgeLength)
edgeLenMax = max(edgeLenMax, edgeLength)
conVerts = [edge_itr.vertexId(x) for x in [0,1]]
if conVerts[0] == vert_itr.index():
p2 = edge_itr.point(1)
else:
p2 = edge_itr.point(0)
px = p2-p1
om.MVector.normalize(px)
edgeAngles.append(px)
edgeDotMax = 0.0
edgeDotMaxLen = 0
edgeDotMin = 1000000.0
edgeDotMinLen = 1
#Calculate edge weightings, We find the highest and lowest only, to avoid "dilution" by number of edges branching this vertex
for edgeW in range(len(edgeAngles)):
edgeLen = edgeLengths[edgeW]/edgeLenMax
edgeLen = 1 + ((self.edgeDistBias.getValue())/100)*(edgeLen-1)
edgeDot = vertNormal*edgeAngles[edgeW]
if edgeDot > edgeDotMax:
edgeDotMax = edgeDot
edgeDotMaxLen = edgeLen
if edgeDot < edgeDotMin:
edgeDotMin = edgeDot
edgeDotMinLen = edgeLen
#print("Maximum edge angle: " + str(edgeDotMax))
#print("Minimum edge angle: " + str(edgeDotMin))
edgeDotAverage = -(edgeDotMax*edgeDotMaxLen+edgeDotMin*edgeDotMinLen)*self.edgeContrast.getValue()+0.5
col = om.MColor()
col.r = edgeDotAverage
col.g = edgeDotAverage
col.b = edgeDotAverage
col.a = 1
colorList.append(col)
self.progressor.step(1)
vert_itr.next()
print mesh
mesh.setVertexColors(colorList, range(mesh.numVertices))
mesh.updateSurface()
pm.polyColorPerVertex (colorDisplayOption=True)
self.progressor.setEnable(False)
self.progressor.setProgress(0)
def toggleView(self, *args):
mel.toggleShadeMode()
def ui(self):
self.win = pm.window("CbCWin", title="Color vertices by Curvature")
self.layout = pm.columnLayout()
self.edgeDistBias = pm.floatSliderGrp(label="Edge Distance Bias", columnWidth3=(100, 40, 120), field=True)
self.edgeContrast = pm.floatSliderGrp(label="Curvature Contrast", columnWidth3=(100, 40, 120), field=True, value=0.5, min=0, max=2)
self.blendBtn = pm.button(label="Color by Curvature", command=self.doColoring)
self.viewButton = pm.button(label="Toggle Vertex Color Display", command=self.toggleView)
#self.angleWeightBool = pm.checkBox(label="Use Angleweighted Normals", value=True)
self.progressor = pm.progressBar(enable=False, progress=0, width=260)
#pm.setParent('..')
self.win.show()
myUI = colorByCurvature()
myUI.ui()