def promptExportControl(*args): '''Export selection, prompt for name, and create icon as well. ''' sel = mc.ls(sl=True) assert sel, 'Select a control curve(s) to export.' for each in sel: if mc.nodeType(each) == 'nurbsCurve': continue shapes = mc.listRelatives(each, shapes=True, type='nurbsCurve') assert shapes, '{} is not a nurbsCurve'.format(each) result = mc.promptDialog(title='Export Control Curve', message='Enter Name:', button=['OK', 'Cancel'], defaultButton='OK', cancelButton='Cancel', dismissString='Cancel') if result != 'OK': return ctrlName = mc.promptDialog(query=True, text=True) ctrlName = ''.join(x if x.isalnum() else '_' for x in ctrlName) if os.path.exists(controlFilePath(ctrlName)): result = mc.confirmDialog( title='Control Exists', message='A control of this name already exists.', button=['Overwrite', 'Cancel'], defaultButton='Cancel', cancelButton='Cancel', dismissString='Cancel') if result != 'Overwrite': return ctrl = exportControl(sel, ctrlName) strokes = mc.ls(type='stroke') #create the icon mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush + '.screenspaceWidth', 1) mc.setAttr(brush + '.distanceScaling', 0.01) mc.setAttr(brush + '.color1', 0.1, 0.65, 1, type='double3') mc.select(ctrl) mc.AttachBrushToCurves(ctrl) image = utl.renderShelfIcon(name=ctrlName, width=64, height=64) imagePath = os.path.join(REPOSITORY_PATH, os.path.basename(image)) shutil.move(image, imagePath) #delete new strokes. newStrokes = [x for x in mc.ls(type='stroke') if x not in strokes] for each in newStrokes: mc.delete(mc.listRelatives(each, parent=True, pa=True))
def promptExportControl(*args): '''Export selection, prompt for name, and create icon as well. ''' sel = mc.ls(sl=True) assert sel, 'Select a control curve(s) to export.' for each in sel: if mc.nodeType(each) == 'nurbsCurve': continue shapes = mc.listRelatives(each, shapes=True, type='nurbsCurve') assert shapes, '{} is not a nurbsCurve'.format(each) result = mc.promptDialog( title='Export Control Curve', message='Enter Name:', button=['OK', 'Cancel'], defaultButton='OK', cancelButton='Cancel', dismissString='Cancel') if result != 'OK': return ctrlName = mc.promptDialog(query=True, text=True) ctrlName = ''.join(x if x.isalnum() else '_' for x in ctrlName) if os.path.exists(controlFilePath(ctrlName)): result = mc.confirmDialog(title='Control Exists', message='A control of this name already exists.', button=['Overwrite','Cancel'], defaultButton='Cancel', cancelButton='Cancel', dismissString='Cancel' ) if result != 'Overwrite': return ctrl = exportControl(sel, ctrlName) strokes = mc.ls(type='stroke') #create the icon mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush+'.screenspaceWidth', 1) mc.setAttr(brush+'.distanceScaling', 0.01) mc.setAttr(brush+'.color1', 0.1, 0.65, 1, type='double3') mc.select(ctrl) mc.AttachBrushToCurves(ctrl) image = utl.renderShelfIcon(name=ctrlName, width=64, height=64) imagePath = os.path.join(REPOSITORY_PATH, os.path.basename(image)) shutil.move(image, imagePath) #delete new strokes. newStrokes = [x for x in mc.ls(type='stroke') if x not in strokes] for each in newStrokes: mc.delete(mc.listRelatives(each, parent=True, pa=True))
def traceArc(space='camera'): ''' The main function for creating the arc. ''' if space != 'world' and space != 'camera': OpenMaya.MGlobal.displayWarning('Improper space argument.') return global ML_TRACE_ARC_PREVIOUS_SELECTION global ML_TRACE_ARC_PREVIOUS_SPACE #save for reset: origTime = mc.currentTime(query=True) #frame range frameRange = utl.frameRange() start = frameRange[0] end = frameRange[1] #get neccesary nodes objs = mc.ls(sl=True, type='transform') if not objs: OpenMaya.MGlobal.displayWarning('Select objects to trace') return ML_TRACE_ARC_PREVIOUS_SELECTION = objs ML_TRACE_ARC_PREVIOUS_SPACE = space cam = None nearClipPlane = None shortCam = '' if space=='camera': cam = utl.getCurrentCamera() #the arc will be placed just past the clip plane distance, but no closer than 1 unit. nearClipPlane = max(mc.getAttr(cam+'.nearClipPlane'),1) shortCam = mc.ls(cam, shortNames=True)[0] topGroup = 'ml_arcGroup' worldGrp = 'ml_arcWorldGrp' localGrp = 'ml_localGrp_'+shortCam #create nodes if not mc.objExists(topGroup): topGroup = mc.group(empty=True, name=topGroup) parentGrp = topGroup if space=='world' and not mc.objExists(worldGrp): worldGrp = mc.group(empty=True, name=worldGrp) mc.setAttr(worldGrp+'.overrideEnabled',1) mc.setAttr(worldGrp+'.overrideDisplayType',2) mc.parent(worldGrp, topGroup) parentGrp = mc.ls(worldGrp)[0] if space == 'camera': camConnections = mc.listConnections(cam+'.message', plugs=True, source=False, destination=True) if camConnections: for cc in camConnections: if '.ml_parentCam' in cc: localGrp = mc.ls(cc, o=True)[0] if not mc.objExists(localGrp): localGrp = mc.group(empty=True, name=localGrp) mc.parentConstraint(cam, localGrp) mc.setAttr(localGrp+'.overrideEnabled',1) mc.setAttr(localGrp+'.overrideDisplayType',2) mc.parent(localGrp, topGroup) mc.addAttr(localGrp, at='message', longName='ml_parentCam') mc.connectAttr(cam+'.message', localGrp+'.ml_parentCam') parentGrp = mc.ls(localGrp)[0] #group per object: group = list() points = list() for i,obj in enumerate(objs): sn = mc.ls(obj,shortNames=True)[0] name = sn.replace(':','_') points.append(list()) groupName = 'ml_%s_arcGrp' % name if mc.objExists(groupName): mc.delete(groupName) group.append(mc.group(empty=True, name=groupName)) group[i] = mc.parent(group[i],parentGrp)[0] mc.setAttr(group[i]+'.translate', 0,0,0) mc.setAttr(group[i]+'.rotate', 0,0,0) with utl.UndoChunk(): with utl.IsolateViews(): #helper locator loc = mc.spaceLocator()[0] mc.parent(loc,parentGrp) #frame loop: time = range(int(start),int(end+1)) for t in time: mc.currentTime(t, edit=True) #object loop for i,obj in enumerate(objs): objPnt = mc.xform(obj, query=True, worldSpace=True, rotatePivot=True) if space=='camera': camPnt = mc.xform(cam, query=True, worldSpace=True, rotatePivot=True) objVec = euclid.Vector3(objPnt[0],objPnt[1],objPnt[2]) camVec = euclid.Vector3(camPnt[0],camPnt[1],camPnt[2]) vec = objVec-camVec vec.normalize() #multiply here to offset from camera vec=vec*nearClipPlane*1.2 vec+=camVec mc.xform(loc, worldSpace=True, translation=vec[:]) trans = mc.getAttr(loc+'.translate') points[i].append(trans[0]) elif space=='world': points[i].append(objPnt) mc.delete(loc) #create the curves and do paint effects mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.005) for i,obj in enumerate(objs): #setup brush for path mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.003) #color for c in ('R','G','B'): color = random.uniform(0.3,0.7) mc.setAttr(brush+'.color1'+c,color) baseCurve = mc.curve(d=3,p=points[i]) #fitBspline makes a curve that goes THROUGH the points, a more accurate path curve = mc.fitBspline(baseCurve, constructionHistory=False, tolerance=0.001) mc.delete(baseCurve) #paint fx mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] stroke = mc.parent(stroke,group[i])[0] mc.setAttr(stroke+'.overrideEnabled',1) mc.setAttr(stroke+'.overrideDisplayType',2) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) curve = mc.parent(curve,group[i])[0] mc.setAttr(curve+'.translate',0,0,0) mc.setAttr(curve+'.rotate',0,0,0) mc.hide(curve) #setup brush for tics if space=='camera': mc.setAttr(brush+'.brushWidth',0.008) if space=='world': mc.setAttr(brush+'.brushWidth',0.005) mc.setAttr(brush+'.color1G',0) mc.setAttr(brush+'.color1B',0) for t in range(len(points[i])): frameCurve = None if space=='camera': vec = euclid.Vector3(points[i][t][0],points[i][t][1],points[i][t][2]) vec*=0.98 frameCurve = mc.curve(d=1,p=[points[i][t],vec[:]]) elif space=='world': frameCurve = mc.circle(constructionHistory=False, radius=0.0001, sections=4)[0] mc.setAttr(frameCurve+'.translate', points[i][t][0], points[i][t][1] ,points[i][t][2]) constraint = mc.tangentConstraint(curve, frameCurve, aimVector=(0,0,1), worldUpType='scene') #mc.delete(constraint) #check for keyframe colorAttribute='color1G' if mc.keyframe(obj, time=((t+start-0.5),(t+start+0.5)), query=True): mc.setAttr(brush+'.color1R',1) else: mc.setAttr(brush+'.color1R',0) mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] thisBrush = mc.listConnections(stroke+'.brush', destination=False)[0] #setup keyframes for frame highlighting mc.setKeyframe(thisBrush, attribute='color1G', value=0, time=(start+t-1, start+t+1)) mc.setKeyframe(thisBrush, attribute='color1G', value=1, time=(start+t,)) stroke = mc.parent(stroke,group[i])[0] mc.hide(frameCurve) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) frameCurve = mc.parent(frameCurve,group[i])[0] if space=='camera': mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.pressureScale[1].pressureScale_Position', 1) mc.setAttr(stroke+'.pressureScale[1].pressureScale_FloatValue', 0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) mc.setAttr(frameCurve+'.translate',0,0,0) mc.setAttr(frameCurve+'.rotate',0,0,0) mc.currentTime(origTime, edit=True) panel = mc.getPanel(withFocus=True) mc.modelEditor(panel, edit=True, strokes=True) mc.select(objs,replace=True)
def traceArc(space='camera'): ''' The main function for creating the arc. ''' if space not in ('world','camera'): OpenMaya.MGlobal.displayWarning('Improper space argument.') return global ML_TRACE_ARC_PREVIOUS_SELECTION global ML_TRACE_ARC_PREVIOUS_SPACE globalScale = 1 if mc.optionVar(exists='ml_arcTracer_brushGlobalScale'): globalScale = mc.optionVar(query='ml_arcTracer_brushGlobalScale') #save for reset: origTime = mc.currentTime(query=True) #frame range frameRange = utl.frameRange() start = frameRange[0] end = frameRange[1] #get neccesary nodes objs = mc.ls(sl=True, type='transform') if not objs: OpenMaya.MGlobal.displayWarning('Select objects to trace') return ML_TRACE_ARC_PREVIOUS_SELECTION = objs ML_TRACE_ARC_PREVIOUS_SPACE = space cam = None nearClipPlane = None shortCam = '' if space=='camera': cam = utl.getCurrentCamera() #the arc will be placed just past the clip plane distance, but no closer than 1 unit. nearClipPlane = max(mc.getAttr(cam+'.nearClipPlane'),1) shortCam = mc.ls(cam, shortNames=True)[0] topGroup = 'ml_arcGroup' worldGrp = 'ml_arcWorldGrp' localGrp = 'ml_localGrp_'+shortCam #create nodes if not mc.objExists(topGroup): topGroup = mc.group(empty=True, name=topGroup) parentGrp = topGroup if space=='world' and not mc.objExists(worldGrp): worldGrp = mc.group(empty=True, name=worldGrp) mc.setAttr(worldGrp+'.overrideEnabled',1) mc.setAttr(worldGrp+'.overrideDisplayType',2) mc.parent(worldGrp, topGroup) parentGrp = mc.ls(worldGrp)[0] if space == 'camera': camConnections = mc.listConnections(cam+'.message', plugs=True, source=False, destination=True) if camConnections: for cc in camConnections: if '.ml_parentCam' in cc: localGrp = mc.ls(cc, o=True)[0] if not mc.objExists(localGrp): localGrp = mc.group(empty=True, name=localGrp) mc.parentConstraint(cam, localGrp) mc.setAttr(localGrp+'.overrideEnabled',1) mc.setAttr(localGrp+'.overrideDisplayType',2) mc.parent(localGrp, topGroup) mc.addAttr(localGrp, at='message', longName='ml_parentCam') mc.connectAttr(cam+'.message', localGrp+'.ml_parentCam') parentGrp = mc.ls(localGrp)[0] #group per object: group = [] for i,obj in enumerate(objs): sn = mc.ls(obj,shortNames=True)[0] name = sn.replace(':','_') groupName = 'ml_{}_arcGrp'.format(name) if mc.objExists(groupName): mc.delete(groupName) group.append(mc.group(empty=True, name=groupName)) group[i] = mc.parent(group[i],parentGrp)[0] mc.setAttr(group[i]+'.translate', 0,0,0) mc.setAttr(group[i]+'.rotate', 0,0,0) with utl.UndoChunk(): #determine the method to run. Test fast against accurate. #If fast is the same, continue with fast method. #Otherwise revert to accurate method. mc.currentTime(start) fastPoints = arcDataFast([objs[0]], parentGrp, start+1, start+1, space, nearClipPlane, cam) accuratePoints = arcDataAccurate([objs[0]], parentGrp, start+1, start+1, space, nearClipPlane, cam) points = None #if they're equivalent, continue with fast: if [int(x*1000000) for x in fastPoints[0][0]] == [int(x*1000000) for x in accuratePoints[0][0]]: points = arcDataFast([objs[0]], parentGrp, start, end, space, nearClipPlane, cam) else: points = arcDataAccurate([objs[0]], parentGrp, start, end, space, nearClipPlane, cam) #create the curves and do paint effects mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.005) for i,obj in enumerate(objs): #setup brush for path globalScale mc.setAttr(brush+'.globalScale', globalScale) mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.003) #color for c in ('R','G','B'): color = random.uniform(0.3,0.7) mc.setAttr(brush+'.color1'+c,color) baseCurve = mc.curve(d=3,p=points[i]) #fitBspline makes a curve that goes THROUGH the points, a more accurate path curve = mc.fitBspline(baseCurve, constructionHistory=False, tolerance=0.001, name='ml_arcTracer_curve_#') mc.delete(baseCurve) #paint fx mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] mc.rename(mc.listConnections(stroke+'.brush', destination=False)[0], 'ml_arcTracer_brush_#') stroke = mc.parent(stroke,group[i])[0] mc.setAttr(stroke+'.overrideEnabled',1) mc.setAttr(stroke+'.overrideDisplayType',2) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) curve = mc.parent(curve,group[i])[0] mc.setAttr(curve+'.translate',0,0,0) mc.setAttr(curve+'.rotate',0,0,0) mc.hide(curve) #setup brush for tics if space=='camera': mc.setAttr(brush+'.brushWidth',0.008) if space=='world': mc.setAttr(brush+'.brushWidth',0.005) mc.setAttr(brush+'.color1G',0) mc.setAttr(brush+'.color1B',0) for t in range(len(points[i])): frameCurve = None if space=='camera': vec = utl.Vector(points[i][t][0],points[i][t][1],points[i][t][2]) vec*=0.98 frameCurve = mc.curve(d=1,p=[points[i][t],vec[:]]) elif space=='world': frameCurve = mc.circle(constructionHistory=False, radius=0.0001, sections=4)[0] mc.setAttr(frameCurve+'.translate', points[i][t][0], points[i][t][1], points[i][t][2]) constraint = mc.tangentConstraint(curve, frameCurve, aimVector=(0,0,1), worldUpType='scene') #mc.delete(constraint) #check for keyframe colorAttribute='color1G' if mc.keyframe(obj, time=((t+start-0.5),(t+start+0.5)), query=True): mc.setAttr(brush+'.color1R',1) else: mc.setAttr(brush+'.color1R',0) mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] thisBrush = mc.listConnections(stroke+'.brush', destination=False)[0] thisBrush = mc.rename(thisBrush, 'ml_arcTracer_brush_#') #setup keyframes for frame highlighting mc.setKeyframe(thisBrush, attribute='color1G', value=0, time=(start+t-1, start+t+1)) mc.setKeyframe(thisBrush, attribute='color1G', value=1, time=(start+t,)) stroke = mc.parent(stroke,group[i])[0] mc.hide(frameCurve) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) frameCurve = mc.parent(frameCurve,group[i])[0] if space=='camera': mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.pressureScale[1].pressureScale_Position', 1) mc.setAttr(stroke+'.pressureScale[1].pressureScale_FloatValue', 0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) mc.setAttr(frameCurve+'.translate',0,0,0) mc.setAttr(frameCurve+'.rotate',0,0,0) mc.currentTime(origTime, edit=True) panel = mc.getPanel(withFocus=True) try: mc.modelEditor(panel, edit=True, strokes=True) except: pass mc.select(objs,replace=True) mc.refresh()