That is awesome!
Thank you for sharing this. Lets see how we can integrate this.
Also, on the scaling issue referenced.
That is awesome!
Thank you for sharing this. Lets see how we can integrate this.
Also, on the scaling issue referenced.
youâre welcome guys
Awesome addition! The way we dealt with pickers at Disney was something similar: we can alter some basic transforms in the picker itself, but for more advanced shapes, the button was copied in the viewport to be altered, and then back to the picker.
Thanks for sharing!
so i was having a look at adding the text, and i thought iâd check to see if the text is the same between 4k and 1080p i was right to be suspicious, the text draws different on 4k as you can see below
so i had a quick look in code in:
anim_picker.widgets.picker_widgets.GraphicText().set_size()
font.setPointSizeF(value / pm.mayaDpiSetting(q=True, realScaleValue=True))
this fixed it
i saw in another thread i started about a similar issue @JxE said that pm.mayaDpiSetting is not available on mac and suggested using devicePixelRatio so i tried
pyqt.maya_main_window().devicePixelRatio()
however this returns 1 not the expected 1.5 as set in windows.
Thatâs odd, was your Maya main window on your 4k monitor when you ran the code? Weâre seeing it return the correct scaling on our macs when we run that, but maybe it doesnât work on Windows?
yeah i ran these two code snippets one after the other same maya session
pyqt.maya_main_window().devicePixelRatio()
# Result: 1 #
pm.mayaDpiSetting(q=True, realScaleValue=True)
# Result: 1.5 #
Itâs possible itâs only telling the difference between retina and non-retina displays and maybe your 4k monitor doesnât count? https://doc.qt.io/qtforpython/PySide2/QtGui/QScreen.html#PySide2.QtGui.PySide2.QtGui.QScreen.devicePixelRatio
There may be a hint here, but I canât dig into it too much right now: https://doc.qt.io/qt-5/qscreen.html#details
On iMac 5K screen and on Macbook Pro Retina, I get 2.
For fun, in case it helps, here is everything it returns on the 5K screen.
import maya.OpenMayaUI as omui
from mgear.vendor.Qt import QtCompat
from mgear.vendor.Qt import QtWidgets
main_window_ptr = omui.MQtUtil.mainWindow()
maya_main_window = QtCompat.wrapInstance(long(main_window_ptr), QtWidgets.QWidget)
maya_main_window.colorCount()
// Result: 256 //
maya_main_window.depth()
// Result: 24 //
maya_main_window.devicePixelRatio()
// Result: 2 //
maya_main_window.devicePixelRatioF()
// Result: 2.0 //
maya_main_window.heightMM()
// Result: 329 //
maya_main_window.logicalDpiX()
// Result: 72 //
maya_main_window.logicalDpiY()
// Result: 72 //
maya_main_window.paintingActive()
// Result: False //
maya_main_window.physicalDpiX()
// Result: 109 //
maya_main_window.physicalDpiY()
// Result: 108 //
maya_main_window.widthMM()
// Result: 599 //
so my results here are windows 10 some lg 4k monitor these setting
maya_main_window.colorCount()
# Result: 256 #
maya_main_window.depth()
# Result: 32 #
maya_main_window.devicePixelRatio()
# Result: 1 #
maya_main_window.devicePixelRatioF()
# Result: 1.0 #
maya_main_window.heightMM()
# Result: 334 #
maya_main_window.logicalDpiX()
# Result: 144 #
maya_main_window.logicalDpiY()
# Result: 144 #
maya_main_window.paintingActive()
# Result: False #
maya_main_window.physicalDpiX()
# Result: 163 #
maya_main_window.physicalDpiY()
# Result: 161 #
maya_main_window.widthMM()
# Result: 600 #
the logicalDpi seems to match with what maya setting says maya is but then you get 72, i dunno
Hey guys, thanks for the information on different machines.
I am testing this solution on anim_pickers and channel master
I have not applied to it to every aspect of the anim_picker ui or channel master, just the parks looking the most affected by the dpi.
Hi JimBo_Drew,
I donât know how to use the code you posted at the top of the thread but it looks really exciting!!!
Thanks
I was testing this out today and realized rotation wasnât supported. You can read and write rotation by adding:
In extract_picker_data()
for item in tab['data']['items']:
rotValue = item['rotation']
item_curve.rz.set(rotValue)
In overwrite_picker_data()
item_data['rotation'] = item_curve.rz.get()
Full example:
import pymel.core as pm
from PySide2 import QtGui
import mgear.core.attribute as attr
import mgear.anim_picker
from mgear.core import pyqt
import json
def extract_picker_data(factor = 0.1, background_fade = 0.5, showCVs=True):
animPickerUI = pyqt.get_instance(pyqt.get_main_window(), mgear.anim_picker.gui.MainDockWindow)
data = animPickerUI.get_character_data()
grp = pm.group(em=True, n='pickerData_extraction')
for tab in data['tabs']:
picker_grp = pm.group(em=True, n=tab['name'], p=grp)
if 'background' in tab['data'].keys():
ip = pm.imagePlane(n='{}_background'.format(tab['name']))
ip[0].tz.set(-1)
ip[0].overrideEnabled.set(1)
ip[0].overrideDisplayType.set(2)
ip[1].alphaGain.set(background_fade)
pm.parent(ip[0], picker_grp)
q_image = QtGui.QImage(tab['data']['background'])
ip[1].imageName.set(tab['data']['background'])
ip[1].width.set(q_image.size().width() * factor)
ip[1].height.set(q_image.size().height() * factor)
for item in tab['data']['items']:
handles = item['handles']
pos_x, pos_y = item['position']
rotValue = item['rotation']
item_curve = pm.circle(d=1, s=len(item['handles']), ch=False)[0]
pm.parent(item_curve, picker_grp)
pm.closeCurve(item_curve, ch=False, ps=2, rpo=True)
item_curve.displayHandle.set(1)
if showCVs:
item_curve.getShape().dispCV.set(1)
q_color = QtGui.QColor(*item['color'])
attr.addColorAttribute(item_curve, 'color', q_color.getRgbF()[:3])
attr.addAttribute(item_curve, 'alpha', 'long', item['color'][3], minValue=0, maxValue=255)
item_curve.overrideEnabled.set(1)
item_curve.overrideRGBColors.set(1)
item_curve.color >> item_curve.overrideColorRGB
item_curve.rotatePivot >> item_curve.selectHandle
item_curve.rz.set(rotValue)
if 'controls' in item.keys():
attr.addAttribute(item_curve, 'controls', 'string', json.dumps(item['controls']))
if 'action_mode' in item.keys():
attr.addAttribute(item_curve, 'action_mode', 'bool', item['action_mode'])
attr.addAttribute(item_curve, 'action_script', 'string', item['action_script'])
if 'menus' in item.keys():
attr.addAttribute(item_curve, 'menus', 'string', json.dumps(item['menus']))
if 'text' in item.keys():
attr.addAttribute(item_curve, 'text_data', 'string', json.dumps({'text': item['text'],
'text_color': item['text_color'],
'text_size': item['text_size']}))
for i, (x, y) in enumerate(handles):
item_curve.getShape().controlPoints[i].set(x * factor, y * factor, 0)
item_curve.t.set(pos_x * factor, pos_y * factor, 0)
def overwrite_picker_data(factor = 0.1, data_node='PICKER_DATA', deleteCurves=True):
grp = pm.PyNode('pickerData_extraction')
new_data = {'tabs': []}
upscale = lambda x, y: [x * (1 / factor), y * (1 / factor)]
for tab_grp in grp.listRelatives():
new_data['tabs'].append({'name': tab_grp.name()})
new_data['tabs'][-1]['data'] = {'items': []}
bg_imagePlane = tab_grp.listRelatives(type='imagePlane', ad=True)
if bg_imagePlane:
new_data['tabs'][-1]['data']['background'] = bg_imagePlane[0].imageName.get()
for item_curve in [ic for ic in tab_grp.listRelatives() if ic.getShape().type() != 'imagePlane']:
item_data = {}
if item_curve.hasAttr('action_mode'):
item_data['action_mode'] = True
item_data['action_script'] = item_curve.action_script.get()
# color
q_color = QtGui.QColor()
q_color.setRgbF(*item_curve.color.get())
q_color.setAlpha(item_curve.alpha.get())
item_data['color'] = q_color.getRgb()
# controls
if item_curve.hasAttr('controls'):
item_data['controls'] = json.loads(item_curve.controls.get())
# position
item_data['position'] = upscale(*list(item_curve.getPivots(ws=True))[0][:2])
item_data['rotation'] = item_curve.rz.get()
# handles
item_curve.f.get()
handles = []
for cv in item_curve.cv[:-1 if item_curve.f.get() == 0 else None]:
x, y = upscale(*cv.getPosition(space='world')[:2])
handles.append([x - item_data['position'][0], y - item_data['position'][1]])
item_data['handles'] = handles
# menus
if item_curve.hasAttr('menus'):
item_data['menus'] = json.loads(item_curve.menus.get())
# text
if item_curve.hasAttr('text_data'):
item_data.update(json.loads(item_curve.text_data.get()))
new_data['tabs'][-1]['data']['items'].append(item_data)
if deleteCurves:
pm.delete(grp)
data_node = pm.PyNode(data_node)
data_node.picker_datas.set(l=False)
data_node.picker_datas.set(json.dumps(new_data).replace('true', 'True'))
data_node.picker_datas.set(l=True)
animPickerUI = pyqt.get_instance(pyqt.get_main_window(), mgear.anim_picker.gui.MainDockWindow)
animPickerUI.refresh()
@Moustache_Animation to use this, copy the entire script and run it. This will define the two functions. You could also save the script somewhere in your scripts directory and use âimportâ.
Then, to make the curves, run this:
extract_picker_data(factor = 0.1, background_fade = 0.5, showCVs=True)
To put the curves back into your data, make sure you use the correct PICKER_DATA node name, if you are using a different name:
overwrite_picker_data(factor = 0.1, data_node='PICKER_DATA', deleteCurves=True)
Note: The script will fail on the default template biped picker. Because some of the buttons have 2 vertices. The text buttons that are between the space-switch buttons have 2 vertices. If you turn the âVtx Countâ up to 4 on those buttons, it wonât fail anymore.
thatâs cool chris, i didnât know about the 2 vert buttons, totally makes sense that would fail the script though, i will change it to create a curve instead of a circle, iâve cleaned up the way i store data if it isnât need by maya also so it shouldnât miss things if they are not explicitly called like it done here
btw, I just noticed I did something wrong with my rotation. It works, but the 2nd time you build the curves, the curves have double rotation. I guess because your code reads the world orientation of the points, and then I rotate the transform above that.
Hey @JimBo_Drew
I finally got around to adding the additions you shared. Thank you again for that.
Convert to and from curves ¡ Issue #44 ¡ mgear-dev/anim_picker (github.com)
as the title says i have done a bunch of clean up to these functions things seem to work better now, I was having some issues with certain cases, but i think i have fixed all the bugs I found.
now rotations are not baked into verts when you bring the curves back.
I was getting a error when creating 2 point curves after doing some digging I see that this is supposed to create a circle but there was a bug preventing it from working, so i fixed that and implemented support for these circles in maya curves
added some attrs from adjusting background image size on tab group, this group can be move and scaled for convince how ever when you bring the data back this is ignored.
curves are no longer closed as this was causing issues, now if the first and last cv are the same the last is ignored
I have put in a pull request for these changes, let me know if i messed that up as i avery unfamilar with github.
Hi @JimBo_Drew I hope you donât mind! But I merged this to the old thread so it is easier to find the previous discussion.
I love this tool of yours! It makes editing the picker so easy and intuitive! Looking forward to the changes!