Hi all, trying to create a pretty simple script that creates a sidebar that has a button for “Crease and Sharp Edge” and “Uncrease and Soften Edge”.
Every time I try to load my script in Blender I get the error ‘RestrictContext’ object has no attribute ‘edit_object’
I have tried to read through the context stuff in the scripting documentation but it’s a bit over my head.
If anyone has any resources or advice on how to work through this as simply as possible it would be appreciated.
Thanks!
are you trying to execute it on startup? I’ve only ever seen context restricted when executing on startup without waiting for Blender to fully load using a timer or callback
I am just trying to get it to load inside of blender. It would just be a button that is pressed to execute an action. I don’t believe I am trying to execute it on startup.
Can you post your code? Would be a lot easier to see what’s happening
Yeah, without you posting context there’s just guessing. Pun maybe intended.
Jokes aside, I was just dealing with this issue yesterday. This error is Blender preventing access to bpy.context
and bpy.data
on startup so as to avoid referencing things that might not yet exist.
If you’re doing stuff directly on register()
, then you might want to begin looking there for your problem.
Some pointers:
Most recent documentation I could find on this (scroll down a bit)
https://archive.blender.org/wiki/index.php/Extensions:2.6/Py/API_Changes/
In my case I solved it by using a handler that runs the code after loading everything
https://blender.stackexchange.com/questions/137690/how-to-run-a-modal-operator-after-file-open
I believe that making your code a Blender add-on will circumvent all the problems you are having, have you tried this method yet?
Here is the code. I am trying to have it as an addon so I can have it loaded up in the sidebar and then make hotkeys / pie menus from there.
import bpy
import bmesh
#Main Functions
class CreaseAndSharp(bpy.types.Operator):
bl_idname = “mesh.crease_and_sharp”
bl_label = “CreaseAndSharp”
bl_description = “Crease Quickly”
bl_options = {‘REGISTER’, ‘UNDO’}
def crease(self, selection)
Get the active mesh
obj = bpy.context.edit_object
me = obj.data
Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
bm.faces.active = None
Modify the BMesh, can do anything here…
bpy.ops.transform.edge_crease(value=1)
bpy.ops.mesh.mark_sharp()
Show the updates in the viewport
and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)
return {‘FINISHED’}
Scanning through your code it doesn’t look like crease() ever gets called and you have a variable ‘selection’ that is never used, so how are you getting an exception on that line? Also, you’re creating a bmesh but then using bpy.ops and not even using the bmesh. Is this the actual code or some abridged version?
Regardless, I’m guessing that you actually want crease() to be execute(self, context). When you do that, just use context and not boy.context. Take a look at the example operator templates that ship with blender for more details.
In addition to what @testure has said, this above is not good: bl_idnames
like mesh.blah blah
should be avoided as they may well conflict with Blender core. So, to avoid this you should pick a prefix that will be unique to yourself, for Precision Drawing Tools, I use pdt_whatever.function
so conflicts never arise.
Also your class name is not right, operator classes should be of the form PRF_OT_CreaseAndSharp
where “PFR” is your prefix, “OT” means Operator and the rest should be camel case. If you run Blender from a console (terminal) you will see all the error and advisory messages - this is good practice. Further down the line you should try to avoid using bpy.ops - rather call the base functions instead.
Like @testure I think this is pseudo code as you have no colon after your def ...()
line and you should be passing self
and context
, not selection, get your selection from the context…
Finally, for now, you should always add DocStrings - you need to research what these are, they make it so much easier for you and others to understand your code…
I know we may sound critical here, but it is better to start off on the right foot to save yourself a ton of aggro later on as things get more complex.
Cheers, Clock.
EDIT:
This may be a problem with how you posted the code, but you have no indentations…