4
$\begingroup$

I try to import from the file "boolean_2d_union" the function but fail to be able to get this right.

I have the following structure

add-on folder:
   __init__.py
   addons (folder)
       boolean_2d_union.py

Here is the script of my ini file.

   bl_info = {
    "name": "Fullscreen Modeling Pie Menus",
    "author": "Claas Kuhnen",
    "version": (1, 0),
    "blender": (2, 75, 0),
    "location": "View3D > Pie Menus",
    "description": "Pie Menus for Modeling and Object Properties",
    "warning": "Beta - Concepy Study",
    "category": "User Interface",
}   
import math
import bmesh
import bpy, os
from bpy.types import Menu, Header, Panel, UIList   
from bpy.props import IntProperty, FloatProperty, BoolProperty,EnumProperty,StringProperty
from mathutils import *

from boolean_2d_union import Boolean2DUnion

class PieTest(Menu):
    bl_idname = "pie.test"
    bl_label = "Pie Test"

    def draw(self, context):
        layout = self.layout
        pie = layout.menu_pie()
        #4 
        pie.operator("bpt.boolean_2d_union", text="Import Test")

addon_keymaps = []


def register():
    bpy.utils.register_module(__name__)

    wm = bpy.context.window_manager

    if wm.keyconfigs.addon:

        #Viewport Shade
        km = wm.keyconfigs.addon.keymaps.new(name = 'Object Non-modal')
        kmi = km.keymap_items.new('wm.call_menu_pie', "RIGHTMOUSE", "PRESS", shift=True, ctrl=True)
        kmi.properties.name = "pie.test"


def unregister():
    bpy.utils.unregister_module(__name__)

    wm = bpy.context.window_manager

    if wm.keyconfigs.addon:
        for km in addon_keymaps:
            for kmi in km.keymap_items:
                km.keymap_items.remove(kmi)

            wm.keyconfigs.addon.keymaps.remove(km)

    # clear the list
    del addon_keymaps[:]

if __name__ == "__main__":
    register()

I always get a syntax error:

enter image description here

I added a link to the add-on zip file URL

Inside the file boolean_2d_union.py this is the following code:

class Boolean2DUnion(bpy.types.Operator):
    bl_idname = "bpt.boolean_2d_union"
    bl_label = "Boolean 2D Union"
    bl_options = {'REGISTER', 'UNDO'}
$\endgroup$
1
  • $\begingroup$ this snippet also has a problem with the addon_keymaps, but it's a different matter with a working example already $\endgroup$
    – zeffii
    Commented Jan 18, 2016 at 22:40

1 Answer 1

5
$\begingroup$

To learn more about importing from subdirs, you should be reading Stackoverflow and googling stuff like 'how to import from sub directories in Python` : python-import-a-file-from-a-subdirectory , this is a general Python question and has many good answers and links.

I'll answer the Blender specifics (reduced version) of this code. no pie, no keymaps. We can test if a class/Operator was correctly imported and registered by using the spacebar menu and search for the operator's bl_label ( here Boolean 2D Union ) , and launch it from there.

enter image description here

That operator has a poll to test if at least two faces are selected before showing up in the menu or spacebar search. Here you can see we successfully imported that class and registered it.

Importing from sub directories

I've prepared a small zip at this repostory : https://github.com/zeffii/some_test_addon , which you can Install from File.

if your add-on's folder structure is like this.

addon_name     <-- avoid spaces in the add-on folder names
|
+ __init__.py
+ included_addons   <-- avoid folders named just 'addons'
  |
  + __init__.py   <---  (often empty) tells Python that this folder is a module.
  + boolean_2d_union.py

it should work this way, from the top level __init__.py

bl_info = {
    "name": "Some Test Addon",
    "author": "----",
    "version": (0, 1),
    "blender": (2, 76, 0),
    "category": "User Interface",
}

import bpy

from .included_addons import boolean_2d_union


def register():
    # this line will throw an exception if you press F8 and don't
    # have any classes defined in this __init__.py file, but usually
    # this file has at least some classes either for a property collection 
    # or addon preferences.. or a menu drawing function.
    bpy.utils.register_module(__name__)

def unregister():
    bpy.utils.unregister_module(__name__)

Registration

When boolean_2d_union.py is imported, Boolean2DUnion is registered for you by bpy.utils.register_module(__name__).

There are many subtleties attached to multi-file addons regarding reload code and I think this is outside of the scope of your question, but further reading is suggested.

some insight

Does this work if I hit F8 (accidentally or intentionally). You might temporarily add some print events into __init__.py to get a sense of what's happening during that reload event, and get an idea of what has been loaded when.

bl_info = {
    "name": "Some Test Addon",
    "author": "----",
    "version": (0, 1),
    "blender": (2, 76, 0),
    "category": "User Interface",
}

import bpy

if 'boolean_2d_union' in locals():
    print('1 -- RELOAD EVENT (f8)')
    print("don't need to reload an unchanged file")
else:
    from .included_addons import boolean_2d_union
    print('2')

def register():
    print('3')
    bpy.utils.register_module(__name__)
    if 'bpt' in dir(bpy.ops):
        print(dir(bpy.ops.bpt))  # will show   ['boolean_2d_union']
        print('4')
    print('5')

def unregister():
    print('6')
    bpy.utils.unregister_module(__name__)

Read the source of any of the multifile add-ons to see how they deal (or don't deal) with the F8 reload event. As a developer it's handy to have reload handling code so you don't have to keep closing/reopening Blender. Sometimes it is inevitable to have to close/reload, but get F8 working first and then if the reload didn't pick up your changes

  • either fix the reload to take new files into account
  • or restart
$\endgroup$
4
  • $\begingroup$ Sometimes I think I do not know how to write the question right when searching in Google. Thank you for the explanation! $\endgroup$ Commented Jan 20, 2016 at 15:35
  • 1
    $\begingroup$ As you start with Blender's Python API without prior Python experience I can imagine it's difficult to get a sense of how general some scripting questions are. Often the hardest part of finding solutions to obstacles is the lack of the correct terminology -- for this reason alone many people tend to focus more on learning Python after a while, then bpy API becomes less of an enigma, and you learn new ways to approach solutions. $\endgroup$
    – zeffii
    Commented Jan 20, 2016 at 17:31
  • $\begingroup$ I think you are quite right. If you would have a moment, I have to question I would like to run by you. I do not know how to do this via a chat. The chat button seems only to appear if there is plenty of comments. $\endgroup$ Commented Jan 20, 2016 at 17:34
  • $\begingroup$ you can go into the existing chat chat.stackexchange.com/rooms/34313/… ask away, i'll be back soon $\endgroup$
    – zeffii
    Commented Jan 20, 2016 at 17:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .