/py_blender_room

A python framework for building 3D environments using Blender

Primary LanguagePythonMIT LicenseMIT

image

Py-Blender-Room

A python framework for building 3D environments using Blender.

Developed and tested with Python 3.7 and Blender 2.83.

Motivation

I once had a need to create a 3D model of an empty room. The model would consist of some walls with windows, a floor and a ceiling. It was chosen to build it using Blender (https://www.blender.org/) a beautiful cross-platform and free 3D modelling software. Moreover, I chose not to create a model "with a mouse", but to program it with the Blender's python API.

As a result, py-blender-room was born, hence the "room" in its name.

How To

py-blender-room offers a workflow to create models and open them in Blender. Individual models, called projects, reside in projects package.

The initial project, named room1, can be found there. The more models I (or anyone else) need to create, the more sub-packages will appear there.

image

the entry script of the project is build.py and it is meant to be interpreted with Blender's built-in Python, as follows:

~/dist/blender-2.83.4-linux64/blender --python py_blender_room/projects/room1/production_build.py

as a result, blender will open with the model as shown in the video below:

open_blender

tip: if you simply want to validate your script without opening Blender's User Interface, you may run Blender with -b option.

Architecture

image

  • Scene holds some objects
  • SceneRenderer knows how to get those objects and make Modeler "materialize" them
  • Modeler is something that implements ModelerInterface. An example of a Modeler is Blender. Another example is FakeModeler which is used in unit tests.

What a project is?

  • a scene class
  • a scene renderer class
  • build.py script

each of these files is described below:

A scene class

This class, inheriting from Scene, defines a high-level list of objects.

Objects can be anything: in case of Room1 project, they are "Wall", "Floor" etc. In case of other imaginary projects, they could be "Tree", "Road" and so on.

In a sense, these classes define the domain-specific language you need for your particular project.

The Scene, in its turn, maintains the list of objects, i.e. those "Walls", "Trees" and "Roads"

The only requirement is that your scene renderer knows how to translate them into the sequence of modeler instructions. For example, in case of walls, Room1SceneRenderer knows how to make modeler create Box meshes, cut out windows, insert "glasses" ang put the whole ensemble into an appropriate position.

A Scene Renderer Class

Your scene renderer class is a middleware that translates your domain-specific scene objects into instructions modeler understands.

A Modeler is "something" that can build your model, for example, Blender's API is modeler. In the framework, modeler is represented with a class implementing ModelerInterface.

note: if you want to use certain feature of blender that wasn't used before, you might want to extend that interface.

build.py

This is an entry script:

def run():
    scene = Room1Scene()
    scene.build()
    modeler = Blender()
    scene_renderer = Room1SceneRenderer()
    scene_renderer.modeler = modeler
    scene_renderer.render(scene)

above is a real working example from Room1 project.

The build script:

  • instantiates a scene
  • invokes a build method of the scene
  • creates a modeler
    • for Blender, just use Blender()
  • instantiates a scene renderer
  • connects a scene renderer with a modeler
  • renders the scene

Testing

There is a workflow set up to smoke-test the code in two ways:

currently, Blender 2.83 is supported and tested.