-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for #135 bpy.context.[active_]object set to None after adding primitive when run from VS Code Extension #138
Conversation
…e when run from VS Code Extension JacquesLucke#135 # Summary of issue Calling a script via operator results in an empty context. # Related devtalk.blender from @JacquesLucke https://devtalk.blender.org/t/how-to-run-a-script-from-outside-blender-script-live-link-addon/9792/3?u=jacqueslucke # Solution Use bpy.app.timers to register a function to run the target script. # Changes pythonFiles\include\blender_vscode\operators\script_runner.py * remove the RunScriptOperator and move the contents of the execute method into a the `run_script()` function * register a timer callback to the `run_script()` function that will execute the target script # Potentially related issues * When adding objects to collections the objects only show after the script ends. JacquesLucke#101 * accessing bpy.context.object crashes Blender JacquesLucke#86 * Crash when adding mesh JacquesLucke#63 * Delete is skipped JacquesLucke#68 # Testing * execute a simple script that uses `bpy.context.active_object` * set the #context.area: SEQUENCE_EDITOR and run this script https://github.com/CGArtPython/blender_plus_python/blob/main/sequence_editor_frame_import/sequence_editor_frame_import_done.py * execute the script from issue JacquesLucke#101 JacquesLucke#101 * execute the script from issue JacquesLucke#86 JacquesLucke#86 * execute the script from issue JacquesLucke#63 JacquesLucke#63 * execute the script from issue JacquesLucke#68 JacquesLucke#68 * execute the script from issue JacquesLucke#41 JacquesLucke#41
Ready to make any changes based on the code review. I can also move this code out of the operator's folder since it no longer contains the operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just looking into the issue and it seems like the proposed fix does not work generally. It essentially removes the context-overrides created by prepare_script_context
. This happens to fix your script but can break other code. For example, see what happens when you print bpy.context.space_data
in the script: In master
this prints the 3d view space, but with this patch the result is None
.
I think the core issue for what causes the issue in #135 is that the context changes while the script is executed and the context-override is not valid anymore. The diff below also seems to fix the bug for me, maybe you can try that as well. The idea is that we only override the "important" part of the context, and leave the rest for Blender to figure out when actually accessing e.g bpy.context.active_object
.
diff --git a/pythonFiles/include/blender_vscode/operators/script_runner.py b/pythonFiles/include/blender_vscode/operators/script_runner.py
index 9159b90..a1d022d 100644
--- a/pythonFiles/include/blender_vscode/operators/script_runner.py
+++ b/pythonFiles/include/blender_vscode/operators/script_runner.py
@@ -42,16 +42,8 @@ def prepare_script_context(filepath):
context["view_layer"] = context["window"].view_layer
context["screen"] = context["window"].screen
context["workspace"] = context["window"].workspace
- context["active_object"] = context["view_layer"].objects.active
- context["object"] = context["active_object"]
- context["collection"] = context["view_layer"].active_layer_collection.collection
context["area"] = get_area_by_type(area_type)
- context["space_data"] = context["area"].spaces.active
- context["selected_objects"] = [obj for obj in context["view_layer"].objects if obj.select_get(view_layer=context["view_layer"])]
- context["selected_editable_objects"] = context["selected_objects"]
context["region"] = get_region_in_area(context["area"], region_type) if context["area"] else None
- if context["space_data"].type == "VIEW_3D":
- context["region_data"] = context["space_data"].region_3d
return context
def get_area_by_type(area_type):
You are right! I tested it with my scripts, and it looks like everything is working! I can close this PR. |
I committed the alternative fix in 621e275. |
- Capitalize global variables - Add type hints
Summary of issue
Calling a script via operator results in an empty context.
Related devtalk.blender
from @JacquesLucke
https://devtalk.blender.org/t/how-to-run-a-script-from-outside-blender-script-live-link-addon/9792/3?u=jacqueslucke
Solution
Use bpy.app.timers to register a function to run the target script.
Changes
pythonFiles\include\blender_vscode\operators\script_runner.py
run_script()
functionrun_script()
function that will execute the target scriptPotentially related issues
Testing
bpy.context.active_object