[API] Morpheas - a secondary GUI API for Blender based on BGL and OpenGL

Morpheas

Morpheas is a Blender GUI API that helps with the construction of custom GUI. It depends on BGL (Blender python module that gives access to Blender’s window OpneGL context) and PyPNG
Features

  • Simple structure , easy to learn. Only 2 methods needed for the functioning of the GUI
  • Fully documented code. Code comments for the entire code.
  • Single module. Entire source code contained only in one python source code file
  • trasnparent or non trasparent custom skins (textures) for any GUI element
  • Text with customisable size and font
  • Buttons with the ability to change skin when mouse enters or exits them
  • Auto hide feature that hides the GUI when the mouse exits the area assigned with drawing the GUI
  • Relative and absolute coordinate system. Relative system coordinate system starts from the bottom left corner of the area assigned for drawing the GUI. Absolute coordinate system start from the bottom left area of entire Blender window. This way you can very precisely locate GUI elements
  • Independent event system supporting, left click, left click release, right click, right click release, mouse move , mouse over and mouse outside the graphical element
  • Multi layer system that allows Morphs ( the basic Morpheas GUI element) to include other morphes as children
  • World morph provides automatic handling of Blender events and drawing of Morpheas
  • Non Blocking. Blender events not used are passed back to Blender so that Morpheas NEVER interfere with normal user blender interaction
  • Multiple textures. Each morph can have multiple textures assigned to it, one is only active at a time
  • OpenGL loading of textures. Textures are NOT loaded using the traditional method of the image editor. This means that the user of your addon will never see his image editor getting cluttered with images he does not use. Instead Texures are loaded using OpenGL and PyPNG in the background completely invisible to the user of your addon
  • Custom actions , actions assigned to events are defined as independent classes giving great deal of flexibility to the coder on defining custom functionality
  • Fully Object Orientated , the library makes no use of globals, precedures or anything else than python classes
  • Examples. Morpheas comes with multiple examples also fully documented and it even includes assets used by those examples in the form of a single blender file. Just install Morpheas as a regular Blender addon to demo its features through its examples found in Tools Panel , “Morpheas” tab

Installation

Installing is very simple just add morpheas.py to your project and you are ready to use it, all code is included in a single file
You will also need png.py which you can get from code folder of the github repo of PyPNG project
Documentation

Documentation of the project is included in the source code in form of code comments. Morpheas is fully documented and it also comes included with several examples also fully documented

Download

Morpheas can be downloaded here
https://github.com/kilon/morpheas/archive/master.zip

Project is hosted in Github here

Attachments


1 Like

Good to see some more put into having a standardized way to draw a GUI in the viewport. Stephen Leger and Okavango already did some work in this sens, maybe you could agree on a unique framework with good docs?

Also like Mano-Wii, a simple addon that uses your library would help a lot :slight_smile:

No idea who Stephen Leger and Okavango did and where, can you provide a link or at least the name of the project.

Ineed Morpheas need some examples and some documentation here is a small example





import bpy
import bgl
import blf
from morpheas import *


# this class is defining the action performed when the button is clicked
clase AButtonAction:
   def onLeftClick(morph):
      print("the button has been clicked")
      morph.texture = "buttonClickedIcon"


def draw_callback_px(self, context):
   #draw the morphs
   self.world.draw()




class ModalDrawOperator(bpy.types.Operator):
    """Draw a line with the mouse"""
    bl_idname = "view3d.modal_operator"
    bl_label = "Simple Modal View3D Operator"
    
    def __init__(self):
         self.world = None
         # create button 
         self.abutton = ButtonMorph(texture="buttonIcon",onLeftClickAction = aButtonAction)
         self.world.addMorph(self.abutton)


    def modal(self, context, event):
         context.area.tag_redraw()
         self.world.onEvent(event)
         if self.world.consumedEvent:
            return {'RUNNING_MODAL'}
         else:
            return {'PASS THROUGH'}


    def invoke(self, context, event):
        # create the world
        self.world = World()
      
        if context.area.type == 'VIEW_3D':
            # the arguments we pass the the callback
            args = (self, context)
            # Add the region OpenGL drawing callback
            # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
            self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')


            self.mouse_path = []


            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}




def register():
    bpy.utils.register_class(ModalDrawOperator)




def unregister():
    bpy.utils.unregister_class(ModalDrawOperator)


if __name__ == "__main__":
    register()



As you can it requires minimal code as the 90% of the code is just the creation and handling of modal operator

Still its early stages and many things can and will change

For some weird reason when i try to edit the previous post it shows me blank

a mistake in the code is that the name is AButtonAction and not with small later A
so it should be

self.abutton = ButtonMorph(texture=“buttonIcon”,onLeftClickAction=AButtonAction)

so in addition to this the rest of the code is just

self.world= World()
self.world.draw()
self.world.onEvent(event)

The rest of the code is only for the modal operator and is copy paste from the Modal Draw template of Blender Text Editor

I also made a small gist for those that prefer to read code with syntax highlighting

is this right ?
it doesnt work, i would love to test it , but it doesnt work . check out this
i have added morpheas.py and png.py file along with your given code in init file but it doesnt work
https://we.tl/UzH5s7Bn7v

yeah sorry about this, I was in a hurry and I thought the code would work out of the box but now I see it has several problem including that is deeply tied to Cyclops at a couple of areas that I did not notice. I will be updating Morpheas , it will now come fully commented and we will have an example subfolder with an example that works and is also fully commented.

I am already working on this but it may take some time because I need to rethink a bit Morpheas architecture to avoid in the future any similar kind problem

Hi,
NP Station and Archipack both are in the latest buildbot and use about the same code to display an OpenGL UI in the viewport. Maybe you can send them a PM https://blenderartists.org/forum/member.php?271461-stephen_leger https://blenderartists.org/forum/member.php?153914-Okavango . It would really make the UI more unified, reduce risk of collisions, reduce code size and improve stability to have one framework for all.

There is tiny problem for me with this scenario, I want complete ownership (copyright) and control over Morpheas. This is because Morpheas is an extremely important part of Cyclops and it evolves to serve specific needs and the fact that Cyclops will be a GPL open source but commercial addon.

On the other the hand Morpheas’s code is licensed as GPL which means that it does not stop anyone, including you, using the code under the name of diffirent project and in sync with my repo or out of sync. So you could take this code and get in contact with those developers to agree on a common design of a GUI API having Morpheas as an initial design.

There is no risk of collision by the way, this is because of the design of Blender which is quite good in those case. A draw fuction method/assigned to a modal is seperate from the draw method of another modal operator. You could mess up OpenGL context but then that is something you could do anyway.

The only collision that I think is the overlap of multiple GUIs which is usability and not a code related problem. I will provide a solution to this problem via Cyclops by defining an interface of interaction but that is a very long term goal if not temporary.

And I am back

Heavy refactoring of the code and resolution of many bugs

The code now works independ of Cyclops. It also now follow proper python naming. It comes with a working example and the code is now fully documented. More info about new features and how to use and install is given to the first post . Enjoy ! :slight_smile:

I guess this is something to be used by developers, right? I installed the addon and it doesn’t seem to “do” anything :slight_smile:

Indeed this is for blender users that code in python and for addon developers, Morpheas as an addon “does” something, it demostrates the GUI abilities it has. It should have created a Morpheas tab in your Tool panel and have a single button there named “Example 1” , clicking that will not display anything but if you hover your mouse inside the viewport will see the GUI appear in the form of a single button.

Click on it , if you dare :wink:

I will be adding many more examples in the future

Of course the examples are not there only to show how it works in practice but also to act as a basis for any user not afraid to code in python to design his own custom look GUIs. Morpheas targets not only experienced developers but also people who never coded before or people who are very new into coding.

Aha, button found and pressed. :slight_smile:

Well done :slight_smile:

I’m trying to make an add-on (hopefully good enough to sell it on the BlenderMarket and pay my rent and taxes) that uses bgl quite a lot and Morpheas is a really big help. Not perfect(yet), I’ve added a few things (if no texture is given it draws a rectangle instead, it can have rounded corners etc), I’ll share them with you once they’re a bit more polished and you can add them if you want. But I think this is a very good start for something that allows developers to use bgl more freely. If something changes in the API, we just have to change Morpheas, not dozens of addons.
Ε, και αφού κάθισες εσύ και ασχολήθηκες με τον κώδικά μου στο παρελθόν, είναι δίκαιο να ανταποδώσω…:yes:

Hi, what are the plans on updating this to 2.8? I am just developing myself a small UI lib, but why to do that twice, right?

Edit:
just did a bit of digging into this… and such an overkill to use PIL here I think… Blender has perfectly fine and simple drawing of texture images, I am just looking for a layer to simplify some work for me…
I didn’t manage to run this on mac, because of only win binaries in parts in the PIL lib…

Short version: Is complicated situation. A new version will come in the distant future which will be far more powerful and far faster than the currently implementation.But It wont be independent library and pure python. For now Morphease is part of commercial GPL build of Blender I am developing. So the best option is for you to port the existing code to use the new imbuf module. imbuf module (I think its available for 2.79) is a 2.8 python module part of the Blender standard distribution that gives “low level” access to loading images inside Blender.

Long version:

Morpheas was developed for a commercial addon (Cyclops) I was planning that would offer a right click menu. Unfortunately I decided to abandon the project for 2 reasons

  1. Blender 2.8 came out and I was informed that there was the possibility that BGL would be removed. Mainly because the future of OpenGL is a bit sketchy right now for Blender because Apple stopped supporting OpenGL for its OS and because OpenGL in general is mostly replaced by Vulkan nowdays.
  2. Debugging OpenGL issues from Python provided to be a nightmare mainly because almost all debug tools are made for C/C++ which are by far the most popular languages for OpenGL

So Cyclops was put on ice together with Morpheas. However in its place a new project was born “Ephestos” which is far more than just a commercial addon but a commercial build of Blender 2.8 with same goal as Cyclops but far larger ambitions mainly because accessing Blender source code opens the door to a universe of options. I would have released it already but I decided to go back to using Python for most of my work to boost my productivity and make it also easier for people to customise/use my code/libraries.

So I very recently revived Morpheas. Morphease is no longer a pure python library and no longer depends on BGL or OpenGL, instead there will be a new module called cmopph that gives low lever access to Blender 2.8 GUI. This means goodbye to PIL and any form of third party dependency, instead Morpheas leverages the immense power of Blender 2.8 directly.

However what complicates stuff is that I can no longer release Morpheas as independent library mainly because oh how deep its integrated into Blender. I am considering however a free version for my custom Build of Blender and instead selling the addons themselves. But this is a long term goal because right now my focus is on releasing Ephestos.

Morpheas will play a central role for my future goals for Ephestos and most likely will be also independent of Blender to make it easy for me to port my GUIs to other Apps in case I ever want to do this.

On the matter of running the existing Morphea on MacOS it should work for the simply reason that my main platform is the MacOS however I have no idea what happens with Blender 2.8 because in my early effort I did not even manage to load Morpheas in any OS.

My current version of the new Morphease builds fine on MacOS , Ubuntu and Win10.

You are more than welcome to take old Morpheas and port it to 2.8 , AFAIK 2.8 does support BGL but I have no clue how well it does that considering that not even the beta version is out now. I used PIL because it was fast enough and because I did not want to load the images inside blender image editor. Blender 2.8 come with a new module called imbuf which gives access to Blender internal mechanism for loading image files (including icons, material previews etc) which makes the need for PIL no longer mandatory. I have contributed to this module (C code) because at first I was planning to use it for my project but I decided not to.

My new Morpheas does not use imbuf module, instead I implement my own module cause I want to keep my C code independent from the Blender source code and I like to have full freedom in my implementation which makes debugging my code also easier. This also allows me greater freedom in the features I want for Morpheas have in the future.

So yes Morpheas is stronger and more powerful than ever, but it may take me some time before I make it part of a free release because at this moment everything is in a state of flux. Of course this is still GPL license as is the entire Ephestos project and it will shortly make it available through a yearly commercial subscription.