Gesture Helper is a convenient tool that allows you to effortlessly control Blender using gestures.
It supports both slow selection and fast gesture operations, catering to diverse usage scenarios.
· Sub-level gestures are supported, enabling fine-grained control over your actions.
· Right-click and one-click addition functions simplify common operations.
· A revolutionary press-and-drag definition system allows you to create custom operation sets without interfering with existing shortcut keys, fostering a personalized workflow. · It comes with MAYA presets and quick Blender operation presets for a smooth learning curve.
· Supports both Chinese and English languages, automatically switching based on your system settings.
Especially for Maya users accustomed to using Hotbox, Gesture Helper helps you regain a familiar and intuitive workflow in Blender.
Feel free to raise any issues on GitHub, and let's work together to enhance Gesture Helper!
Enhance security
This extension requests the following permission:
Import/export Gesture preset
Before we start diving into code review, can I ask how is this different from pie menus? I understand the visual part of it, it does indeed look very cool and arguably better/cleaner than pie menus, but I worry that this coolness comes on the expense of performance, because lot of GPU drawing needs to happen for this, and it is not trivial matter.
So, putting the cool design aside, talking about pure functionality, is this any different than pie menus? And before you answer I suggest you take a look at pie menu settings Preferences > Interface > Menus > Pie Menus and see how much it can be customized, as well as take a look at 3D Viewport Pie Menus add-on that utilizes some features that can be in pie menus that aren't in default Blender.
(I understand your confusion, perhaps I should save money to provide more English documents.) You can find the button to import gestures in the settings of the add-on (experience its purpose through default presets) Here is a video I recorded: https://www.bilibili.com/video/BV15M4m117ye/ Then, let me explain why I need to develop this add-on
I think the default shortcut key or pie meun is a standard. (Just like communicating in different languages, changing shortcut keys can create obstacles for ordinary users in communication and knowledge learning. (There are also annoying shortcut key conflicts)) But users still need to customize the functionality. Why destroy the existing shortcut keys? So I came up with another way - gestures, adding to the existing shortcut key system instead of replacing it. For example, pressing Z can pop up a shaping pie menu. You can also long press Z or press Z and drag the mouse directly, at which point you can directly pop up a gesture menu. 2) Quick operation, even one handed operation Long press to pop up the gesture menu, press and drag the mouse to directly execute the corresponding direction command. If set to the right mouse button, you can quickly switch functions with one hand 3) More levels than pie menu Pie menu has only one level, while gesture systems can support multiple levels. A single menu supports a maximum of 512 (8 * 8 * 8) commands. For example, you can use gestures to draw a "√" to save the file 4) Make customization easier - right-click directly to add commands to gesture menu Just like copying a drive, it can be directly added to the current gesture by right clicking on most commands. Finally, it has undergone considerable optimization in terms of performance. This tool was first developed in 2022 (demonstrated to Pablo during his last visit to Beijing, China), and although it was not publicly released until January 2024, it encountered performance issues in the early stages but made significant improvements after several refactoring attempts.
(I understand your confusion, perhaps I should save money to provide more English documents.)
You can find the button to import gestures in the settings of the add-on (experience its purpose through default presets)
Here is a video I recorded: https://www.bilibili.com/video/BV15M4m117ye/ Then, let me explain why I need to develop this add-on
I think the default shortcut key or pie meun is a standard. (Just like communicating in different languages, changing shortcut keys can create obstacles for ordinary users in communication and knowledge learning. (There are also annoying shortcut key conflicts))
But users still need to customize the functionality. Why destroy the existing shortcut keys? So I came up with another way - gestures, adding to the existing shortcut key system instead of replacing it.
For example, pressing Z can pop up a shaping pie menu. You can also long press Z or press Z and drag the mouse directly, at which point you can directly pop up a gesture menu.
Long press to pop up the gesture menu, press and drag the mouse to directly execute the corresponding direction command. If set to the right mouse button, you can quickly switch functions with one hand
Pie menu has only one level, while gesture systems can support multiple levels. A single menu supports a maximum of 512 (8 * 8 * 8) commands. For example, you can use gestures to draw a "√" to save the file
Just like copying a drive, it can be directly added to the current gesture by right clicking on most commands.
Finally, it has undergone considerable optimization in terms of performance. This tool was first developed in 2022 (demonstrated to Pablo during his last visit to Beijing, China), and although it was not publicly released until January 2024, it encountered performance issues in the early stages but made significant improvements after several refactoring attempts.
Right, I talked to Pablo and he explained it to me. Does indeed look very handy add-on.
On the code review side:
prop = f"preferences.addons['{ADDON_NAME}'].preferences.active_gesture{self.___element_value___(self.__property_data__)}.enabled"
__package__
should be used to access add-on preferences, not ADDON_NAME. For nested folders package should be imported from base folder.
https://docs.blender.org/manual/en/latest/extensions/addons.html#user-preferences-and-package
non_portable_backslash: Use of back-slash (often used for non-portable MS-Windows paths).
Common false positives include:
output\gesture_helper\source\gesture_helper\utils\icons.py:15:55:
icon_folder = os.path.join(ADDON_FOLDER, r'src\icon')
output\gesture_helper\source\gesture_helper\utils\texture.py:13:55:
icon_folder = os.path.join(ADDON_FOLDER, r'src\icon')
src\icon might fail on some systems. For safety you should join src and icon folders with os.path.join
error_prone_builtins:
Calls to potentially insecure functions exec()
& eval()
.
Besides security implications if this comes from an untrusted source. This often hints at poor code.
getattr(data, attr)
& setattr(data, attr, value)
can be an alternative.ast.parse(...)
then ast.literal_eval(node)
.output\gesture_helper\source\gesture_helper\element\element_operator.py:19:26:
properties = eval(ps) # 高威
output\gesture_helper\source\gesture_helper\ops\modal_mouse.py:138:13:
exec("bpy.context.{:s} = int({:d})".format(self.data_path, round(self.___value___ + delta)))
output\gesture_helper\source\gesture_helper\ops\modal_mouse.py:140:13:
exec("bpy.context.{:s} = {:f}".format(self.data_path, self.___value___ + delta))
output\gesture_helper\source\gesture_helper\src\translate\__init__.py:105:16:
return eval(text)
output\gesture_helper\source\gesture_helper\utils\string_eval.py:68:16:
return eval(eval_string, __globals, __poll_args())
output\gesture_helper\source\gesture_helper\utils\string_eval.py:73:16:
return exec(eval_string, __globals, __poll_args())
It would be good to make changes for all your submitted add-ons. All of them seem to have same quality issues that we have to go through one by one and that slows down approval process by a lot.
At present, we are a non-profit open source organization, and some of the developers in our team are relatively young. I will unify these development standards with the developers this week. Thank you for providing these suggestions, which will definitely enable us to submit more useful tools in a standardized manner in the future.
Documentation isn't thorough yet, but you can read some safety requirements here in Violations and Code Quality sections
https://developer.blender.org/docs/features/extensions/moderation/guidelines/#violations-in-code
Hi, I'm responsible for the maintenance of this addon, all other problems have been solved, but I can't find a better solution for the security of eval and exec.
exel: I check the expression once before executing exec, because ast.literal_eval
can't perform ==
operation(bpy.context.space_data.type == "VIEW_3D"
), so it can only be realized in this way.
ast.literal_eval("1 == 1")
Traceback (most recent call last):
ValueError: malformed node or string on line 1: <ast.Compare object at 0x0000013CFDD6BB80>
```<br>
<br>exec: there is only one place in the addon where the user-defined script is used as an operator to execute the function, this is also checked and then executed, if there is no better solution, then we may have to remove this function!<br><br>
The code for the check is here `try_call_eval` and `try_call_exec`<br>
[try call](https://github.com/AIGODLIKE/gesture_helper/blob/3fc640d473dc73d481da3bfb821232ccb2622f41/utils/string_eval.py#L66)
Can you tell me exactly where this is happening in code?
Here is the code I wrote for the security check View code
<br> <br> disallowed ``` __shield = {'Del', 'Import', 'Lambda', 'Return', 'Global', 'Assert', 'ClassDef', 'ImportFrom', # 'Module', # 'Expr', # 'Call', } ```
Use ast.dump
to determine if the input expression contains a type that is not allowed, and if so, return an exception.
def __check_shield(eval_string):
dump_data = ast.dump(ast.parse(eval_string), indent=2)
is_shield = {i for i in __shield if i in dump_data}
if is_shield:
e = Exception(f'input poll_string is invalid\t{is_shield} of {eval_string}')
print(e)
return e
Run eval after checking that there are no problems<br>
def try_call_eval(eval_string: str):
if __check_shield(eval_string) is not Exception:
return eval(eval_string, __globals, __poll_args())
My first impression was that you simply do not need to be doing any of that. It is very "python-y" way of doing things, don't think bpy needs that much protections and prints, this is very overcomplicated piece of bpy code, but I made peace with your groups coding style, so let it be.
But I opened code to look further and found some more issues.
First of all, bl_idname
of AddonPreferences should be __package__
not the name of the add-on. Any time you're accessing preferences should also use package, or import package from the root folder (please make this change for all your add-ons. Poor quality of your submissions is taking most of my time on this platform).
https://docs.blender.org/manual/en/latest/advanced/extensions/addons.html#user-preferences-and-package
I see __is_enabled_addon__
function. What is that for? Whole __globals
thing is confusing to me.
What is TempDrawProperty
for? Chinese name and descriptions prevent me from understanding it.
I'm sorry for the trouble, please give me some time to change the code.
The bl_idname of AddonPreferences has been changed to package, the new code has not been uploaded yet.
__is_enabled_addon__
This is a user-used method for use in expressions that allows the user to condition on whether or not the addon is enabled.
eval and exec use
__globals
is a global parameter for safe use of eval and exec to avoid exposing more built-in methods.
TempDrawProperty
This is used when drawing the interface.
It's used to add the draw-expand boolean property in real time.
It is retrieved by an identifier and created if the property does not exist.
I will approve this with eval() and exec(), if other moderators have issues with that they can request it after approval, and I believe maintainers will respond, as they have proven to be collaborative and active.
Sign in to comment.
Ready for review