Examples of inheritance in Blender

Some years ago I learned some Java and played with inheritance. That was quite a fun because I could create a hierarchy of classes like a template for a building, and then other classes like House, Flat, Tower use that template. So far I barely see examples in addons (or are we using it in fact all the time?) like that way.

Here an example of inheritance in Python:

class Polygon:
    def __init__(self, no_of_sides):
        self.n = no_of_sides
        self.sides = [0 for i in range(no_of_sides)]

    def inputSides(self):
        self.sides = [float(input("Enter side "+str(i+1)+" : ")) for i in range(self.n)]

    def dispSides(self):
        for i in range(self.n):
            print("Side",i+1,"is",self.sides[i])
class Triangle(Polygon):
    def __init__(self):
        Polygon.__init__(self,3)

    def findArea(self):
        a, b, c = self.sides
        # calculate the semi-perimeter
        s = (a + b + c) / 2
        area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
        print('The area of the triangle is %0.2f' %area)

You see that in class Triangle(Polygon) there is a def init(self) function, and that is what I don’t see.

I’ve see one example though of what I think is inheritance like this:

class BToolSetup():

    def execute(self, context):
        Operation(context, self.mode)
        return {"FINISHED"}

    def invoke(self, context, event):
        if len(context.selected_objects) < 2:
            self.report({"ERROR"}, "At least two objects must be selected")
            return {"CANCELLED"}

        return self.execute(context)


class BTool_Union(Operator, BToolSetup):
    bl_idname = "btool.boolean_union"
    bl_label = "Brush Union"
    bl_description = "This operator add a union brush to a canvas"
    bl_options = {"REGISTER", "UNDO"}

    mode = "UNION"

But there I don’t see the init definition.
What I have in mind is to code like I did in Java. So I can start with more abstract idea of objects, and refine it in more specific classes. Do we do that in Blender as well?

After some searching, I found this thread . . . https://blenderartists.org/t/inheritance-of-properties-in-subclasses/593197?u=shawn_irwin
Which seems to address the issue. I worked on a huge project where I was creating the skeletons of various creatures, including humans, and then using code instead to animate them, so that you could just click the character you wanted, it built the bones, you would skin it, then hit the play button, and off it would go. But I used just ONE class for the whole group of creatures, but using inheritance might have been better. I often hear people preaching against using global properties, but I use them, and I have never found them to be a major issue, your style of coding can be make or break depending on how you are doing things. Some people will swear by OOP, others functional programming . . . it really is to each his or her own in my view. I starting coding back in the 1990’s, so I saw coding go from favoring functional to favoring OOP, and classes of course. I’m kind of a rebel though, I hate rules, so breaking them is no big deal to me as long as it gets the job done and does not result in consequences later on down the road. Not everyone agrees with that, but that’s their problem, not mine, ha ha ha.

Thanks! Yes, many roads leads to rome I heard. I’ll check the link, but it’s a bit old (7 years ago), but interesting read. Myabe the thread Inheritance of objects gives an entry point as well.

In the Blender API overview I found

import bpy
class BaseOperator:
    def execute(self, context):
        print("Hello World BaseClass")
        return {'FINISHED'}

class SimpleOperator(bpy.types.Operator, BaseOperator):
    bl_idname = "object.simple_operator"
    bl_label = "Tool Name"

bpy.utils.register_class(SimpleOperator)

Which is a mix in example. And overview says “Regarding inheritance, Blender doesn’t impose restrictions on the kinds of class inheritance used, the registration checks will use attributes and functions defined in parent classes.”

And says: " Notice these classes don’t define an __init__(self) function. While __init__() and __del__() will be called if defined, the class instances lifetime only spans the execution. So a panel for example will have a new instance for every redraw, for this reason there is rarely a cause to store variables in the panel instance. Instead, persistent variables should be stored in Blender’s data so that the state can be restored when Blender is restarted."

I would take “Blender’s data” to mean custom-made properties, i.e. user-created . . . . Another thing I was thinking about doing was instead of creating a character skeleton as one big class, create component classes that could be things like arm, leg, head, torso . . . . then have them link together simply by parenting them together. That could be a way to do it. In your case it might be floor, wall, ceiling, etc.

1 Like

AFAIK you can only inherit or mix method and property, and annotation custom property will not inherit.

and you can not inherit or mix Blender class with abstract class.

2 Likes

update:
Because I (or we) normally use to work with classes that are panels, opererators, etc, I think we don’t come to the idea to just use a simple base class of something and instantiate it. I found out that this code just works in Blender:

class Dog():
    def __init__(self,numberFeet,numberEyes):

        self.foots = numberFeet
        self.eyes = numberEyes

goodDog = Dog(6,4)
print(goodDog.foots)
print(goodDog.eyes)

badDog = Dog(2,1)
print(badDog.foots)
print(badDog.eyes)

So the above class is not a Panel, Operator etc, but we can also use classes to organise our coding. What I find interesting is, that I have one Dog class, and can make all kinds of Dogs from that one template dog class.
Next I will experiment with inheritance and other stuff.

1 Like

Yes, that is standard for a class, and it makes them extremely useful. The class I built for creating characters had a full 662 items in it. That is a lot for a class, ha ha.

Mark Lutz, who is a guru in Python, says you can pass the superclass to the subclass like this:
(From page 829 of “Learning Python, Fifth Edition”)

>>> class Character(bpy.types.Operator):
...     bl_idname = "object.character"
...     bl_label = "characterPanel"
...     bl_description = "character"
...     bl_options = {"REGISTER", "UNDO"}
...     # bpy.data.objects[character.name].show_in_front
...     show_in_front = True 
...     # BEGIN WITH character PARTS
...     name = ""
...     armature = ""
...     armatureName = ""
...     x = 0
...     y = 0
...     z = 0
...     n = 0

Then:

>>> class Dog(Character):
...     bl_idname = "object.dog"
...     bl_label = "Dog"
...     bl_description = "Dog"
...     bl_options = {"REGISTER", "UNDO"}
...     #
...     bark = True
...     sit = False

Then:

char = Character
dog = Dog

Then:

dog.x
0

char.x = 40

dog.x
40
1 Like

That’s what I am looking for yes. Since I am experimenting so far, only with simple classes (not panels and operators, etc) I wonder the following;

I see class Character(bpy.types.Operator) in your examle. So this superclass (a base class in my own words), is on it’s own also a subclass( bpy.types.Operator is a class). What will happen with the subclass Dog, will it inherit things from the class Operator?

So let’s say you make another class, a panel, where you add the Character class ( or Dog class) as operator. Is the idea then that the Dog class are going to show up in the UI of the addon/script or something like that?

Or is this example just to show that the dog inherits attributes from it’s base class? Which is cool that we can do that, and is what I initially was aiming for.

It is kind of a bad example, because I took it from some code I have used to create panels, and the dog class, I just made that one up. I think you can get away without using the bpy.types.operator and the like if you are not creating panels or using it in a plug in, but otherwise you have to have the type listed. Whether this type of inheritance would work with panels, I would say unlikely.

1 Like

Ah, yes. I got it. Yes, that’s great.
I am curious what character you made with your script. Do you have some renders? 662 attributs… that looks like a pretty detailed character template, or?

This script that I wrote was made for animating characters without having to do rigging. It builds the bones and then when you hit the play button, the bones walk, so all you have to do is add the skin and possibly do some adjustments, and it will walk. The script is not 100% complete, as I have a lot of other stuff I am working on, but if you want to see it working, you can go to https://github.com/Skywola/anim and download it. After you download it, you can copy it into the text editor and run it, then go to the Animation view, press n to show the tab on the right side of the viewport, and select the create quadruped or bird button. (The biped and centaur do not work yet) . After it builds the character, you can click the walk or run buttons, also there is a speed setting under the character controls button. This was a project that I wrote originally for MAYA in MEL scripting language. It is pretty close to complete, but I just have a lot of other things that are higher priority at the moment . . . .

1 Like