The goal of this chapter is to familiarize you with the Blender “core” source1, and is intended to be the starting point for the rest of the book. Blender’s codebase is written primarily in the C programming language. Part of this introduction is a preliminary discussion of Blender’s CMake build system. Additionally, we provide an execution trace of how Blender registers an operator, and of the execution of its callback. Much of this book will be easier to digest, if you make an effort to browse the source code in a text editor—ideally, after reading the associated passage. If you have not yet downloaded and compiled the Blender source code, you will eventually want to do so. However, this chapter may be read first.
The Blender Project
Throughout this book, we do not want to merely replicate the wealth of information already present at https://developer.blender.org. Nonetheless, we direct your attention to these valuable resources at the appropriate times. You should use those external documents in support of, and in tandem with, the material of this text.
To fill in “missing” parts of the Blender Foundation’s documentation
To present a simpler starting point in becoming a Blender “core” developer
To go beyond existing documentation, so as to jump-start your efforts
Such experience could otherwise only be gained by direct inspection (and significant experimentation) of the source code. Ultimately, as you progress, that approach will be necessary as well.
Official Documentation
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig1_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig1_HTML.jpg)
The Blender Foundation’s portal for developers: https://developer.blender.org
As aspects can change concerning how to clone and build Blender, and building is both platform specific and configurable, the best way to obtain up-to-date instructions is to visit https://developer.blender.org.
Communication Channels
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig2_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig2_HTML.jpg)
Blender’s browser-based chat server interface
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig3_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig3_HTML.jpg)
Bf-committers subscription web page. This sign-up page is accessible from the official Blender project wiki
The Blender Source Tree
https://wiki.blender.org/wiki/Reference/FAQ, which is unfortunately not found in the source distribution itself. It contains information on what Blender “DNA” and “RNA” are, along with the datatoc module.
The second is the wiki description of the source code modules, https://wiki.blender.org/wiki/Source/File_Structure.
Third is the slightly out-of-date www.blender.org/bf/codelayout.jpg. Inaccuracies are due to omission of newer modules.
There are other important documents that we will mention. But for starters, you should at least read the aforementioned material.
The key aspect of the codelayout.jpg information is the calling hierarchy of the modules. “Modules” in the Blender Project’s parlance represent directories containing code related to a particular set of functions (much as a component is, in an object-oriented design). Some modules have interfaces for client modules. The Blender terminology for these interfaces is module “APIs.”
The easiest way to begin browsing Blender’s source is by using the project’s repository server: https://developer.blender.org/diffusion/B/. There, you will also find the latest instructions on cloning the git repository.2
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig4_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig4_HTML.jpg)
The Eclipse IDE’s “project explorer” view, from the CMake generated .proj. We can see that Blender contains many more directories than those of the “core” source code, located in source/. There is a directory for unit tests, that is, tests/. And, doc/ is for documentation. We will stay focused on source/, and go beyond it only when required
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig5_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig5_HTML.jpg)
The Eclipse IDE’s “project explorer” view of source/. Note that in codelayout.jpg and https://wiki.blender.org/wiki/Source/File_Structure, this path would be written as blender/source/. Most of the official documents refer to the repository’s directory as blender/. However, during cloning with git, you can name this directory
Whenever Blender dynamically allocates (or deallocates) memory, you will see the MEM_* API being used instead of malloc, calloc, etc. The MEM_* API prototypes are available from [Source Directory]/intern/guardedalloc/MEM_guardedalloc.h.
The [Source Directory]/doc/guides/ directory contains additional official documentation on guardedalloc and the user interface API. The two text files are blender-guardedalloc.txt and interface_API.txt. We will talk more about the UI_* API in Chapter 8. Much of the interface_API.txt document is now obsolete, but still contains useful information.
There are modules that we will not concern ourselves with, due to the scope of the codebase. Therefore, this book focuses on UI and geometric modeling, along with the essential modules from Blender (e.g., windowmanager, blenloader, etc.). Figure 1-6 shows a listing of the “core” Blender modules.
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig6_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig6_HTML.jpg)
The “core” blender modules, showing the entire set located in source/blender/. The directory layout is split over two subfigures, left-to-right
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig7_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig7_HTML.jpg)
The blenloader module . The intern subdirectory contains the implementation of its interface and static “internal” functions. Blenloader’s interface prototypes are located at the same level as intern/, in C header files. There is a similar layout for all modules with an API
The Blender CMake Build System
Now let us discuss how Blender makes use of the CMake build system and how various modules can be included or excluded from a build.
The Basics
CMake is a “meta” build system, developed by Kitware. By “meta,” it is implied that CMake acts as an abstraction layer over platform-specific build systems, such as autotools or Visual Studio. The official documentation for CMake is available at https://cmake.org. Kitware provides a complete description of their scripting language used to write CMakeLists.txt files there.
The responsibility of CMake is to produce build files for any given platform which is supported by Blender. CMake uses CMakeLists.txt files to direct the generation of platform-specific build scripts. For example, Blender’s CMakeLists.txt files are written to support build script generation for Linux, Windows, and Mac OS, and for a chosen build script type on that platform, that is, Visual Studio vs. Makefile on Linux.
In Blender’s source tree, a CMakeLists.txt file is provided at the top-level (shown in Figure 1-4) as the entry point. There is also a CMakeLists.txt file above the individual “core” modules (Figure 1-6) and in each of blender/, creator/, and tools/ (Figure 1-5). There is at least one CMakeLists.txt file in every module directory (not necessarily one in a module’s subdirectory, however) directing CMake to include the module’s source files and headers. For instance, see the CMakeLists.txt file in Figure 1-7, for the blenloader module.
Excerpt from the repository top-level CMakeLists.txt file3
As this book is about “core” Blender development, we focus on the CMakeLists.txt files that direct the build system for the primary source code. You should verify that Blender’s build system is more extensive than the CMakeLists.txt files in the repository’s source/ directory alone.
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig8_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig8_HTML.jpg)
The directories in the repository that comprise the build system. Most of the build system for “core” Blender is in the source/ directory, alongside the source files. We have CMake script support functions (defined in build_files/ subdirectories) or scripts for building Blender dependencies
Module Build Options
From source/blender/CMakeLists.txt, we see the “core” modules included by the add_subdirectory() CMake script function, along with conditional modules near the end of the snippet
You should find it useful to reset some of these options when configuring your build. Beyond what is shown here, there are more fine-grained configurations for builds. CMake actually defines C preprocessor macros to allow inclusion of individual lines of source code, instead of the coarser-level “whole” directories we show in Listing 1-2.
It is advisable that when building Blender for the first time, that you build in debug mode, by setting CMAKE_BUILD_TYPE_INIT to “Debug.” This can be done through the cmake executable after the initial configuration, or by changing the source/CMakeLists.txt file itself.
A Representative Code Example
Let us commence with exploring the Blender code, by a concrete example. It will relate UI interaction with the operator code tied to particular UI events. The purpose of this relatively simple example is to lay some groundwork for more future descriptions about operators and related topics.
Geometric Modeling and Operators
We wish to get the “ball rolling,” as it were, by introducing operator registration and associated callback invocation. Thus, we will trace the execution path taken by Blender when a user creates a spherical model, regarding the operator registration for that case.
Operators in Blender are essentially functions (and state) that are called when they are triggered by the UI. They are more than just a callback in Blender. We will mostly focus on the callback portion, in our example trace.
First, let us investigate operator registration. As we are interested in creating a sphere primitive, an icosphere modeled with polygons, we note the registration of this operator via MESH_OT_primitive_ico_sphere_add(). This function is defined in source/blender/editors/mesh/editmesh_add.c.
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig9_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig9_HTML.jpg)
During Blender initialization, mesh operators are registered. The windowmanager module is called from main(), located in source/creator/creator.c, which subsequently calls the editor module’s ED_operatortypes_mesh(). The call stack is shown here (from gdb within the Eclipse IDE). Hexadecimal numbers are the logical addresses of the functions. These numbers are unimportant here, and sometimes may be partially abbreviated for clarity
Excerpt from ED_operatortypes_mesh() from source/blender/editors/mesh/mesh_ops.c. This code snippet shows operator registration for many of the “primitives” that can be easily created by either menu or hotkey combinations. MESH_OT_primitive_ico_sphere_add is a function pointer and is in bold type
The WM_operatortype_append() function . This function calls MESH_OT_primitive_ico_sphere_add() to register the operator shown in bold type
MEST_OT_primitive_ico_sphere_add(), an operator registration function from source/blender/editors/mesh/editmesh_add.c. Setting the callback for the operator is in bold type
Elided add_primitive_icosphere_exec() callback function, from source/blender/editors/mesh/editmesh_add.c. Notice the bContext struct pointer called C, and the call to the makesrna module via RNA_boolean_get(). These are important parts of the Blender architecture, for maintaining and conveying state information
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig10_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig10_HTML.jpg)
WM_main() is the event loop for Blender, located in source/blender/windowmanager/intern/wm.c. wm_event_do_handlers() is the high-level function updating the callback (or handler) mechanism. We see here that add_primitive_icosphere_exec() is called after having been registered, and now invoked from the UI
We will not go further into add_primitive_icosphere_exec(), as the point of this example is to illustrate operator registration and invocation of a callback (other operators are registered similarly). For the present, however, notice the interaction with the module makesrna and the bContext struct called C (Listing 1-6). The global variable named C is significant.
Blender’s Event Loop
WM_main() contains the event loop for Blender, as shown in Listing 1-7. C, the same object of type bContext struct as already mentioned, is passed to each of the high-level update function calls of the event loop. All of these are wrappers who either collect events, process callbacks based on those events, or broadcast notifiers based on event processing.
Blender’s main event loop, called WM_main(), is defined in source/blender/windowmanager/intern/wm.c
The preceding trace was shown using the call stack and code snippets of the relevant execution path. If you are a visual learner, you will find it beneficial to use Doxygen.4 A sample call graph is shown in Figure 1-11. Because these call graphs are often very large, the proper way to display them is interactively from html. We will discuss Doxygen again in a later chapter.
![../images/495914_1_En_1_Chapter/495914_1_En_1_Fig11_HTML.jpg](../images/495914_1_En_1_Chapter/495914_1_En_1_Fig11_HTML.jpg)
Partial view of WM_main()’s call graph. Such call graphs are easily generated using Doxygen
Road Map for the Remainder of the Book
In this first chapter, we went over some of the basics of the Blender code. We made a distinction between “core” Blender and the other parts of the codebase. We showed how a build of Blender is managed by CMake and how CMake can generate build scripts for various platforms. We also talked a little about operators and callbacks and saw how they worked in the creation of an icosphere.
What Will Not Be Covered
As the Blender codebase is vast, we will not cover things like the game engine and the rendering subsystems (e.g., “Blender Internal,” or Cycles). We will also not describe “core” code related to physics, compositing, animation, or modifiers. Nor will we extensively discuss the full set of editors, such as the outliner, etc.
What Will Be Covered
Going forward, we will break down a series of central “core” modules. We will discuss Blender’s “DNA,” the underlying records that maintain the state for Blender. We will also discuss how Blender integrates its embedded Python interpreter, how its UI is constructed at the C code level, and how Blender’s “RNA” is related to all of this. We will walk through the C code that draws the UI, an OpenGL-based set of widgets internal to Blender itself (and therefore, “core” Blender). The windowmanager module will be analyzed, as it is the primary module of Blender. And, we will decompose polygonal mesh operators to a low level and show how the corresponding mesh data structures are managed. Finally, we will create a new editor within the editor module, using C code to do so.
The focus of this text is how Blender’s code works as an application and how it processes aspects of polygonal models, namely, the basic polygonal mesh editor operations. Knowing this information should eventually allow developers to investigate areas of the Blender codebase beyond the material of this text.