VScode and JacquesLucke's blender_vscode

For those that use these, do you have to restart Blender every time you change your code?
I faintly remember long time ago, i didn't have to do this.
It gets old restarting blender every time. :\

«1

Comments

  • No, I use the Blender > add-on:Reload On Save, the add-on reloads each time after pressing alt+s in VS Code

    dimitar
  • hmm....i have that setting, set, already. :\

  • Did you start Blender from VS Code with the add-on?


  • You already probaly tried to fix that bug your console is giving and pressed alt s again? Sometimes I have to press alt s twice before I get a succesful update add-on message in VS Code

  • Haven't used JacquesLucke's blender_vscode but just to put it out there - if it's using Blender Reload Scripts to update the addon in Blender without then there are problems with that , if it's unregistering and registering addon it could also lead to some unexpected consequences. For me personally fastest way to see the changes in code (given how fast Blender is restaring) is to close Blender and restart it with ⊞ Win + R and blender --open-last.

    Coentheoryshaw
  • edited August 2023

    If you want it to reload you have to have the root folder of your vs code workspace at src/blenderbim/blenderbim, so it can find out the __init__.py file with the relevant blender addon dictionary. But in my experience it's not feasible to use this feature with the BlenderBIM addon, the ifc link systematically gets corrupted in the process and I have to reload Blender. Plus since the panel refactoring a few weeks ago the missing SCENE_PT_scene panel throws an error on reload since it is un-registered by BBIM. That being said I think instead of if getattr(bpy.types, "SCENE_PT_scene") it should be if hasattr(bpy.types, "SCENE_PT_scene") to avoid throwing a AttributeError when the panel has been unregistered there.

    Coen
  • edited August 2023

    Was able to patch a few things together.
    Via this post, if you change os.remove(link_path) to os.rmdir(link_path),in the following file, it fixes the PermissionError: [WinError 5] problem.

    %USERPROFILE%\.vscode-oss\extensions\jacqueslucke.blender-development-0.0.18\pythonFiles\include\blender_vscode\load_addons.py
    ...
    Thanks to @Andrej730's suggestion, I figured if you add the following to %USERPROFILE%\.vscode-oss\extensions\jacqueslucke.blender-development-0.0.18\out\blender_executable.js, it will open the last file.

    ...
    I'm still not able to reload the plugin, via blender_vscode's typical approach, as I get this error, which I think @Gorgious was hinting at. Not sure how to fix, if possible.

    Traceback (most recent call last):
      File "c:\Users\Owner\.vscode-oss\extensions\jacqueslucke.blender-development-0.0.18\pythonFiles\include\blender_vscode\operators\addon_update.py", line 27, in execute
        bpy.ops.preferences.addon_enable(module=self.module_name)
      File "c:\Program Files\Blender Foundation\Blender 3.6\3.6\scripts\modules\bpy\ops.py", line 113, in __call__
        ret = _op_call(self.idname_py(), None, kw)
    RuntimeError: Error: Traceback (most recent call last):
      File "c:\Program Files\Blender Foundation\Blender 3.6\3.6\scripts\modules\addon_utils.py", line 333, in enable
        mod = __import__(module_name)
      File "C:\Users\Owner\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\blenderbim\__init__.py", line 41, in <module>
        import blenderbim.bim
      File "C:\Users\Owner\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\blenderbim\bim\__init__.py", line 25, in <module>
        from . import handler, ui, prop, operator, helper
      File "C:\Users\Owner\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\blenderbim\bim\handler.py", line 280, in <module>
        if getattr(bpy.types, "SCENE_PT_scene"):
    AttributeError: 'module' object has no attribute 'SCENE_PT_scene'
    
    dimitar
  • Recently I wrote some snippet that can be used to reload Blender operator without restarting Blender - typically I have it in Text Editor and run it every time I make some change in the operator code and want to test it. Perhaps it can be useful for someone too.

    import importlib
    
    reregister_classes = {
        "blenderbim.bim.module.model.array": ("RemoveArray", ),
    }
    
    for module_name, classes in reregister_classes.items():
        module = importlib.import_module(module_name)
        for class_name in classes:
            class_obj = getattr(module, class_name)
            bpy.utils.unregister_class(class_obj)
    
        importlib.reload(module)
    
        for class_name in classes:
            class_obj = getattr(module, class_name)
            bpy.utils.register_class(class_obj)
    
    theoryshawbruno_perdigaoGorgiousAcebdamaybernd
  • I've just used it and it's very helpful! Thanks @Andrej730

    theoryshaw
  • edited October 2023

    @Andrej730 Love this script as well!
    You know the next step is to automatically add to reregister_classes, those Classes you're working on, and running this in the VScode background, when the file is saved. ;)

  • You know the next step is to automatically add to reregister_classes, those Classes you're working on, and running this in the VScode background, when the file is saved. ;)

    That would be dangerous for me! ? When I save file in VS Code it doesn't mean I'm sure there won't be any errors and I'd want to register it right away. Reregistering should be some separate deliberate process, imo.
    Tracking exact modules to reload automatically I guess would be possible with some custom VS Code extension. But not sure if it's necessary since typically you're working simultaneously only on couple modules you need to test.

    To simplify the existing script a bit more you can search module elements with something like import inspect; inspect.getmembers(module) and reload all the classes of the certain Blender types like operators, panels, etc. That way you won't need to provide the exact classes, just modules.

    theoryshaw
  • Found a very simple way to attach VS Code python debugger to Blender - https://github.com/hextantstudios/hextant_python_debugger

    theoryshawbdamay
  • @Andrej730 said:
    Found a very simple way to attach VS Code python debugger to Blender - https://github.com/hextantstudios/hextant_python_debugger

    The debugger is working just fine ! Thank you !

    @Andrej730 said:
    Recently I wrote some snippet that can be used to reload Blender operator without restarting Blender - typically I have it in Text Editor and run it every time I make some change in the operator code and want to test it. Perhaps it can be useful for someone too.

    I tried your snippet, i run it inside blender text. But i don't see it working. For example i replace "demo panel" by "demonstration panel" inside the demo plugin, i run the script but it doesn't seem to change anything. I have to reload the all blender to see my changes. Do i do something wrong here ? I don't see my changes even if i deactivate/reactivate bbim from plugin panel. Might be something in cache somewhere ?

  • @bdamay are you sure you edited the snippet and added the classes and modules you need to reload?

  • edited February 15

    @Andrej730 said:
    @bdamay are you sure you edited the snippet and added the classes and modules you need to reload?

    No, you're right. i squizzed this part. :-)

    For the record i did this - for demo panel:

    reregister_classes = {
        "blenderbim.bim.module.demo.ui": ("BIM_PT_demo", )
    }
    

    And it works as expected, thank you.

    I also look forward to achieve this:,

    @theoryshaw said:
    You know the next step is to automatically add to reregister_classes, those Classes you're working on, and running this in the VScode background, when the file is saved. ;)

    do you think it is something that could be done with automatic detection of files and classes that have recent changes or changes compared to the last commit, may be ?

  • do you think it is something that could be done with automatic detection of files and classes that have recent changes or changes compared to the last commit, may be ?

    sure, it may get tricky but I think it's possible

  • @Andrej730 said:
    sure, it may get tricky but I think it's possible

    I'm gonna give it a try in a separate add-on, may be.
    That might be a good exercise for me, getting familiar with blender dev ecosystem.
    I'll let you know

  • edited February 16

    @Andrej730 said:

    To simplify the existing script a bit more you can search module elements with something like import inspect; inspect.getmembers(module) and reload all the classes of the certain Blender types like operators, panels, etc. That way you won't need to provide the exact classes, just modules.

    I finally did something in that spirit to reregister module Classes without having to type the exact name of it.
    Something like this

    import bpy
    import importlib
    import inspect
    
    reregister_modules = ["blenderbim.bim.module.demo.ui"]
    
    for module_name in reregister_modules:
        module = importlib.import_module(module_name)
        # retrieving registered classes with inspect
        classes = [c for c, o in inspect.getmembers(module, inspect.isclass) 
                   if hasattr(bpy.types, c)]
    
        for class_name in classes:
            class_obj = getattr(module, class_name)
            bpy.utils.unregister_class(class_obj)
    
        importlib.reload(module)
    
        for class_name in classes:
            class_obj = getattr(module, class_name)
            bpy.utils.register_class(class_obj)
    

    I also tried a bit further with a recursive reload attempt that can reload module an submodules at once for exemple demo module
    you can find it here https://github.com/bdamay/bbim-reload-addon/blob/main/bbim-reload-addon/bbim_reload_recursive.py

    I was willing to use this to reload from the entire blenderbim.module but i actually i run into errors i don't quite understand well.
    The repository contains a blender add-on script of this attempt, but it's not quite satisfying as it is.

    theoryshaw
  • edited February 23

    Hi everyone, i went a bit further on the reloading feature matter.
    It's for me a good starting point to exercise myself on blender add-on developpement... I took a swim into it this morning, followed one or two tutorials and read demo module comments carefully (these are very good).
    Well, then, i developped my brand first blender add-on that actually do something, as it reloads the submodule you are working on from a custom panel instead of the text editor.
    OK, that's not much... but it's my first one and i would be grateful to anyone experienced or not that might take a look and leave me some comment and remarks about it, even the bad ones that might help me improve.
    It's here https://github.com/bdamay/bbim-reload-addon


    theoryshawCoenbruno_perdigaoMassimoAndrej730
  • @bdamay said:
    OK, that's not much... but it's my first one and i would be grateful to anyone experienced or not that might take a look and leave me some comment and remarks about it, even the bad ones that might help me improve.
    It's here https://github.com/bdamay/bbim-reload-addon

    Thank you for your work, glad that snippet can grow into something even more useful 👍

    Tested the addon, not sure if I'm missing something but I've tried to change operator class CreateProject(bpy.types.Operator) and provided "modules" in the panel project.operator and it didn't reregister CreateProject - noticed from trying to running and from the console output below.

    Also, how can I provide tool modules to reload (e.g. blenderbim.tool.Model) as operators often depend on them or maybe reload other non-bbim modules (e.g. ifcopenshell.api and ifcopenshell.api.geometry.edit_object_placement)?

    Reregistering BBIM utility
    project.operator
    Module  blenderbim.bim.module.project.operator
    Reregistering Class BIM_OT_load_clipping_planes
    Reregistering Class BIM_OT_save_clipping_planes
    done
    
    bdamay
  • Hi @Andrej730 , Thank you very much for your interest in that little addon.
    I have to confess i had some issues using it and didn't dig much into these. I don't think i fully understand how register unregister process really work in Blender.
    But i will take a closer look in the next days and try it on your usecase, i'll let you know if i manage to make it work as it should.
    In the mean time, i recommend not using the addon as it is not safe, sorry

  • edited April 28

    OK i think i might have a beginning of an answer to your first question
    Actually the script does this to limit reregistering to classes that are in bpy.types classes. It appears that LoadProject isn't , only BIM_OT... operators are.
    FYI i use this test to check what's to be unregistered
    classes = [c for c, o in inspect.getmembers(module, inspect.isclass) if hasattr(bpy.types, c)]
    Here i'm assuming Classes that are registered are those present in bpy.types. I'm not quite sure of that part, and how we can get a list or registered classes in Blender otherwise. You may have a hint to point to me about this ? It appears CreateProject doesn't show up with this filter.

    I also noted that even with this filter, for some reason, in some submodules, the script fails to reregister what have been unregistered. That is indeed much unwanted.

    I guess you were right saying it might be safer to choose carefully and individually classes that are needed to be registered than to try to automate this kind or recursion. I might go for something like this if there is no way to do better.

  • @bdamay said:
    Here i'm assuming Classes that are registered are those present in bpy.types. I'm not quite sure of that part, and how we can get a list or registered classes in Blender otherwise. You may have a hint to point to me about this ? It appears CreateProject doesn't show up with this filter.

    Because Blender may register classes by other names based on it's internal format. E.g. "CreateProject" is registered as "bpy.types.BIM_OT_create_project" though it still is the same class:

    Each class also have is_registered attribute and this will be a more straightforward way to check if it needs to be unregistered.

    bdamaytheoryshaw
  • edited May 2

    Hi @Andrej730 ,
    Thank you very much for your help. I suspected something like this but didn't have time to dig further, (and i'm not yet very much familiar with blender api). What you say is insightful.
    I already made a try with the is_registered attribute but still have errors i have to investigate. (I guess it's because i'm unregistering the class, not blender name ?)
    If i may summarize the way i understand it:

    • I inspect all submodules and find submodules and finally classes with their 'python' Class names.
    • i can check if the class is Blender registered by evaluating "is_registered" attribute
    • if it is registered i should the then call unregister followed by register on that Class

    What i may not be sure is that if i call bpy.utils.unregister_class(class_obj) with a reference to the "python" class, will the api unregister the class properly ? or ** is there a way for me to get to the "Blender" name coming from "python" Class name** ?
    (bl_name may be?
    I can't test this right away, as i'm not home, and don't have blender, but hopefully i'll do it tonight )

    theoryshaw
  • @bdamay said:
    What i may not be sure is that if i call bpy.utils.unregister_class(class_obj) with a reference to the "python" class, will the api unregister the class properly ? or ** is there a way for me to get to the "Blender" name coming from "python" Class name** ?
    (bl_name may be?
    I can't test this right away, as i'm not home, and don't have blender, but hopefully i'll do it tonight )

    Either way if you do unregister(blenderbim.CreateProject) or unregister(bpy.types.BlenderPostProcesedName) it will do exactly the same as blenderbim.CreateProject is the same class object as bpy.types.BlenderPostProcesedName, just stored in different modules - one in blenderbim and other in bpy.types.

    bdamay
  • Hi @Andrej730 , i took a look on the reload script feature. I still have issues on certain classes, that i appear to unregister right but can't register again. with a '**missing bl_rna attribute... **' message. (see below)
    That, i don't know what to do with, as it makes the all script really unsafe (as in the end Classes are not available anymore at all).
    I surely misunderstand something, but may be you have a clue on what's happening here ?

    unregistering Class <class 'blenderbim.bim.module.demo.prop.BIMDemoProperties'>
    Reregistering Class <class 'blenderbim.bim.module.demo.prop.BIMDemoProperties'>
    Error: Python: Traceback (most recent call last):
      File "\bbim_reload_recursive.py", line 42, in <module>
      File "\bbim_reload_recursive.py", line 34, in reregister_modules_recursive
      File "\bbim_reload_recursive.py", line 19, in reregister_modules_recursive
    RuntimeError: register_class(...):, missing bl_rna attribute from 'RNAMetaPropGroup' instance (may not be registered)
    

    The code i run is this one:

    import bpy
    import importlib
    import inspect
    
    reregister_modules = ["blenderbim.bim.module.demo"]
    
    def reregister_modules_recursive(module_name):
        print('Module ', module_name)
        module = importlib.import_module(module_name)
        # retrieving registered classes with inspect
        classes = [c[1] for c in inspect.getmembers(module, inspect.isclass)] 
        # reregistering classes        
        for c in classes:            
            if hasattr(c, 'is_registered') and c.is_registered:
                print('unregistering Class', c , 'is_registered', c.is_registered)
                bpy.utils.unregister_class(c)
                print('Reregistering Class', c)
                bpy.utils.register_class(c)
    
        try:
            print('reloading ', module)
            importlib.reload(module)
        except Exception as e:
            print('error reimporting ', module, e)
    
        sub_modules=[]
        for n, sm in inspect.getmembers(module, inspect.ismodule): 
            # We should avoid reparsing upper modules here like bpy. so i check if sub module contains module name 
            if module_name in sm.__name__:                           
                sub_modules.append(sm.__name__) 
    
        for module_name in sub_modules:          
            reregister_modules_recursive(module_name)
    
    for module_name in reregister_modules:                   
        print('-'*60)
        print('Reregistering utility')
    
        reregister_modules_recursive(module_name)
        print('done')
        print('-'*60)
    
    
  • @bdamay said:
    Hi @Andrej730 , i took a look on the reload script feature. I still have issues on certain classes, that i appear to unregister right but can't register again. with a '**missing bl_rna attribute... **' message. (see below)

    Can you please narrow it down to some simple way to reproduce the issue? Something like this:

    import blenderbim.bim.module.demo.prop
    cl = blenderbim.bim.module.demo.prop.BIMDemoProperties
    bpy.utils.unregister_class(cl)
    bpy.utils.register_class(cl)
    
  • @Andrej730 said:

    import blenderbim.bim.module.demo.prop
    cl = blenderbim.bim.module.demo.prop.BIMDemoProperties
    bpy.utils.unregister_class(cl)
    bpy.utils.register_class(cl)
    

    I ran this in console and i don't get no error on BIMDemoProperties class, but i have on PropertyGroup one

    cl = blenderbim.bim.module.demo.prop.PropertyGroup
    bpy.utils.unregister_class(cl)
    bpy.utils.register_class(cl)
    

    gives

    Traceback (most recent call last):
      File "<blender_console>", line 1, in <module>
    RuntimeError: register_class(...):, missing bl_rna attribute from 'RNAMetaPropGroup' instance (may not be registered)
    
  • OK i think i get it . I shouldn't try to reregister PropertyGroup - i will investigate why i get this class from inspecting submodule

Sign In or Register to comment.