Professional Documents
Culture Documents
Full Chapter Core Blender Development Understanding The Essential Source Code 1St Edition Brad E Hollister PDF
Full Chapter Core Blender Development Understanding The Essential Source Code 1St Edition Brad E Hollister PDF
https://textbookfull.com/product/core-blender-development-
understanding-the-essential-source-code-1st-edition-brad-e-
hollister/
https://textbookfull.com/product/neuroimaging-software-and-
communication-the-social-code-of-source-code-edison-bicudo/
https://textbookfull.com/product/understanding-business-the-
core-1st-edition-william-g-nickels/
https://textbookfull.com/product/essential-docker-for-asp-net-
core-mvc-1st-edition-adam-freeman/
The Blender Python API: Precision 3D Modeling and Add-
on Development 1st Edition Chris Conlan
https://textbookfull.com/product/the-blender-python-api-
precision-3d-modeling-and-add-on-development-1st-edition-chris-
conlan/
https://textbookfull.com/product/understanding-bergson-
understanding-modernism-1st-edition-s-e-gontarski/
https://textbookfull.com/product/source-code-analytics-with-
roslyn-and-javascript-data-visualization-mukherjee/
https://textbookfull.com/product/write-great-code-understanding-
the-machine-2nd-edition-randall-hyde/
Brad E. Hollister
This work is subject to copyright. All rights are solely and exclusively
licensed by the Publisher, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in
any other physical way, and transmission or information storage and
retrieval, electronic adaptation, computer software, or by similar or
dissimilar methodology now known or hereafter developed.
The publisher, the authors and the editors are safe to assume that the
advice and information in this book are believed to be true and accurate
at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the
material contained herein or for any errors or omissions that may have
been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
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.
Official Documentation
The official developer site is available at https://developer.blender.org
(see Figure 1-1). There you will find the Blender Foundation’s Phabricator site,
responsible for being a portal to their code repositories, bug tracker, developer
documents, etc.
Communication Channels
It is helpful to speak with developers actively working on the core source code.
While the Blender developer community maintains an Internet Relay Chat (IRC)
room, located on Freenode in the channel #blendercoders, the latest way to
interact in real-time is on https://blender.chat. #blender-coders is the
relevant channel there, for developers (Figure 1-2).
As with most open source projects, Blender has an email list. This provides
another key resource for communication with the Blender developer community. To
post a message for “core” developers to read, and potentially answer, the email
address is bf-committers@blender.org (see Figure 1-3). This is the appropriate list
for developers (and, hopefully, eventually committers), as there are other mailing
lists dedicated only to users, and other aspects of the Blender project apart from
development.
Figure 1-3 Bf-committers subscription web page. This sign-up page is accessible from the official
Blender project wiki
Figure 1-4 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
Libraries not considered “core,” but maintained by Blender, are in the intern
directory. Notably, the ghost module is located there. We will, however, talk more
about ghost (Generic Handy Operating System Toolkit) as it provides an
abstraction to the underlying platform.
Figure 1-5 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
Also in intern is an internal module called guardedalloc . This module wraps
the dynamic memory allocation functions from the C standard library. The
allocation functions are of the form:
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.
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.
For now, realize that modules serving as support for other modules have an
intern subdirectory of their own. There will also be a number of header files above
their intern/, which allow export (inclusion) of the interface function prototypes.
For the module blenloader (Figure 1-7), we can see this convention in the source
tree.
Figure 1-6 The “core” blender modules, showing the entire set located in source/blender/. The
directory layout is split over two subfigures, left-to-right
In a general sense, the editors module is one of the highest in the module
hierarchy, in that it only calls to lower-level functions. This module’s contents (each
subdirectory being an editor or tool, not to be confused with source/tools) ties
together the support functionality of other modules. We will explore editors/mesh/
(mesh operators or “tool” code), and editors/space_view3d/ (an editor “view”),
further in subsequent chapters.
Figure 1-7 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 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.
Listing 1-1 shows an excerpt from the entry-point CMakeLists.txt. In addition to
setting various CMake built-in environment variables (e.g.,
CMAKE_BUILD_TYPE_INIT), new ones are defined (here,
OpenGL_GL_PREFERENCE, for instance). Also shown in Listing 1-1 is an inclusion
of a number of modules (externally referenced CMake scripts), located at
${CMAKE_SOURCE_DIR}/build_files/cmake/Modules and
${CMAKE_SOURCE_DIR}/build_files/cmake/platform.
...
cmake_minimum_required(VERSION 3.5)
if(NOT EXECUTABLE_OUTPUT_PATH)
set(FIRST_RUN TRUE)
else()
set(FIRST_RUN FALSE)
endif()
Figure 1-8 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
...
add_subdirectory(datatoc)
add_subdirectory(editors)
add_subdirectory(windowmanager)
add_subdirectory(blenkernel)
add_subdirectory(blenlib)
add_subdirectory(bmesh)
add_subdirectory(draw)
add_subdirectory(render)
add_subdirectory(blenfont)
add_subdirectory(blentranslation)
add_subdirectory(blenloader)
add_subdirectory(depsgraph)
add_subdirectory(ikplugin)
add_subdirectory(physics)
add_subdirectory(gpu)
add_subdirectory(imbuf)
add_subdirectory(nodes)
add_subdirectory(modifiers)
add_subdirectory(gpencil_modifiers)
add_subdirectory(shader_fx)
add_subdirectory(makesdna)
add_subdirectory(makesrna)
if(WITH_COMPOSITOR)
add_subdirectory(compositor)
endif()
if(WITH_IMAGE_OPENEXR)
add_subdirectory(imbuf/intern/openexr)
endif()
if(WITH_OPENIMAGEIO)
add_subdirectory(imbuf/intern/oiio)
endif()
if(WITH_IMAGE_DDS)
add_subdirectory(imbuf/intern/dds)
endif()
if(WITH_IMAGE_CINEON)
add_subdirectory(imbuf/intern/cineon)
endif()
if(WITH_CODEC_AVI)
add_subdirectory(avi)
endif()
if(WITH_PYTHON)
add_subdirectory(python)
endif()
if(WITH_OPENCOLLADA)
add_subdirectory(collada)
endif()
if(WITH_FREESTYLE)
add_subdirectory(freestyle)
endif()
if(WITH_ALEMBIC)
add_subdirectory(alembic)
endif()
...
Listing 1-2 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.
Figure 1-9 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
/**************************** registration
**********************************/
void ED_operatortypes_mesh(void)
{
...
WM_operatortype_append(MESH_OT_primitive_cone_add);
WM_operatortype_append(MESH_OT_primitive_grid_add);
WM_operatortype_append(
MESH_OT_primitive_monkey_add);
WM_operatortype_append(
MESH_OT_primitive_uv_sphere_add);
WM_operatortype_append(
MESH_OT_primitive_ico_sphere_add);
...
Listing 1-3 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 call to WM_operatortype_append() connects the operator to the
Blender “RNA” system (Listing 1-4). We defer a discussion about Blender “RNA”
until the appropriate chapter, but wm_operatortype_append__begin() from
source/blender/windowmanager/intern/wm_operator_type.c forms part of this
“gluing” process.
/* api callbacks */
ot->exec = add_primitive_icosphere_exec;
ot->poll = ED_operator_scene_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
RNA_def_int(ot->srna, "subdivisions", 2, 1, 10,
"Subdivisions", "", 1, 8);
ED_object_add_unit_props_radius(ot);
ED_object_add_mesh_props(ot);
ED_object_add_generic_props(ot, true);
}
Listing 1-5 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
Listing 1-6 shows the add_primitive_icosphere_exec() callback
implementation, defined in the same source file as
MESH_OT_primitive_ico_sphere_add(). It is declared static, so that only
the callback mechanism (operator) has access to the function.
WM_operator_view3d_unit_defaults(C, op);
ED_object_add_generic_get_opts(C, op, 'Z', loc, rot,
&enter_editmode, &local_view_bits, NULL);
obedit = make_prim_init(C,
CTX_DATA_(BLT_I18NCONTEXT_ID_MESH,
"Icosphere"),
loc,
rot,
local_view_bits,
&creation_data);
em = BKE_editmesh_from_object(obedit);
...
return OPERATOR_FINISHED;
}
Listing 1-6 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
If a user creates an icosphere from the UI,
add_primitive_icosphere_exec() will be called in response. Figure 1-10
shows the call stack for this scenario.
Figure 1-10 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.
while (1) {
Note 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.
Figure 1-11 Partial view of WM_main()’s call graph. Such call graphs are easily generated using
Doxygen
Footnotes
1 At the time of writing, version 2.90 was just released. The book was started while 2.83 was still
current. However, the core principles of the Blender codebase have remained consistent over time.
The book’s code repository is based on the master branch Git revision (SHA1 ID)
28fca2c588fdfb44919ec82eddab19d8cf2e8c9e.
3 As this is the first listing in the book, note that each listing is verbatim from the distribution. At
times, you will see typos and spelling errors, especially in the comments from the source. Here, we
see that “hare” is a misspelling of “have.” We do not mention any further typos in the source.
4 www.doxygen.nl/manual/diagrams.html.
© The Author(s), under exclusive license to APress Media, LLC , part of Springer Nature 2021
B. E. Hollister, Core Blender Development
https://doi.org/10.1007/978-1-4842-6415-7_2
This chapter explains Blender’s persistent data model and related data structures. We
first discuss a high-level description of the blend file. One of the most interesting aspects
about the blend file is that it has been engineered to be very fast. Its contents are a binary
image of memory, when the file was serialized. Blender supports backward compatibility,
making the required transformations of the data structures in a given release to any later
release. We will discuss the mechanics of reading a blend file. Because the blend file is a
direct copy of runtime data structures, a good understanding of the blend file will
support our understanding of how Blender maintains state and manages scene contents,
such as objects and mesh data.
Figure 2-1 Excerpt from the beginning of the BlendFileDnaExporter_25.py output. The title states these
are “SDNA structures,” but possibly more accurate is that they are the “DNA” type struct field information
read from the SDNA blocks, included in the “DNA1” file-block of the blend file. There is a separate SDNA
struct, which is itself a “DNA” type struct
The poet, too, appears to have paid 2s. 6d. for the insertion of his
lines in the Caledonian Mercury.
From this time onward, an annual ball, given by ‘the Right
Honourable Company of Hunters’ in the Palace of Holyroodhouse, is
regularly chronicled. At one which took place on the 8th January
1736—the Hon. Master Charles Leslie being 1735.
‘king,’ and the Hon. Lady Helen Hope being
‘queen’—‘the company in general made a very grand appearance, an
elegant entertainment and the richest wines were served up, and the
whole was carried on and concluded with all decency and good order
imaginable.’ A ball given by the same fraternity in the same place, on
the ensuing 21st of December, was even more splendid. There were
two rooms for dancing, and two for tea, illuminated with many
hundreds of wax-candles. ‘In the Grand Hall [the Gallery?], a table
was covered with three hundred dishes en ambiqu, at which sate a
hundred and fifty ladies at a time ... illuminated with four hundred
wax-candles. The plan laid out by the council of the company was
exactly followed out with the greatest order and decency, and
concluded without the least air of disturbance.’
On the 27th January 1737, ‘the young gentlemen-burghers’ of
Aberdeen gave ‘a grand ball to the ladies, the most splendid and
numerous ever seen there;’ all conducted ‘without the least confusion
or disorder.’ The anxiety to shew that there was no glaring
impropriety in the conduct of the company on these occasions, is
significant, and very amusing.[730]
The reader of this work has received—I fear not very thankfully—
sundry glimpses of the frightful state of the streets of Edinburgh in
previous centuries; and he must have readily understood that the
condition of the capital in this respect represented that of other
populous towns, all being alike deficient in any recognised means of
removing offensive refuse. There was, it must be admitted,
something peculiar in the state of Edinburgh in sanitary respects, in
consequence of the extreme narrowness of its many closes and
wynds, and the height of its houses. How it was endured, no modern
man can divine; but it certainly is true that, at the time when men
dressed themselves in silks and laces, and took as much time for
their toilets as a fine lady, they had to pass in all their bravery
amongst piles of dung, on the very High Street of Edinburgh, and
could not make an evening call upon Dorinda or Celia in one of the
alleys, without the risk of an ablution from above sufficient to
destroy the most elegant outfit, and put the wearers out of conceit
with themselves for a fortnight.
The struggles of the municipal authorities at sundry times to get
the streets put into decent order against a 1735.
royal ceremonial entry, have been adverted
to in our earlier volumes. It would appear that things had at last
come to a sort of crisis in 1686, so that the Estates then saw fit to
pass an act[731] to force the magistrates to clean the city, that it might
be endurable for the personages concerned in the legislature and
government, ordaining for this purpose a ‘stent’ of a thousand
pounds sterling a year for three years on the rental of property. A
vast stratum of refuse, through which people had made lanes
towards their shop-doors and close-heads, was then taken away—
much of it transported by the sage provost, Sir James Dick, to his
lands at Prestonfield, then newly enclosed, and the first that were so
—which consequently became distinguished for fertility[732]—and the
city was never again allowed to fall into such disorder. There was
still, however, no regular system of cleaning, beyond what the street
sewers supplied; and the ancient practice of throwing ashes, foul
water, &c., over the windows at night, graced only with the warning-
cry of Gardez l’eau, was kept up in full vigour by the poorer and
more reckless part of the population.
An Edinburgh merchant and magistrate, named Sir Alexander
Brand, who has been already under our attention as a manufacturer
of gilt leather hangings, at one time presented an overture to the
Estates for the cleaning of the city. The modesty of the opening
sentence will strike the reader: ‘Seeing the nobility and gentry of
Scotland are, when they are abroad, esteemed by all nations to be the
finest and most accomplished people in Europe, yet it’s to be
regretted that it’s always casten up to them by strangers, who admire
them for their singular qualifications, that they are born in a nation
that has the nastiest cities in the world, especially the metropolitan.’
He offered to clean the city daily, and give five hundred a year for the
refuse.[733] But his views do not seem to have been carried into effect.
After 1730, when, as we have seen, great changes were beginning
to take place in Scotland, increased attention was paid to external
decency and cleanliness. The Edinburgh magistrates were anxious to
put down the system of cleaning by ejectment. We learn, for
example, from a newspaper, that a servant-girl having thrown foul
water from a fourth story in Skinners’ Close, ‘which much abused a
lady passing by, was brought before the bailies, and obliged to enact
herself never to be guilty of the like 1735.
practices in future. ’Tis hoped,’ adds our
chronicler, ‘that this will be a caution to all servants to avoid this
wicked practice.’
There lived at this time in Edinburgh a respectable middle-aged
man, named Robert Mein, the representative of the family which had
kept the post-office for three generations between the time of the
civil war and the reign of George I., and who boasted that the pious
lady usually called Jenny Geddes, but actually Barbara Hamilton,
who threw the stool in St Giles’s in 1637, was his great-grandmother.
Mein, being a man of liberal ideas, and a great lover of his native city,
desired to see it rescued from the reproach under which it had long
lain as the most fetid of European capitals, and he accordingly drew
up a paper, shewing how the streets might be kept comparatively
clean by a very simple arrangement. His suggestion was, that there
should be provided for each house, at the expense of the landlord, a
vessel sufficient to contain the refuse of a day, and that scavengers,
feed by a small subscription among the tenants, should discharge
these every night. Persons paying what was then a very common
rent, ten pounds, would have to contribute only five shillings a year;
those paying fifteen pounds, 7s. 6d., and so on in proportion. The
projector appears to have first explained his plan to sundry
gentlemen of consideration—as, for example, Mr William Adam,
architect, and Mr Colin Maclaurin, professor of mathematics, who
gave him their approbation of it in writing—the latter adding: ‘I
subscribe for my own house in Smith’s Land, Niddry’s Wynd, fourth
story, provided the neighbours agree to the same.’ Other subscribers
of consequence were obtained, as ‘Jean Gartshore, for my house in
Morocco’s Close, which is £15 rent,’ and ‘the Countess of
Haddington, for the lodging she possessed in Bank Close,
Lawnmarket, valued rent £20.’ Many persons agreed to pay a half-
penny or a penny weekly; some as much as a half-penny per pound
of rent per month. One lady, however, came out boldly as a recusant
—‘Mrs Black refuses to agree, and acknowledges she throws
over.’[734]
Mr Mein’s plan was adopted, and acted upon to some extent by the
magistrates; and the terrible memory of the ‘Dirty Luggies,’ which
were kept in the stairs, or in the passages within doors, as a
necessary part of the arrangement, was fresh in the minds of old
people whom I knew in early life. The city was in 1740 divided into
twenty-nine districts, each having a couple 1735.
of scavengers supported at its own expense,
who were bound to keep it clean; while the refuse was sold to persons
who engaged to cart it away at three half-pence per cart-load.[735]
The Muse, it was said, after a long career of glory in ancient times,
had reached the shores of England, where Shakspeare taught her to
soar:
‘At last, transported by your tender care,
She hopes to keep her seat of empire here.
For your protection, then, ye fair and great,
This fabric to her use we consecrate;
On you it will depend to raise her name,
And in Edina fix her lasting fame.’
All this was of course but vain prattle. The piece appeared in the
Gentleman’s Magazine (August 1737), and no doubt awoke some
sympathy; but the poet had to bear single-handed the burden of a
heavy loss, as a reward for his spirited attempt to enliven the beau
monde of Edinburgh.