Merged changes in the trunk up to revision 45133.
Conflicts resolved: source/blender/blenloader/intern/readfile.c source/blender/blenloader/intern/writefile.c source/blender/bmesh/intern/bmesh_construct.c source/blender/bmesh/intern/bmesh_mesh_conv.c source/blender/bmesh/intern/bmesh_mesh_conv.h source/blender/editors/interface/interface_templates.c source/blender/editors/interface/resources.c source/blender/editors/mesh/bmesh_select.c source/blender/editors/mesh/bmesh_tools.c source/blender/editors/space_view3d/drawobject.c source/blender/render/intern/source/shadeoutput.c
This commit is contained in:
@@ -26,16 +26,17 @@ API dump in RST files
|
||||
---------------------
|
||||
Run this script from blenders root path once you have compiled blender
|
||||
|
||||
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py
|
||||
./blender.bin --background -noaudio --python doc/python_api/sphinx_doc_gen.py
|
||||
|
||||
This will generate python files in doc/python_api/sphinx-in/
|
||||
providing ./blender.bin is or links to the blender executable
|
||||
|
||||
To choose sphinx-in directory:
|
||||
./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- -o ../python_api
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
|
||||
|
||||
For quick builds:
|
||||
./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- -q
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial
|
||||
|
||||
|
||||
Sphinx: HTML generation
|
||||
-----------------------
|
||||
@@ -47,6 +48,7 @@ Sphinx: HTML generation
|
||||
|
||||
This requires sphinx 1.0.7 to be installed.
|
||||
|
||||
|
||||
Sphinx: PDF generation
|
||||
----------------------
|
||||
After you have built doc/python_api/sphinx-in (see above),
|
||||
@@ -73,6 +75,7 @@ import os
|
||||
import sys
|
||||
import inspect
|
||||
import shutil
|
||||
import logging
|
||||
|
||||
from platform import platform
|
||||
PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
|
||||
@@ -93,6 +96,30 @@ def handle_args():
|
||||
)
|
||||
|
||||
# optional arguments
|
||||
parser.add_argument("-p", "--partial",
|
||||
dest="partial",
|
||||
type=str,
|
||||
default="",
|
||||
help="Use a wildcard to only build specific module(s)\n"
|
||||
"Example: --partial bmesh*\n",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-f", "--fullrebuild",
|
||||
dest="full_rebuild",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Rewrite all rst files in sphinx-in/ "
|
||||
"(default=False)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-b", "--bpy",
|
||||
dest="bpy",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Write the rst file of the bpy module "
|
||||
"(default=False)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-o", "--output",
|
||||
dest="output_dir",
|
||||
type=str,
|
||||
@@ -100,25 +127,11 @@ def handle_args():
|
||||
help="Path of the API docs (default=<script dir>)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-B", "--sphinx-build",
|
||||
dest="sphinx_build",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Run sphinx-build SPHINX_IN SPHINX_OUT (default=False)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-N", "--sphinx-named-output",
|
||||
dest="sphinx_named_output",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Add the theme name to the html dir name (default=False)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-T", "--sphinx-theme",
|
||||
dest="sphinx_theme",
|
||||
type=str,
|
||||
default='default',
|
||||
help=
|
||||
help =
|
||||
# see SPHINX_THEMES below
|
||||
"Sphinx theme (default='default')\n"
|
||||
"Available themes\n"
|
||||
@@ -132,25 +145,53 @@ def handle_args():
|
||||
# 'sphinxdoc', 'traditional'], # sphinx
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-f", "--fullrebuild",
|
||||
dest="full_rebuild",
|
||||
parser.add_argument("-N", "--sphinx-named-output",
|
||||
dest="sphinx_named_output",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Rewrite all rst files in sphinx-in/ (default=False)",
|
||||
help="Add the theme name to the html dir name.\n"
|
||||
"Example: \"sphinx-out_haiku\" (default=False)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-t", "--testdump",
|
||||
dest="test_dump",
|
||||
parser.add_argument("-B", "--sphinx-build",
|
||||
dest="sphinx_build",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Dumps a small part of the API (default=False)",
|
||||
help="Build the html docs by running:\n"
|
||||
"sphinx-build SPHINX_IN SPHINX_OUT\n"
|
||||
"(default=False; does not depend on -P)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-b", "--bpy",
|
||||
dest="bpy",
|
||||
parser.add_argument("-P", "--sphinx-build-pdf",
|
||||
dest="sphinx_build_pdf",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Write the rst file of the bpy module (default=False)",
|
||||
help="Build the pdf by running:\n"
|
||||
"sphinx-build -b latex SPHINX_IN SPHINX_OUT_PDF\n"
|
||||
"(default=False; does not depend on -B)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-R", "--pack-reference",
|
||||
dest="pack_reference",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="Pack all necessary files in the deployed dir.\n"
|
||||
"(default=False; use with -B and -P)",
|
||||
required=False)
|
||||
|
||||
parser.add_argument("-l", "--log",
|
||||
dest="log",
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=(
|
||||
"Log the output of the api dump and sphinx|latex "
|
||||
"warnings and errors (default=False).\n"
|
||||
"If given, save logs in:\n"
|
||||
"* OUTPUT_DIR/.bpy.log\n"
|
||||
"* OUTPUT_DIR/.sphinx-build.log\n"
|
||||
"* OUTPUT_DIR/.sphinx-build_pdf.log\n"
|
||||
"* OUTPUT_DIR/.latex_make.log",
|
||||
),
|
||||
required=False)
|
||||
|
||||
# parse only the args passed after '--'
|
||||
@@ -165,15 +206,22 @@ ARGS = handle_args()
|
||||
|
||||
# ----------------------------------BPY-----------------------------------------
|
||||
|
||||
BPY_LOGGER = logging.getLogger('bpy')
|
||||
BPY_LOGGER.setLevel(logging.DEBUG)
|
||||
|
||||
"""
|
||||
# for quick rebuilds
|
||||
rm -rf /b/doc/python_api/sphinx-* && \
|
||||
./blender.bin --background -noaudio --factory-startup --python doc/python_api/sphinx_doc_gen.py && \
|
||||
./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
|
||||
sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
|
||||
|
||||
or
|
||||
|
||||
./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
|
||||
"""
|
||||
|
||||
# Switch for quick testing so doc-builds don't take so long
|
||||
if not ARGS.test_dump:
|
||||
if not ARGS.partial:
|
||||
# full build
|
||||
FILTER_BPY_OPS = None
|
||||
FILTER_BPY_TYPES = None
|
||||
@@ -181,6 +229,7 @@ if not ARGS.test_dump:
|
||||
EXCLUDE_MODULES = ()
|
||||
|
||||
else:
|
||||
# can manually edit this too:
|
||||
FILTER_BPY_OPS = ("import.scene", ) # allow
|
||||
FILTER_BPY_TYPES = ("bpy_struct", "Operator", "ID") # allow
|
||||
EXCLUDE_INFO_DOCS = True
|
||||
@@ -195,9 +244,9 @@ else:
|
||||
"bge.types",
|
||||
"bgl",
|
||||
"blf",
|
||||
#"bmesh",
|
||||
#"bmesh.types",
|
||||
#"bmesh.utils",
|
||||
"bmesh",
|
||||
"bmesh.types",
|
||||
"bmesh.utils",
|
||||
"bpy.app",
|
||||
"bpy.app.handlers",
|
||||
"bpy.context",
|
||||
@@ -215,10 +264,29 @@ else:
|
||||
"Freestyle",
|
||||
)
|
||||
|
||||
# ------
|
||||
# Filter
|
||||
#
|
||||
# TODO, support bpy.ops and bpy.types filtering
|
||||
import fnmatch
|
||||
m = None
|
||||
EXCLUDE_MODULES = tuple([m for m in EXCLUDE_MODULES if not fnmatch.fnmatchcase(m, ARGS.partial)])
|
||||
|
||||
EXCLUDE_INFO_DOCS = (not fnmatch.fnmatchcase("info", ARGS.partial))
|
||||
|
||||
del m
|
||||
del fnmatch
|
||||
|
||||
BPY_LOGGER.debug("Partial Doc Build, Skipping: %s\n" % "\n ".join(sorted(EXCLUDE_MODULES)))
|
||||
|
||||
#
|
||||
# done filtering
|
||||
# --------------
|
||||
|
||||
try:
|
||||
__import__("aud")
|
||||
except ImportError:
|
||||
print("Warning: Built without 'aud' module, docs incomplete...")
|
||||
BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
|
||||
EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", )
|
||||
|
||||
# examples
|
||||
@@ -229,7 +297,7 @@ for f in os.listdir(EXAMPLES_DIR):
|
||||
EXAMPLE_SET.add(os.path.splitext(f)[0])
|
||||
EXAMPLE_SET_USED = set()
|
||||
|
||||
#rst files dir
|
||||
# rst files dir
|
||||
RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
|
||||
|
||||
# extra info, not api reference docs
|
||||
@@ -248,10 +316,66 @@ RNA_BLACKLIST = {
|
||||
"UserPreferencesSystem": {"language", }
|
||||
}
|
||||
|
||||
MODULE_GROUPING = {
|
||||
"bmesh.types": (
|
||||
("Base Mesh Type", '-'),
|
||||
"BMesh",
|
||||
("Mesh Elements", '-'),
|
||||
"BMVert",
|
||||
"BMEdge",
|
||||
"BMFace",
|
||||
"BMLoop",
|
||||
("Sequence Accessors", '-'),
|
||||
"BMElemSeq",
|
||||
"BMVertSeq",
|
||||
"BMEdgeSeq",
|
||||
"BMFaceSeq",
|
||||
"BMLoopSeq",
|
||||
"BMIter",
|
||||
("Selection History", '-'),
|
||||
"BMEditSelSeq",
|
||||
"BMEditSelIter",
|
||||
("Custom-Data Layer Access", '-'),
|
||||
"BMLayerAccessVert",
|
||||
"BMLayerAccessEdge",
|
||||
"BMLayerAccessFace",
|
||||
"BMLayerAccessLoop",
|
||||
"BMLayerCollection",
|
||||
"BMLayerItem",
|
||||
("Custom-Data Layer Types", '-'),
|
||||
"BMLoopUV"
|
||||
)
|
||||
}
|
||||
|
||||
# --------------------configure compile time options----------------------------
|
||||
|
||||
# -------------------------------BLENDER----------------------------------------
|
||||
|
||||
blender_version_strings = [str(v) for v in bpy.app.version]
|
||||
|
||||
# converting bytes to strings, due to #30154
|
||||
BLENDER_REVISION = str(bpy.app.build_revision, 'utf_8')
|
||||
BLENDER_DATE = str(bpy.app.build_date, 'utf_8')
|
||||
|
||||
BLENDER_VERSION_DOTS = ".".join(blender_version_strings) # '2.62.1'
|
||||
if BLENDER_REVISION != "Unknown":
|
||||
BLENDER_VERSION_DOTS += " r" + BLENDER_REVISION # '2.62.1 r44584'
|
||||
|
||||
BLENDER_VERSION_PATH = "_".join(blender_version_strings) # '2_62_1'
|
||||
if bpy.app.version_cycle == "release":
|
||||
BLENDER_VERSION_PATH = "%s%s_release" % ("_".join(blender_version_strings[:2]),
|
||||
bpy.app.version_char) # '2_62_release'
|
||||
|
||||
# --------------------------DOWNLOADABLE FILES----------------------------------
|
||||
|
||||
REFERENCE_NAME = "blender_python_reference_%s" % BLENDER_VERSION_PATH
|
||||
REFERENCE_PATH = os.path.join(ARGS.output_dir, REFERENCE_NAME)
|
||||
BLENDER_PDF_FILENAME = "%s.pdf" % REFERENCE_NAME
|
||||
BLENDER_ZIP_FILENAME = "%s.zip" % REFERENCE_NAME
|
||||
|
||||
# -------------------------------SPHINX-----------------------------------------
|
||||
|
||||
SPHINX_THEMES = {'bf': ['blender-org'], # , 'naiad',
|
||||
SPHINX_THEMES = {'bf': ['blender-org'], # , 'naiad',
|
||||
'sphinx': ['agogo',
|
||||
'basic',
|
||||
'default',
|
||||
@@ -267,37 +391,43 @@ if ARGS.sphinx_theme not in available_themes:
|
||||
print ("Please choose a theme among: %s" % ', '.join(available_themes))
|
||||
sys.exit()
|
||||
|
||||
if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
|
||||
SPHINX_THEME_DIR = os.path.join(ARGS.output_dir, ARGS.sphinx_theme)
|
||||
SPHINX_THEME_SVN_DIR = os.path.join(SCRIPT_DIR, ARGS.sphinx_theme)
|
||||
|
||||
SPHINX_IN = os.path.join(ARGS.output_dir, "sphinx-in")
|
||||
SPHINX_IN_TMP = SPHINX_IN + "-tmp"
|
||||
SPHINX_OUT = os.path.join(ARGS.output_dir, "sphinx-out")
|
||||
if ARGS.sphinx_named_output:
|
||||
SPHINX_OUT += "_%s" % ARGS.sphinx_theme
|
||||
|
||||
if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
|
||||
SPHINX_THEME_DIR = os.path.join(ARGS.output_dir, ARGS.sphinx_theme)
|
||||
SPHINX_THEME_SVN_DIR = os.path.join(SCRIPT_DIR, ARGS.sphinx_theme)
|
||||
# html build
|
||||
if ARGS.sphinx_build:
|
||||
SPHINX_BUILD = ["sphinx-build", SPHINX_IN, SPHINX_OUT]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
if ARGS.log:
|
||||
SPHINX_BUILD_LOG = os.path.join(ARGS.output_dir, ".sphinx-build.log")
|
||||
SPHINX_BUILD = ["sphinx-build",
|
||||
"-w", SPHINX_BUILD_LOG,
|
||||
SPHINX_IN, SPHINX_OUT]
|
||||
|
||||
# configure compile time options
|
||||
# pdf build
|
||||
if ARGS.sphinx_build_pdf:
|
||||
SPHINX_OUT_PDF = os.path.join(ARGS.output_dir, "sphinx-out_pdf")
|
||||
SPHINX_BUILD_PDF = ["sphinx-build",
|
||||
"-b", "latex",
|
||||
SPHINX_IN, SPHINX_OUT_PDF]
|
||||
SPHINX_MAKE_PDF = ["make", "-C", SPHINX_OUT_PDF]
|
||||
SPHINX_MAKE_PDF_STDOUT = None
|
||||
|
||||
# -------------------------------BLENDER----------------------------------------
|
||||
|
||||
'''
|
||||
blender version
|
||||
'''
|
||||
version_strings = [str(v) for v in bpy.app.version]
|
||||
|
||||
BLENDER_VERSION_DOTS = ".".join(version_strings) # '2.62.1'
|
||||
if bpy.app.build_revision != b"Unknown":
|
||||
# converting bytes to strings, due to #30154
|
||||
BLENDER_VERSION_DOTS += " r" + str(bpy.app.build_revision, 'utf_8') # '2.62.1 r44584'
|
||||
|
||||
BLENDER_VERSION_PDF = "_".join(version_strings) # '2_62_1'
|
||||
if bpy.app.version_cycle == "release":
|
||||
BLENDER_VERSION_PDF = "%s%s_release" % ("_".join(version_strings[:2]),
|
||||
bpy.app.version_char) # '2_62_release'
|
||||
if ARGS.log:
|
||||
SPHINX_BUILD_PDF_LOG = os.path.join(ARGS.output_dir, ".sphinx-build_pdf.log")
|
||||
SPHINX_BUILD_PDF = ["sphinx-build", "-b", "latex",
|
||||
"-w", SPHINX_BUILD_PDF_LOG,
|
||||
SPHINX_IN, SPHINX_OUT_PDF]
|
||||
|
||||
sphinx_make_pdf_log = os.path.join(ARGS.output_dir, ".latex_make.log")
|
||||
SPHINX_MAKE_PDF_STDOUT = open(sphinx_make_pdf_log, "w", encoding="utf-8")
|
||||
|
||||
# --------------------------------API DUMP--------------------------------------
|
||||
|
||||
@@ -326,13 +456,13 @@ def undocumented_message(module_name, type_name, identifier):
|
||||
preloadtitle = '%s.%s' % (module_name, identifier)
|
||||
else:
|
||||
preloadtitle = '%s.%s.%s' % (module_name, type_name, identifier)
|
||||
message = "Undocumented (`contribute "\
|
||||
"<http://wiki.blender.org/index.php/"\
|
||||
"Dev:2.5/Py/API/Generating_API_Reference/Contribute/Howto-message"\
|
||||
"?action=edit"\
|
||||
"§ion=new"\
|
||||
"&preload=Dev:2.5/Py/API/Documentation/Contribute/Howto-message"\
|
||||
"&preloadtitle=%s>`_)\n\n" % preloadtitle
|
||||
message = ("Undocumented (`contribute "
|
||||
"<http://wiki.blender.org/index.php/"
|
||||
"Dev:2.5/Py/API/Generating_API_Reference/Contribute"
|
||||
"?action=edit"
|
||||
"§ion=new"
|
||||
"&preload=Dev:2.5/Py/API/Generating_API_Reference/Contribute/Howto-message"
|
||||
"&preloadtitle=%s>`_)\n\n" % preloadtitle)
|
||||
return message
|
||||
|
||||
|
||||
@@ -374,15 +504,20 @@ def example_extract_docstring(filepath):
|
||||
return "\n".join(text), line_no
|
||||
|
||||
|
||||
def write_title(fw, text, heading_char):
|
||||
fw("%s\n%s\n\n" % (text, len(text) * heading_char))
|
||||
def title_string(text, heading_char, double=False):
|
||||
filler = len(text) * heading_char
|
||||
|
||||
if double:
|
||||
return "%s\n%s\n%s\n\n" % (filler, text, filler)
|
||||
else:
|
||||
return "%s\n%s\n\n" % (text, filler)
|
||||
|
||||
|
||||
def write_example_ref(ident, fw, example_id, ext="py"):
|
||||
if example_id in EXAMPLE_SET:
|
||||
|
||||
# extract the comment
|
||||
filepath = os.path.join(EXAMPLES_DIR, "%s.%s" % (example_id, ext))
|
||||
filepath = os.path.join("..", "examples", "%s.%s" % (example_id, ext))
|
||||
filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
|
||||
|
||||
text, line_no = example_extract_docstring(filepath_full)
|
||||
@@ -398,7 +533,7 @@ def write_example_ref(ident, fw, example_id, ext="py"):
|
||||
EXAMPLE_SET_USED.add(example_id)
|
||||
else:
|
||||
if bpy.app.debug:
|
||||
print("\tskipping example:", example_id)
|
||||
BPY_LOGGER.debug("\tskipping example: " + example_id)
|
||||
|
||||
# Support for numbered files bpy.types.Operator -> bpy.types.Operator.1.py
|
||||
i = 1
|
||||
@@ -557,11 +692,34 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
if module_all:
|
||||
module_dir = module_all
|
||||
|
||||
# TODO - currently only used for classes
|
||||
# grouping support
|
||||
module_grouping = MODULE_GROUPING.get(module_name)
|
||||
|
||||
def module_grouping_index(name):
|
||||
if module_grouping is not None:
|
||||
try:
|
||||
return module_grouping.index(name)
|
||||
except ValueError:
|
||||
pass
|
||||
return -1
|
||||
|
||||
def module_grouping_heading(name):
|
||||
if module_grouping is not None:
|
||||
i = module_grouping_index(name) - 1
|
||||
if i >= 0 and type(module_grouping[i]) == tuple:
|
||||
return module_grouping[i]
|
||||
return None, None
|
||||
|
||||
def module_grouping_sort_key(name):
|
||||
return module_grouping_index(name)
|
||||
# done grouping support
|
||||
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
|
||||
fw = file.write
|
||||
|
||||
write_title(fw, "%s (%s)" % (title, module_name), "=")
|
||||
fw(title_string("%s (%s)" % (title, module_name), "="))
|
||||
|
||||
fw(".. module:: %s\n\n" % module_name)
|
||||
|
||||
@@ -685,7 +843,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
|
||||
fw("\n")
|
||||
else:
|
||||
print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
|
||||
BPY_LOGGER.debug("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
|
||||
continue
|
||||
|
||||
attribute_set.add(attribute)
|
||||
@@ -693,7 +851,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
del module_dir_value_type
|
||||
|
||||
# TODO, bpy_extras does this already, mathutils not.
|
||||
"""
|
||||
'''
|
||||
if submodules:
|
||||
fw("\n"
|
||||
"**********\n"
|
||||
@@ -704,10 +862,19 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
for attribute, submod in submodules:
|
||||
fw("* :mod:`%s.%s`\n" % (module_name, attribute))
|
||||
fw("\n")
|
||||
"""
|
||||
'''
|
||||
|
||||
if module_grouping is not None:
|
||||
classes.sort(key=lambda pair: module_grouping_sort_key(pair[0]))
|
||||
|
||||
# write collected classes now
|
||||
for (type_name, value) in classes:
|
||||
|
||||
if module_grouping is not None:
|
||||
heading, heading_char = module_grouping_heading(type_name)
|
||||
if heading:
|
||||
fw(title_string(heading, heading_char))
|
||||
|
||||
# May need to be its own function
|
||||
fw(".. class:: %s\n\n" % type_name)
|
||||
if value.__doc__:
|
||||
@@ -746,8 +913,7 @@ def pycontext2sphinx(basepath):
|
||||
filepath = os.path.join(basepath, "bpy.context.rst")
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
fw("Context Access (bpy.context)\n")
|
||||
fw("============================\n\n")
|
||||
fw(title_string("Context Access (bpy.context)", "="))
|
||||
fw(".. module:: bpy.context\n")
|
||||
fw("\n")
|
||||
fw("The context members available depend on the area of blender which is currently being accessed.\n")
|
||||
@@ -950,7 +1116,7 @@ def pyrna2sphinx(basepath):
|
||||
else:
|
||||
title = struct_id
|
||||
|
||||
write_title(fw, title, "=")
|
||||
fw(title_string(title, "="))
|
||||
|
||||
fw(".. module:: bpy.types\n\n")
|
||||
|
||||
@@ -1161,7 +1327,7 @@ def pyrna2sphinx(basepath):
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
|
||||
write_title(fw, class_name, "=")
|
||||
fw(title_string(class_name, "="))
|
||||
|
||||
fw(".. module:: bpy.types\n")
|
||||
fw("\n")
|
||||
@@ -1214,7 +1380,7 @@ def pyrna2sphinx(basepath):
|
||||
|
||||
title = "%s Operators" % op_module_name.replace("_", " ").title()
|
||||
|
||||
write_title(fw, title, "=")
|
||||
fw(title_string(title, "="))
|
||||
|
||||
fw(".. module:: bpy.ops.%s\n\n" % op_module_name)
|
||||
|
||||
@@ -1297,38 +1463,30 @@ def write_rst_contents(basepath):
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
|
||||
fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
|
||||
fw(" Blender Documentation contents\n")
|
||||
fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
|
||||
fw(title_string("Blender Documentation Contents", "%", double=True))
|
||||
fw("\n")
|
||||
fw("Welcome, this document is an API reference for Blender %s. built %s.\n" % (BLENDER_VERSION_DOTS, str(bpy.app.build_date, 'utf_8')))
|
||||
fw("Welcome, this document is an API reference for Blender %s, built %s.\n" % (BLENDER_VERSION_DOTS, BLENDER_DATE))
|
||||
fw("\n")
|
||||
|
||||
# fw("`A PDF version of this document is also available <blender_python_reference_%s.pdf>`_\n" % BLENDER_VERSION_PDF)
|
||||
fw("`A compressed ZIP file of this site is available <blender_python_reference_%s.zip>`_\n" % BLENDER_VERSION_PDF)
|
||||
# fw("`A PDF version of this document is also available <%s>`_\n" % BLENDER_PDF_FILENAME)
|
||||
fw("`A compressed ZIP file of this site is available <%s>`_\n" % BLENDER_ZIP_FILENAME)
|
||||
|
||||
fw("\n")
|
||||
|
||||
if not EXCLUDE_INFO_DOCS:
|
||||
fw("============================\n")
|
||||
fw("Blender/Python Documentation\n")
|
||||
fw("============================\n")
|
||||
fw("\n")
|
||||
fw("\n")
|
||||
fw(title_string("Blender/Python Documentation", "=", double=True))
|
||||
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n\n")
|
||||
for info, info_desc in INFO_DOCS:
|
||||
fw(" %s <%s>\n\n" % (info_desc, info))
|
||||
fw("\n")
|
||||
|
||||
fw("===================\n")
|
||||
fw("Application Modules\n")
|
||||
fw("===================\n")
|
||||
fw("\n")
|
||||
fw(title_string("Application Modules", "=", double=True))
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n\n")
|
||||
|
||||
app_modules = [
|
||||
app_modules = (
|
||||
"bpy.context", # note: not actually a module
|
||||
"bpy.data", # note: not actually a module
|
||||
"bpy.ops",
|
||||
@@ -1341,37 +1499,33 @@ def write_rst_contents(basepath):
|
||||
"bpy.app.handlers",
|
||||
|
||||
# C modules
|
||||
"bpy.props"
|
||||
]
|
||||
"bpy.props",
|
||||
)
|
||||
|
||||
for mod in app_modules:
|
||||
if mod not in EXCLUDE_MODULES:
|
||||
fw(" %s\n\n" % mod)
|
||||
|
||||
fw("==================\n")
|
||||
fw("Standalone Modules\n")
|
||||
fw("==================\n")
|
||||
fw("\n")
|
||||
fw(title_string("Standalone Modules", "=", double=True))
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n\n")
|
||||
|
||||
standalone_modules = [
|
||||
standalone_modules = (
|
||||
# mathutils
|
||||
"mathutils", "mathutils.geometry", "mathutils.noise",
|
||||
# misc
|
||||
"Freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
|
||||
# bmesh
|
||||
"bmesh", "bmesh.types", "bmesh.utils"
|
||||
]
|
||||
"bmesh", "bmesh.types", "bmesh.utils",
|
||||
)
|
||||
|
||||
for mod in standalone_modules:
|
||||
if mod not in EXCLUDE_MODULES:
|
||||
fw(" %s\n\n" % mod)
|
||||
|
||||
# game engine
|
||||
if "bge" not in EXCLUDE_MODULES:
|
||||
fw("===================\n")
|
||||
fw("Game Engine Modules\n")
|
||||
fw("===================\n")
|
||||
fw("\n")
|
||||
fw(title_string("Game Engine Modules", "=", double=True))
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n\n")
|
||||
fw(" bge.types.rst\n\n")
|
||||
@@ -1382,10 +1536,7 @@ def write_rst_contents(basepath):
|
||||
fw(" bge.constraints.rst\n\n")
|
||||
|
||||
# rna generated change log
|
||||
fw("========\n")
|
||||
fw("API Info\n")
|
||||
fw("========\n")
|
||||
fw("\n")
|
||||
fw(title_string("API Info", "=", double=True))
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n\n")
|
||||
fw(" change_log.rst\n\n")
|
||||
@@ -1421,7 +1572,7 @@ def write_rst_bpy(basepath):
|
||||
|
||||
title = ":mod:`bpy` --- Blender Python Module"
|
||||
|
||||
write_title(fw, title, "=")
|
||||
fw(title_string(title, "="))
|
||||
|
||||
fw(".. module:: bpy.types\n\n")
|
||||
file.close()
|
||||
@@ -1435,8 +1586,7 @@ def write_rst_types_index(basepath):
|
||||
filepath = os.path.join(basepath, "bpy.types.rst")
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
fw("Types (bpy.types)\n")
|
||||
fw("=================\n\n")
|
||||
fw(title_string("Types (bpy.types)", "="))
|
||||
fw(".. toctree::\n")
|
||||
fw(" :glob:\n\n")
|
||||
fw(" bpy.types.*\n\n")
|
||||
@@ -1451,8 +1601,7 @@ def write_rst_ops_index(basepath):
|
||||
filepath = os.path.join(basepath, "bpy.ops.rst")
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
fw("Operators (bpy.ops)\n")
|
||||
fw("===================\n\n")
|
||||
fw(title_string("Operators (bpy.ops)", "="))
|
||||
write_example_ref("", fw, "bpy.ops")
|
||||
fw(".. toctree::\n")
|
||||
fw(" :glob:\n\n")
|
||||
@@ -1470,8 +1619,7 @@ def write_rst_data(basepath):
|
||||
filepath = os.path.join(basepath, "bpy.data.rst")
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
fw("Data Access (bpy.data)\n")
|
||||
fw("======================\n\n")
|
||||
fw(title_string("Data Access (bpy.data)", "="))
|
||||
fw(".. module:: bpy\n")
|
||||
fw("\n")
|
||||
fw("This module is used for all blender/python access.\n")
|
||||
@@ -1536,6 +1684,9 @@ def copy_handwritten_rsts(basepath):
|
||||
"bge.constraints",
|
||||
"bgl", # "Blender OpenGl wrapper"
|
||||
"gpu", # "GPU Shader Module"
|
||||
|
||||
# includes...
|
||||
"include__bmesh",
|
||||
]
|
||||
for mod_name in handwritten_modules:
|
||||
if mod_name not in EXCLUDE_MODULES:
|
||||
@@ -1590,7 +1741,7 @@ def align_sphinx_in_to_sphinx_in_tmp():
|
||||
# remove deprecated files that have been removed
|
||||
for f in sorted(sphinx_in_files):
|
||||
if f not in sphinx_in_tmp_files:
|
||||
print("\tdeprecated: %s" % f)
|
||||
BPY_LOGGER.debug("\tdeprecated: %s" % f)
|
||||
os.remove(os.path.join(SPHINX_IN, f))
|
||||
|
||||
# freshen with new files.
|
||||
@@ -1604,53 +1755,142 @@ def align_sphinx_in_to_sphinx_in_tmp():
|
||||
do_copy = False
|
||||
|
||||
if do_copy:
|
||||
print("\tupdating: %s" % f)
|
||||
BPY_LOGGER.debug("\tupdating: %s" % f)
|
||||
shutil.copy(f_from, f_to)
|
||||
|
||||
|
||||
def refactor_sphinx_log(sphinx_logfile):
|
||||
refactored_log = []
|
||||
with open(sphinx_logfile, "r", encoding="utf-8") as original_logfile:
|
||||
lines = set(original_logfile.readlines())
|
||||
for line in lines:
|
||||
if 'warning' in line.lower() or 'error' in line.lower():
|
||||
line = line.strip().split(None, 2)
|
||||
if len(line) == 3:
|
||||
location, kind, msg = line
|
||||
location = os.path.relpath(location, start=SPHINX_IN)
|
||||
refactored_log.append((kind, location, msg))
|
||||
with open(sphinx_logfile, "w", encoding="utf-8") as refactored_logfile:
|
||||
for log in sorted(refactored_log):
|
||||
refactored_logfile.write("%-12s %s\n %s\n" % log)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# dirs preparation
|
||||
# eventually, create the dirs
|
||||
for dir_path in [ARGS.output_dir, SPHINX_IN]:
|
||||
if not os.path.exists(dir_path):
|
||||
os.mkdir(dir_path)
|
||||
|
||||
# eventually, log in files
|
||||
if ARGS.log:
|
||||
bpy_logfile = os.path.join(ARGS.output_dir, ".bpy.log")
|
||||
bpy_logfilehandler = logging.FileHandler(bpy_logfile, mode="w")
|
||||
bpy_logfilehandler.setLevel(logging.DEBUG)
|
||||
BPY_LOGGER.addHandler(bpy_logfilehandler)
|
||||
|
||||
# using a FileHandler seems to disable the stdout, so we add a StreamHandler
|
||||
bpy_log_stdout_handler = logging.StreamHandler(stream=sys.stdout)
|
||||
bpy_log_stdout_handler.setLevel(logging.DEBUG)
|
||||
BPY_LOGGER.addHandler(bpy_log_stdout_handler)
|
||||
|
||||
# in case of out-of-source build, copy the needed dirs
|
||||
if ARGS.output_dir != SCRIPT_DIR:
|
||||
# examples dir
|
||||
examples_dir_copy = os.path.join(ARGS.output_dir, "examples")
|
||||
if os.path.exists(examples_dir_copy):
|
||||
shutil.rmtree(examples_dir_copy, True)
|
||||
shutil.copytree(EXAMPLES_DIR,
|
||||
examples_dir_copy,
|
||||
ignore=shutil.ignore_patterns(*(".svn",)),
|
||||
copy_function=shutil.copy)
|
||||
|
||||
# eventually, copy the theme dir
|
||||
if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
|
||||
if os.path.exists(SPHINX_THEME_DIR):
|
||||
shutil.rmtree(SPHINX_THEME_DIR, True)
|
||||
shutil.copytree(SPHINX_THEME_SVN_DIR,
|
||||
SPHINX_THEME_DIR,
|
||||
ignore=shutil.ignore_patterns(*(".svn",)),
|
||||
copy_function=shutil.copy)
|
||||
|
||||
# dump the api in rst files
|
||||
if os.path.exists(SPHINX_IN_TMP):
|
||||
shutil.rmtree(SPHINX_IN_TMP, True)
|
||||
|
||||
rna2sphinx(SPHINX_IN_TMP)
|
||||
|
||||
if ARGS.full_rebuild:
|
||||
# only for full updates
|
||||
shutil.rmtree(SPHINX_IN, True)
|
||||
shutil.rmtree(SPHINX_OUT, True)
|
||||
rna2sphinx(SPHINX_IN_TMP)
|
||||
shutil.copytree(SPHINX_IN_TMP,
|
||||
SPHINX_IN,
|
||||
copy_function=shutil.copy)
|
||||
if ARGS.sphinx_build and os.path.exists(SPHINX_OUT):
|
||||
shutil.rmtree(SPHINX_OUT, True)
|
||||
if ARGS.sphinx_build_pdf and os.path.exists(SPHINX_OUT_PDF):
|
||||
shutil.rmtree(SPHINX_OUT_PDF, True)
|
||||
else:
|
||||
# write here, then move
|
||||
shutil.rmtree(SPHINX_IN_TMP, True)
|
||||
rna2sphinx(SPHINX_IN_TMP)
|
||||
# move changed files in SPHINX_IN
|
||||
align_sphinx_in_to_sphinx_in_tmp()
|
||||
|
||||
# report which example files weren't used
|
||||
EXAMPLE_SET_UNUSED = EXAMPLE_SET - EXAMPLE_SET_USED
|
||||
if EXAMPLE_SET_UNUSED:
|
||||
print("\nUnused examples found in '%s'..." % EXAMPLES_DIR)
|
||||
for f in EXAMPLE_SET_UNUSED:
|
||||
print(" %s.py" % f)
|
||||
print(" %d total\n" % len(EXAMPLE_SET_UNUSED))
|
||||
BPY_LOGGER.debug("\nUnused examples found in '%s'..." % EXAMPLES_DIR)
|
||||
for f in sorted(EXAMPLE_SET_UNUSED):
|
||||
BPY_LOGGER.debug(" %s.py" % f)
|
||||
BPY_LOGGER.debug(" %d total\n" % len(EXAMPLE_SET_UNUSED))
|
||||
|
||||
# eventually, copy the theme in the output directory
|
||||
if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
|
||||
if not os.path.exists(SPHINX_THEME_DIR):
|
||||
shutil.copytree(SPHINX_THEME_SVN_DIR,
|
||||
SPHINX_THEME_DIR,
|
||||
copy_function=shutil.copy)
|
||||
|
||||
# eventually, build the docs
|
||||
# eventually, build the html docs
|
||||
if ARGS.sphinx_build:
|
||||
import subprocess
|
||||
sphinx_build_command = "sphinx-build %s %s" % (SPHINX_IN, SPHINX_OUT)
|
||||
print ('\n%s\n' % sphinx_build_command)
|
||||
subprocess.call(sphinx_build_command, shell=True)
|
||||
subprocess.call(SPHINX_BUILD)
|
||||
|
||||
# sphinx-build log cleanup+sort
|
||||
if ARGS.log:
|
||||
if os.stat(SPHINX_BUILD_LOG).st_size:
|
||||
refactor_sphinx_log(SPHINX_BUILD_LOG)
|
||||
|
||||
# eventually, build the pdf docs
|
||||
if ARGS.sphinx_build_pdf:
|
||||
import subprocess
|
||||
subprocess.call(SPHINX_BUILD_PDF)
|
||||
subprocess.call(SPHINX_MAKE_PDF, stdout=SPHINX_MAKE_PDF_STDOUT)
|
||||
|
||||
# sphinx-build log cleanup+sort
|
||||
if ARGS.log:
|
||||
if os.stat(SPHINX_BUILD_PDF_LOG).st_size:
|
||||
refactor_sphinx_log(SPHINX_BUILD_PDF_LOG)
|
||||
|
||||
# eventually, prepare the dir to be deployed online (REFERENCE_PATH)
|
||||
if ARGS.pack_reference:
|
||||
|
||||
if ARGS.sphinx_build:
|
||||
# delete REFERENCE_PATH
|
||||
if os.path.exists(REFERENCE_PATH):
|
||||
shutil.rmtree(REFERENCE_PATH, True)
|
||||
|
||||
# copy SPHINX_OUT to the REFERENCE_PATH
|
||||
ignores = ('.doctrees', 'objects.inv', '.buildinfo')
|
||||
shutil.copytree(SPHINX_OUT,
|
||||
REFERENCE_PATH,
|
||||
ignore=shutil.ignore_patterns(*ignores))
|
||||
shutil.copy(os.path.join(REFERENCE_PATH, "contents.html"),
|
||||
os.path.join(REFERENCE_PATH, "index.html"))
|
||||
|
||||
# zip REFERENCE_PATH
|
||||
basename = os.path.join(ARGS.output_dir, REFERENCE_NAME)
|
||||
tmp_path = shutil.make_archive(basename, 'zip',
|
||||
root_dir=ARGS.output_dir,
|
||||
base_dir=REFERENCE_NAME)
|
||||
final_path = os.path.join(REFERENCE_PATH, BLENDER_ZIP_FILENAME)
|
||||
os.rename(tmp_path, final_path)
|
||||
|
||||
if ARGS.sphinx_build_pdf:
|
||||
# copy the pdf to REFERENCE_PATH
|
||||
shutil.copy(os.path.join(SPHINX_OUT_PDF, "contents.pdf"),
|
||||
os.path.join(REFERENCE_PATH, BLENDER_PDF_FILENAME))
|
||||
|
||||
sys.exit()
|
||||
|
||||
|
Reference in New Issue
Block a user