collectionProperty error on blenderstart custom UI list


(rombout) #1

Im trying to figure out why this CollectionProperty which has a PropertyGroup for a custom UI list, doesnt want to load from from blender startup.

Ive found this code and works fine when a scene i open and used in text area to register it. All works and it shows up.

import bpyimport os


coll_data = (
    ("Option A", "The first option, can be found by searching '1' as well"),
    ("Option B", "You can find this by searching for 'roflmao'"),
    ("Some text", "Some more descriptive explanation"),
    ("Blabla", "Talking stuff...")
)


class COLL_UL_search(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            # You should always start your row layout by a label (icon + text), or a non-embossed text field,
            # this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
            # We use icon_value of label, as our given icon is an integer value, not an enum ID.
            # Note "data" names should never be translated!
            split = layout.split(0.3)
            split.label(item.label)
            split.label(item.description)


        elif self.layout_type in {'GRID'}:
            pass


class MyColl(bpy.types.PropertyGroup):
    #name = bpy.props.StringProperty()
    label = bpy.props.StringProperty()
    description = bpy.props.StringProperty()




class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"




    def draw(self, context):
        layout = self.layout


        col = context.scene.col
        idx = context.scene.col_idx


        if idx >= len(col):
            #context.scene.col_idx = len(col) - 1
            text = "(index error)"
        else:
            text = col[idx].name


        layout.template_list("COLL_UL_search", "", context.scene, "col", context.scene, "col_idx")




def collhack(scene):
    bpy.app.handlers.scene_update_pre.remove(collhack)


    try:
        scene.col.clear()
    except:
        pass


    for i, (label, description) in enumerate(coll_data, 1):
        item = scene.col.add()
        item.label = label
        item.description = description
        item.name = " ".join((str(i), label, description))






def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.col = bpy.props.CollectionProperty(type=MyColl)
    bpy.types.Scene.col_idx = bpy.props.IntProperty(default=0)


    bpy.app.handlers.scene_update_pre.append(collhack)




def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Scene.col
    del bpy.types.Scene.col_idx




if __name__ == "__main__":
    register()

Now i wanted to add my own items. The list i need is from a different render engine i use which can have linked materials. Ive added a function which checks if the links working and if not return a list of missing materials, material name, meshname.

The problem is the registration now. The collectionProperty “Scene.col_item” doesnt want to register. I also see this error in the console.

TypeError: CollectionProperty(...): expected an RNA type derived from PropertyGroup, failed with: RuntimeError: , missing bl_rna attribute from 'RNAMetaPropGroup' instance (may not be registered)


Traceback (most recent call last):
  File "/Applications/Blender/blender.app/Contents/MacOS/../Resources/2.78/scripts/modules/addon_utils.py", line 330, in enable
    mod = __import__(module_name)
  File "/Users/romboutversluijs/Library/Application Support/Blender/2.78/scripts/addons/TheaForBlender/__init__.py", line 58, in <module>
    from . import thea_operators
  File "/Users/romboutversluijs/Library/Application Support/Blender/2.78/scripts/addons/TheaForBlender/thea_operators.py", line 3187, in <module>
    type=MyColl
ValueError: bpy_struct "Scene" registration error: col_item could not register

My adjusted code is like this

def checkRelinkTheaExtMat():    '''check if Thea linked materials are live
        :return: False if missing link
        :rtype: bool
    '''
    missing_Materials = []
    matNameExt = ""
    matMesh = ""
    matExtLink = True
    sceneLoaded = False
    try:
        if bpy.context.scene:
            sceneLoaded = True
        else:
            missing_Materials.append(("Nothing loaded", ""))
    except:
        pass
    if sceneLoaded:
        for mat in bpy.data.materials:
            if getattr(mat, "thea_extMat"):
                extMat = os.path.exists(os.path.abspath(bpy.path.abspath(mat.get('thea_extMat'))))
                if extMat == False:
    #                matMesh = bpy.context.active_object.name
                    matExtLink = False
                    matNameExt = mat.name
                    MNAME = matNameExt
                    obs = []
                    for o in bpy.data.objects:
                        if isinstance(o.data, bpy.types.Mesh) and MNAME in o.data.materials:
    #                        obs.append(o.name)
                            matMesh = o.name
#                    missing_Materials.append("%s > Mesh obj: %s" % (matNameExt, matMesh))
                    missing_Materials.append((matNameExt, matMesh))
    #                return [matExtLink, matNameExt, matMesh]
                else:
                    pass
            missing_Materials = sorted(list(set(missing_Materials)))
    else:
        pass
#    print("*** Missing Material list: %s" % missing_Materials)
    return [matExtLink, matNameExt, matMesh, missing_Materials]












class COLL_UL_search(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            # You should always start your row layout by a matname (icon + text), or a non-embossed text field,
            # this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
            # We use icon_value of matname, as our given icon is an integer value, not an enum ID.
            # Note "data" names should never be translated!
            if not checkRelinkTheaExtMat()()[1]:
                layout.matname("Yeah all material linked")
            else:


                row = layout.split(1)
                row = layout.row(align=True)
                row.label("", icon='MATERIAL')
                row.label(item.matname)
                row = layout.row(align=True)
                row.prop(bpy.data.materials[item.matname], "thea_extMat","")
                row.operator("open.thea_files", text="", icon='FILESEL')
            try:
                if (os.path.exists(os.path.abspath(bpy.path.abspath(bpy.data.materials[item.matname].get('thea_extMat')))))==False:
                    row.label(text="Missing link!", icon='ERROR')
            except:
                pass


        elif self.layout_type in {'GRID'}:
            pass






class RelinkMissingMaterials(bpy.types.Panel):
    """Creates a Panel in the Material Tab"""
    bl_label = "Relink Missing Materials"
    bl_idname = "OBJECT_PT_relink_missing_materials"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "materials"




    def draw(self, context):
        layout = self.layout
        thea_globals.log.debug("List missing; %s" % layout)
        col_item = context.scene.col_item
        idx = context.scene.col_idx


        if idx >= len(col_item):
#            context.scene.col_idx = len(col_item) - 1
            text = "(index error)"
        else:
            text = col_item[idx].name


        layout.template_list("COLL_UL_search", "", context.scene, "col_item", context.scene, "col_idx")




class MyColl(bpy.types.PropertyGroup):
    #name = bpy.props.StringProperty()
    matname = bpy.props.StringProperty()
    matpath = bpy.props.StringProperty()


def collhack(scene):
#    bpy.app.handlers.scene_update_pre.remove(collhack)


    try:
        scene.col_item.clear()
    except:
        pass


    for i, (matname, matpath) in enumerate(checkRelinkTheaExtMat()[3], 1):
        item = scene.col_item.add()
        item.matname = matname
        item.matpath = matpath
        item.name = " ".join((str(i), matname, matpath))




#def sceneLoaded(context):
#    Scene = bpy.types.Scene
#    try:
#        if context.scene:
##            scene = bpy.context.scene
#            sceneLoaded = True
#    except:
#        pass
#    if context:
Scene = bpy.types.Scene
Scene.col_item = bpy.props.CollectionProperty(
    type=MyColl
    )


Scene.col_idx = bpy.props.IntProperty(
    default=0
    )
#        bpy.app.handlers.scene_update_pre.append(collhack)
collhack(bpy.context.scene)
#        print("scene items:%s" % item.matname)

I also tried adding the registration of the bottom 3 to register part in the main addon but it doesnt work as well.

What can i change to get this to work?


(Teck-freak) #2

Hey there. No Idea if it’s still of interest, but here’s the reason:
You didn’t register the PropertyGroup MyColl !

Register it with bpy.utils.register_class(MyColl) or just register the whole script with bpy.utils.register_module(name)

cheers


(rombout) #3

Thanks for the reply, I should have marked this solved. I got it solved by placing some of the properties in the unit file and register them there. It works but isn’t very clean.

I still need to make it look all cleaner.


(Teck-freak) #4

Anytime. :slight_smile: Keep up the good work and good luck with your Addon


(rombout) #5

Thanks i should dive into this more. I did manage to combine to custom UI items into one panel now. Part i borrowed from amaranth addon which check for missing textures. The other one i made my self which check for linked materials, this is an option the render engine has im using.

I didnt started this addon but i did tons of adds so the functionality became better. I was fedd up with black objects rendering and missing textures. So i added an option which check all links prior to start of the render, if it finds any broken links its spits them out in the panels and stops it. I made an option so users can turn it on or off.

09 17

I just need to so some cleaning, but ive been busy with other adds :slight_smile: hahah to much ideas here


(Teck-freak) #6

Heh, I know that feeling :smirk: . Same with me. Currently I aim to teach Blender at my university, but I’m being asked to make it as CAD-esque as possible. :-/ Well, I’m looking forward to your addon. :wink:


(rombout) #7

Okay, you need to teach Blender and do in a CAD manner… how should i interpret that?

I got this thing work now, but i still need to clean the bottom part in the addon. Also i thinking of making it look cleaner in the code. Its sort of scattered all over the place now. Not really proper method.

Ive also added option that it will fix links from strings when the model is openened on a different system but the textures are already fixed. The addon would show the old paths, sort of added compare state and if different change it to the new path


(Teck-freak) #8

Sounds good so far.

Well, the prof whom I work for asked me to start from something the students might know, like autoCAD and to use as much of CAD-like modelling as I can, in order to “make their first steps with Blender easier”. I tried to explain how 3d-modeling is different to CAD, but he’s fixed on the idea.
Now I need to find as many CAD-like addons as I can and try to bundle them up, as to teach the basics of modelling and animation in 3x1.5h somehow.
I mean, I can see, why you’d like something like “find intersection” or “find circle center” or maybe “change circle resolution”. But I’d much rather teach them the basics of modelling first and then tell them they may use some addons to help them. I think it will be faster that way.

In any case, now I must compile a list of CAD and modelling-aid addons, preferibly free or low-cost.
Got some Ideas?
Thx in advance


(rombout) #9

Oofff no not really, i dont know CAD. I know there are CAD importers and there is a special build of blender whih uses a complete different method of modeling. Its a special build which is build around using units and having correct input. I just tried remembering the name but cant come up with. Ill try to look and see if i can find it again.

I just read somewhere about units and CAD doesnt use real world units, thats BS right? I mean CAD is used for many projects like architecture and other building applications. If it doesnt have real world units i wonder how they do measuring and such. I remember CAD beeing a super precise modeling application?

But what that prof is asking is really weird. Why would you want to teach them Blender in a CAD manner, how should one do that. It doesnt make sense to teach a 2d method, i believe CAD is mainly 2d right?


(rombout) #10

PS is perhaps a useful article about the measurment method in Blender.
https://www.katsbits.com/tutorials/blender/metric-imperial-units.php

PS i believe with the coming of 2.8 they have fixed this now. I thought i read this somewhere a while back. PS not sure when you need to start with this. Because Blender 2.8 is quite different on how it works in quite some parts.


(rombout) #11

Ow i think you hit the jackpot, i just said something about the special build there is for blender. After grinding my memory i remembered its name “Mechanical Blender”. Guess what its main slogan or quote is…

mechanical Blender

Blender for CAD Environments

Here’s the link perhaps it helps, remember this use is quite different. It also causes big errors if you use files from this version in the official version. Atleast that was perhaps 2 years back orso when i used it couple times.

I think this must help you a lot with that “weird” prof method :wink:

http://www.mechanicalblender.org/


(Teck-freak) #12

Hey rombout.
Sorry for the late answer.

First off: Thanks :slight_smile:

Now answering, in your order:
Yes, the importers/exporters would be interesting, as well as modelling addons or whatever you can dig up.

No, that’s correct. AutoCAD uses a (more or less random) base size and a global scale-factor, but it never explicitly states a unit for its sizes (at least for dxf files). It simply assumes you all are talking in the same units. In precision work, that’s usually mm, and in architecture usually it’s meter.

Yes CAD comes from 2D and even though it learned 3D in the last 10 years, it’s still heavily influenced by 2D-based methods. It is easier to do 3D-Modeling for buildings, than to do 3D-CAD, and the precision is about the same.

I knew about the measurements in blender, but that article is a nice source.
I’ll use that in my next lesson. :slight_smile:

I started on Monday, but I’ll probably do it all over this monday (5. nov.).
I would like to let my students use Blender-2.78c as installation in the box.
(I don’t like the fancied-up interface of 2.8, and it removes some functionality I needed)

I already knew mechanical Blender but I have to agree, it’s almost perfect.
It just seems that there’s no functional build, let alone a current one. (The 2017-build cried about a missing lib-png.so )
I’ll see if there’s an easy way to compile it as installation in a box for windows and for linux.

Thanks again mate, it really helps.


(rombout) #13

Off i cant help you with that build. So that means its not being developped no more perhaps.

It was quite booming i thought a while back.

But what function are you talking about which they took out?

PS but if CAD doesnt use a measurement, how do people from say USA and EUROPE swap files? If one uses Metric and the other IMPERIAL??


(Teck-freak) #14

Some shortcuts are gone, modifying subwindows is harder to do, simple drawing settings like wireframe, or shaded are gone, …
Don’t get me wrong, there’s cool stuff coming, like eevee and the ability to re-input an already run shader as color. But currently the UI is messed up, and I hope it will be converted back just a bit, as the old interface was easier to teach to students.

PS: By being carefull and telling each other. Also, usually in CAD folks would use the metric system. As far as I know, it works with decimal subdivisions and with radians, but the base-unit is just a dangling scale-factor. The idea behind it seems to be that you can optimize the range of your sizes, so you can keep a rather high precision in rather short ‘number’-structs. To get to a true value, the global scale, which is far longer (bit-length) will be multiplied on top.
When opening a file, it assumes everyone used the same scale/base-unit. If not YOU have to adjust the base scale.