Add Chromium-only Blender WebEngine parity work
This commit is contained in:
461
blender-5.2.0/doc/blender_file_format/BlendFileDnaExporter_25.py
Executable file
461
blender-5.2.0/doc/blender_file_format/BlendFileDnaExporter_25.py
Executable file
@@ -0,0 +1,461 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2022 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
######################################################
|
||||
#
|
||||
# Name:
|
||||
# dna.py
|
||||
#
|
||||
# Description:
|
||||
# Creates a browsable DNA output to HTML.
|
||||
#
|
||||
# Author:
|
||||
# Jeroen Bakker
|
||||
#
|
||||
# Version:
|
||||
# v0.1 (12-05-2009) - migration of original source code to Python.
|
||||
# Added code to support blender 2.5 branch
|
||||
# v0.2 (25-05-2009) - integrated with BlendFileReader.py
|
||||
#
|
||||
# Input:
|
||||
# blender build executable
|
||||
#
|
||||
# Output:
|
||||
# dna.html
|
||||
# dna.css (will only be created when not existing)
|
||||
#
|
||||
# Startup:
|
||||
# ./blender -P BlendFileDnaExporter.py
|
||||
#
|
||||
# Process:
|
||||
# 1: write blend file with SDNA info
|
||||
# 2: read blend header from blend file
|
||||
# 3: seek DNA1 file-block
|
||||
# 4: read dna record from blend file
|
||||
# 5: close and eventually delete temp blend file
|
||||
# 6: export dna to html and css
|
||||
# 7: quit blender
|
||||
#
|
||||
######################################################
|
||||
|
||||
import sys
|
||||
from string import Template # strings completion
|
||||
|
||||
|
||||
# logs
|
||||
import logging
|
||||
log = logging.getLogger("BlendFileDnaExporter")
|
||||
|
||||
if '--dna-debug' in sys.argv:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
class DNACatalogHTML:
|
||||
'''
|
||||
DNACatalog is a catalog of all information in the DNA1 file-block
|
||||
'''
|
||||
|
||||
def __init__(self, catalog, bpy_module=None):
|
||||
self.Catalog = catalog
|
||||
self.bpy = bpy_module
|
||||
|
||||
def WriteToHTML(self, handle):
|
||||
|
||||
dna_html_template = """
|
||||
<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="dna.css" media="screen, print" />
|
||||
<meta http-equiv="Content-Type" content="text/html"; charset="ISO-8859-1" />
|
||||
<title>The mystery of the blend</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class=title>
|
||||
Blender ${version}<br/>
|
||||
Internal SDNA structures
|
||||
</div>
|
||||
Architecture: ${bitness} ${endianness}<br/>
|
||||
Build revision: <a href="https://svn.blender.org/svnroot/bf-blender/!svn/bc/${revision}/trunk/">${revision}</a><br/>
|
||||
File format reference: <a href="mystery_of_the_blend.html">The mystery of the blend</a> by Jeroen Bakker<br/>
|
||||
<h1>Index of blender structures</h1>
|
||||
<ul class=multicolumn>
|
||||
${structs_list}
|
||||
</ul>
|
||||
${structs_content}
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
header = self.Catalog.Header
|
||||
bpy = self.bpy
|
||||
|
||||
# ${version} and ${revision}
|
||||
if bpy:
|
||||
version = '.'.join(map(str, bpy.app.version))
|
||||
revision = bpy.app.build_hash
|
||||
else:
|
||||
version = str(header.Version)
|
||||
revision = 'Unknown'
|
||||
|
||||
# ${bitness}
|
||||
if header.PointerSize == 8:
|
||||
bitness = '64 bit'
|
||||
else:
|
||||
bitness = '32 bit'
|
||||
|
||||
# ${endianness}
|
||||
if header.LittleEndianness:
|
||||
endianess = 'Little endianness'
|
||||
else:
|
||||
endianess = 'Big endianness'
|
||||
|
||||
# ${structs_list}
|
||||
log.debug("Creating structs index")
|
||||
structs_list = ''
|
||||
list_item = '<li class="multicolumn">({0}) <a href="#{1}">{1}</a></li>\n'
|
||||
structureIndex = 0
|
||||
for structure in self.Catalog.Structs:
|
||||
structs_list += list_item.format(structureIndex, structure.Type.Name)
|
||||
structureIndex += 1
|
||||
|
||||
# ${structs_content}
|
||||
log.debug("Creating structs content")
|
||||
structs_content = ''
|
||||
for structure in self.Catalog.Structs:
|
||||
log.debug(structure.Type.Name)
|
||||
structs_content += self.Structure(structure)
|
||||
|
||||
d = dict(
|
||||
version=version,
|
||||
revision=revision,
|
||||
bitness=bitness,
|
||||
endianness=endianess,
|
||||
structs_list=structs_list,
|
||||
structs_content=structs_content
|
||||
)
|
||||
|
||||
dna_html = Template(dna_html_template).substitute(d)
|
||||
dna_html = self.format(dna_html)
|
||||
handle.write(dna_html)
|
||||
|
||||
def Structure(self, structure):
|
||||
struct_table_template = """
|
||||
<table><a name="${struct_name}"></a>
|
||||
<caption><a href="#${struct_name}">${struct_name}</a></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>reference</th>
|
||||
<th>structure</th>
|
||||
<th>type</th>
|
||||
<th>name</th>
|
||||
<th>offset</th>
|
||||
<th>size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${fields}
|
||||
</tbody>
|
||||
</table>
|
||||
<label>Total size: ${size} bytes</label><br/>
|
||||
<label>(<a href="#top">top</a>)</label><br/>"""
|
||||
|
||||
d = dict(
|
||||
struct_name=structure.Type.Name,
|
||||
fields=self.StructureFields(structure, None, 0),
|
||||
size=str(structure.Type.Size)
|
||||
)
|
||||
|
||||
struct_table = Template(struct_table_template).substitute(d)
|
||||
return struct_table
|
||||
|
||||
def StructureFields(self, structure, parentReference, offset):
|
||||
fields = ''
|
||||
for field in structure.Fields:
|
||||
fields += self.StructureField(field, structure, parentReference, offset)
|
||||
offset += field.Size(self.Catalog.Header)
|
||||
return fields
|
||||
|
||||
def StructureField(self, field, structure, parentReference, offset):
|
||||
structure_field_template = """
|
||||
<tr>
|
||||
<td>${reference}</td>
|
||||
<td>${struct}</td>
|
||||
<td>${type}</td>
|
||||
<td>${name}</td>
|
||||
<td>${offset}</td>
|
||||
<td>${size}</td>
|
||||
</tr>"""
|
||||
|
||||
if field.Type.Structure is None or field.Name.IsPointer():
|
||||
|
||||
# ${reference}
|
||||
reference = field.Name.AsReference(parentReference)
|
||||
|
||||
# ${struct}
|
||||
if parentReference is not None:
|
||||
struct = '<a href="#{0}">{0}</a>'.format(structure.Type.Name)
|
||||
else:
|
||||
struct = structure.Type.Name
|
||||
|
||||
# ${type}
|
||||
type = field.Type.Name
|
||||
|
||||
# ${name}
|
||||
name = field.Name.Name
|
||||
|
||||
# ${offset}
|
||||
# offset already set
|
||||
|
||||
# ${size}
|
||||
size = field.Size(self.Catalog.Header)
|
||||
|
||||
d = dict(
|
||||
reference=reference,
|
||||
struct=struct,
|
||||
type=type,
|
||||
name=name,
|
||||
offset=offset,
|
||||
size=size
|
||||
)
|
||||
|
||||
structure_field = Template(structure_field_template).substitute(d)
|
||||
|
||||
elif field.Type.Structure is not None:
|
||||
reference = field.Name.AsReference(parentReference)
|
||||
structure_field = self.StructureFields(field.Type.Structure, reference, offset)
|
||||
|
||||
return structure_field
|
||||
|
||||
def indent(self, input, dent):
|
||||
output = ''
|
||||
if dent < 0:
|
||||
for line in input.split('\n'):
|
||||
dent = abs(dent)
|
||||
output += line[dent:] + '\n' # unindent of a desired amount
|
||||
elif dent == 0:
|
||||
for line in input.split('\n'):
|
||||
output += line.lstrip() + '\n' # remove indentation completely
|
||||
elif dent > 0:
|
||||
for line in input.split('\n'):
|
||||
output += ' ' * dent + line + '\n'
|
||||
return output
|
||||
|
||||
def format(self, input):
|
||||
diff = {
|
||||
'\n<!DOCTYPE': '<!DOCTYPE',
|
||||
'\n</ul>': '</ul>',
|
||||
'<a name': '\n<a name',
|
||||
'<tr>\n': '<tr>',
|
||||
'<tr>': ' <tr>',
|
||||
'</th>\n': '</th>',
|
||||
'</td>\n': '</td>',
|
||||
'<tbody>\n': '<tbody>'
|
||||
}
|
||||
output = self.indent(input, 0)
|
||||
for key, value in diff.items():
|
||||
output = output.replace(key, value)
|
||||
return output
|
||||
|
||||
def WriteToCSS(self, handle):
|
||||
'''
|
||||
Write the Cascading style-sheet template to the handle
|
||||
It is expected that the handle is a File-handle.
|
||||
'''
|
||||
css = """
|
||||
@CHARSET "ISO-8859-1";
|
||||
|
||||
body {
|
||||
font-family: verdana;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.title {
|
||||
font-size: large;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
background-color: #D3D3D3;
|
||||
color:#404040;
|
||||
margin-right: 3%;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
h1:hover{
|
||||
background-color: #EBEBEB;
|
||||
}
|
||||
|
||||
h3 {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
table {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000000;
|
||||
border-collapse: collapse;
|
||||
width: 94%;
|
||||
margin: 20px 3% 10px;
|
||||
}
|
||||
|
||||
caption {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #000000;
|
||||
color:#ffffff;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
}
|
||||
|
||||
tr {
|
||||
}
|
||||
|
||||
td {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #a0a0a0;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
}
|
||||
|
||||
label {
|
||||
float:right;
|
||||
margin-right: 3%;
|
||||
}
|
||||
|
||||
ul.multicolumn {
|
||||
list-style:none;
|
||||
float:left;
|
||||
padding-right:0px;
|
||||
margin-right:0px;
|
||||
}
|
||||
|
||||
li.multicolumn {
|
||||
float:left;
|
||||
width:200px;
|
||||
margin-right:0px;
|
||||
}
|
||||
|
||||
a {
|
||||
color:#a000a0;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color:#a000a0;
|
||||
text-decoration:underline;
|
||||
}
|
||||
"""
|
||||
|
||||
css = self.indent(css, 0)
|
||||
|
||||
handle.write(css)
|
||||
|
||||
|
||||
def usage():
|
||||
print("\nUsage: \n\tblender2.5 --background --python BlendFileDnaExporter_25.py [-- [options]]")
|
||||
print("Options:")
|
||||
print("\t--dna-keep-blend: doesn't delete the produced blend file DNA export to html")
|
||||
print("\t--dna-debug: sets the logging level to DEBUG (lots of additional info)")
|
||||
print("\t--dna-versioned saves version information in the html and blend filenames")
|
||||
print("\t--dna-overwrite-css overwrite dna.css, useful when modifying css in the script")
|
||||
print("Examples:")
|
||||
print("\tdefault: % blender2.5 --background --python BlendFileDnaExporter_25.py")
|
||||
print("\twith options: % blender2.5 --background --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
|
||||
|
||||
|
||||
######################################################
|
||||
# Main
|
||||
######################################################
|
||||
|
||||
def main():
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
try:
|
||||
bpy = __import__('bpy')
|
||||
|
||||
# Files
|
||||
if '--dna-versioned' in sys.argv:
|
||||
blender_version = '_'.join(map(str, bpy.app.version))
|
||||
filename = 'dna-{0}-{1}_endian-{2}-{3}'.format(sys.arch, sys.byteorder, blender_version, bpy.app.build_hash)
|
||||
else:
|
||||
filename = 'dna'
|
||||
dir = os.path.dirname(__file__)
|
||||
Path_Blend = os.path.join(dir, filename + '.blend') # temporary blend file
|
||||
Path_HTML = os.path.join(dir, filename + '.html') # output html file
|
||||
Path_CSS = os.path.join(dir, 'dna.css') # output css file
|
||||
|
||||
# create a blend file for dna parsing
|
||||
if not os.path.exists(Path_Blend):
|
||||
log.info("1: write temp blend file with SDNA info")
|
||||
log.info(" saving to: " + Path_Blend)
|
||||
try:
|
||||
bpy.ops.wm.save_as_mainfile(filepath=Path_Blend, copy=True, compress=False)
|
||||
except Exception:
|
||||
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
|
||||
return
|
||||
else:
|
||||
log.info("1: found blend file with SDNA info")
|
||||
log.info(" " + Path_Blend)
|
||||
|
||||
# read blend header from blend file
|
||||
log.info("2: read file:")
|
||||
|
||||
if dir not in sys.path:
|
||||
sys.path.append(dir)
|
||||
import BlendFileReader
|
||||
|
||||
handle = BlendFileReader.openBlendFile(Path_Blend)
|
||||
blendfile = BlendFileReader.BlendFile(handle)
|
||||
catalog = DNACatalogHTML(blendfile.Catalog, bpy)
|
||||
|
||||
# close temp file
|
||||
handle.close()
|
||||
|
||||
# deleting or not?
|
||||
if '--dna-keep-blend' in sys.argv:
|
||||
# Keep the blend, useful for studying HEX-dumps.
|
||||
log.info("5: closing blend file:")
|
||||
log.info(" {0}".format(Path_Blend))
|
||||
else:
|
||||
# delete the blend
|
||||
log.info("5: close and delete temp blend:")
|
||||
log.info(" {0}".format(Path_Blend))
|
||||
os.remove(Path_Blend)
|
||||
|
||||
# export dna to xhtml
|
||||
log.info("6: export sdna to xhtml file: {!r}".format(Path_HTML))
|
||||
handleHTML = open(Path_HTML, "w")
|
||||
catalog.WriteToHTML(handleHTML)
|
||||
handleHTML.close()
|
||||
|
||||
# only write the css when doesn't exist or at explicit request
|
||||
if not os.path.exists(Path_CSS) or '--dna-overwrite-css' in sys.argv:
|
||||
handleCSS = open(Path_CSS, "w")
|
||||
catalog.WriteToCSS(handleCSS)
|
||||
handleCSS.close()
|
||||
|
||||
# quit blender
|
||||
if not bpy.app.background:
|
||||
log.info("7: quit blender")
|
||||
bpy.ops.wm.exit_blender()
|
||||
|
||||
except ImportError:
|
||||
log.warning(" skipping, not running in Blender")
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
431
blender-5.2.0/doc/blender_file_format/BlendFileReader.py
Normal file
431
blender-5.2.0/doc/blender_file_format/BlendFileReader.py
Normal file
@@ -0,0 +1,431 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
######################################################
|
||||
# Importing modules
|
||||
######################################################
|
||||
|
||||
import os
|
||||
import struct
|
||||
import gzip
|
||||
import tempfile
|
||||
|
||||
import logging
|
||||
log = logging.getLogger("BlendFileReader")
|
||||
|
||||
######################################################
|
||||
# module global routines
|
||||
######################################################
|
||||
|
||||
|
||||
def ReadString(handle, length):
|
||||
'''
|
||||
ReadString reads a String of given length or a zero terminating String
|
||||
from a file handle
|
||||
'''
|
||||
if length != 0:
|
||||
return handle.read(length).decode()
|
||||
else:
|
||||
# length == 0 means we want a zero terminating string
|
||||
result = ""
|
||||
s = ReadString(handle, 1)
|
||||
while s != "\0":
|
||||
result += s
|
||||
s = ReadString(handle, 1)
|
||||
return result
|
||||
|
||||
|
||||
def Read(type, handle, fileheader):
|
||||
'''
|
||||
Reads the chosen type from a file handle
|
||||
'''
|
||||
def unpacked_bytes(type_char, size):
|
||||
return struct.unpack(fileheader.StructPre + type_char, handle.read(size))[0]
|
||||
|
||||
if type == 'ushort':
|
||||
return unpacked_bytes("H", 2) # unsigned short
|
||||
elif type == 'short':
|
||||
return unpacked_bytes("h", 2) # short
|
||||
elif type == 'uint':
|
||||
return unpacked_bytes("I", 4) # unsigned int
|
||||
elif type == 'int':
|
||||
return unpacked_bytes("i", 4) # int
|
||||
elif type == 'float':
|
||||
return unpacked_bytes("f", 4) # float
|
||||
elif type == 'ulong':
|
||||
return unpacked_bytes("Q", 8) # unsigned long
|
||||
elif type == 'pointer':
|
||||
# The pointersize is given by the header (BlendFileHeader).
|
||||
if fileheader.PointerSize == 4:
|
||||
return Read('uint', handle, fileheader)
|
||||
if fileheader.PointerSize == 8:
|
||||
return Read('ulong', handle, fileheader)
|
||||
|
||||
|
||||
def openBlendFile(filename):
|
||||
'''
|
||||
Open a filename, determine if the file is compressed and returns a handle
|
||||
'''
|
||||
handle = open(filename, 'rb')
|
||||
magic = ReadString(handle, 7)
|
||||
if magic in {"BLENDER", "BULLETf"}:
|
||||
log.debug("normal blendfile detected")
|
||||
handle.seek(0, os.SEEK_SET)
|
||||
return handle
|
||||
else:
|
||||
log.debug("gzip blendfile detected?")
|
||||
handle.close()
|
||||
log.debug("decompressing started")
|
||||
fs = gzip.open(filename, "rb")
|
||||
handle = tempfile.TemporaryFile()
|
||||
data = fs.read(1024 * 1024)
|
||||
while data:
|
||||
handle.write(data)
|
||||
data = fs.read(1024 * 1024)
|
||||
log.debug("decompressing finished")
|
||||
fs.close()
|
||||
log.debug("resetting decompressed file")
|
||||
handle.seek(0, os.SEEK_SET)
|
||||
return handle
|
||||
|
||||
|
||||
def Align(handle):
|
||||
'''
|
||||
Aligns the file-handle on 4 bytes
|
||||
'''
|
||||
offset = handle.tell()
|
||||
trim = offset % 4
|
||||
if trim != 0:
|
||||
handle.seek(4 - trim, os.SEEK_CUR)
|
||||
|
||||
|
||||
######################################################
|
||||
# module classes
|
||||
######################################################
|
||||
|
||||
class BlendFile:
|
||||
'''
|
||||
Reads a blend-file and store the header, all the file-blocks, and catalog
|
||||
structs found in the DNA file-block
|
||||
|
||||
- BlendFile.Header (BlendFileHeader instance)
|
||||
- BlendFile.Blocks (list of BlendFileBlock instances)
|
||||
- BlendFile.Catalog (DNACatalog instance)
|
||||
'''
|
||||
|
||||
def __init__(self, handle):
|
||||
log.debug("initializing reading blend-file")
|
||||
self.Header = BlendFileHeader(handle)
|
||||
self.Blocks = []
|
||||
fileblock = BlendFileBlock(handle, self)
|
||||
found_dna_block = False
|
||||
while not found_dna_block:
|
||||
if fileblock.Header.Code in {"DNA1", "SDNA"}:
|
||||
self.Catalog = DNACatalog(self.Header, handle)
|
||||
found_dna_block = True
|
||||
else:
|
||||
fileblock.Header.skip(handle)
|
||||
|
||||
self.Blocks.append(fileblock)
|
||||
fileblock = BlendFileBlock(handle, self)
|
||||
|
||||
# appending last fileblock, "ENDB"
|
||||
self.Blocks.append(fileblock)
|
||||
|
||||
# seems unused?
|
||||
"""
|
||||
def FindBlendFileBlocksWithCode(self, code):
|
||||
#result = []
|
||||
#for block in self.Blocks:
|
||||
#if block.Header.Code.startswith(code) or block.Header.Code.endswith(code):
|
||||
#result.append(block)
|
||||
#return result
|
||||
"""
|
||||
|
||||
|
||||
class BlendFileHeader:
|
||||
'''
|
||||
BlendFileHeader allocates the first 12 bytes of a blend file.
|
||||
It contains information about the hardware architecture.
|
||||
Header example: BLENDER_v254
|
||||
|
||||
BlendFileHeader.Magic (str)
|
||||
BlendFileHeader.PointerSize (int)
|
||||
BlendFileHeader.LittleEndianness (bool)
|
||||
BlendFileHeader.StructPre (str) see http://docs.python.org/py3k/library/struct.html#byte-order-size-and-alignment
|
||||
BlendFileHeader.Version (int)
|
||||
'''
|
||||
|
||||
def __init__(self, handle):
|
||||
log.debug("reading blend-file-header")
|
||||
|
||||
self.Magic = ReadString(handle, 7)
|
||||
log.debug(self.Magic)
|
||||
|
||||
pointersize = ReadString(handle, 1)
|
||||
log.debug(pointersize)
|
||||
if pointersize == "-":
|
||||
self.PointerSize = 8
|
||||
if pointersize == "_":
|
||||
self.PointerSize = 4
|
||||
|
||||
endianness = ReadString(handle, 1)
|
||||
log.debug(endianness)
|
||||
if endianness == "v":
|
||||
self.LittleEndianness = True
|
||||
self.StructPre = "<"
|
||||
if endianness == "V":
|
||||
self.LittleEndianness = False
|
||||
self.StructPre = ">"
|
||||
|
||||
version = ReadString(handle, 3)
|
||||
log.debug(version)
|
||||
self.Version = int(version)
|
||||
|
||||
log.debug("{0} {1} {2} {3}".format(self.Magic, self.PointerSize, self.LittleEndianness, version))
|
||||
|
||||
|
||||
class BlendFileBlock:
|
||||
'''
|
||||
BlendFileBlock.File (BlendFile)
|
||||
BlendFileBlock.Header (FileBlockHeader)
|
||||
'''
|
||||
|
||||
def __init__(self, handle, blendfile):
|
||||
self.File = blendfile
|
||||
self.Header = FileBlockHeader(handle, blendfile.Header)
|
||||
|
||||
def Get(self, handle, path):
|
||||
log.debug("find dna structure")
|
||||
dnaIndex = self.Header.SDNAIndex
|
||||
dnaStruct = self.File.Catalog.Structs[dnaIndex]
|
||||
log.debug("found " + dnaStruct.Type.Name)
|
||||
handle.seek(self.Header.FileOffset, os.SEEK_SET)
|
||||
return dnaStruct.GetField(self.File.Header, handle, path)
|
||||
|
||||
|
||||
class FileBlockHeader:
|
||||
'''
|
||||
FileBlockHeader contains the information in a file-block-header.
|
||||
The class is needed for searching to the correct file-block (containing Code: DNA1)
|
||||
|
||||
Code (str)
|
||||
Size (int)
|
||||
OldAddress (pointer)
|
||||
SDNAIndex (int)
|
||||
Count (int)
|
||||
FileOffset (= file pointer of data-block)
|
||||
'''
|
||||
|
||||
def __init__(self, handle, fileheader):
|
||||
self.Code = ReadString(handle, 4).strip()
|
||||
if self.Code != "ENDB":
|
||||
self.Size = Read('uint', handle, fileheader)
|
||||
self.OldAddress = Read('pointer', handle, fileheader)
|
||||
self.SDNAIndex = Read('uint', handle, fileheader)
|
||||
self.Count = Read('uint', handle, fileheader)
|
||||
self.FileOffset = handle.tell()
|
||||
else:
|
||||
self.Size = Read('uint', handle, fileheader)
|
||||
self.OldAddress = 0
|
||||
self.SDNAIndex = 0
|
||||
self.Count = 0
|
||||
self.FileOffset = handle.tell()
|
||||
# self.Code += ' ' * (4 - len(self.Code))
|
||||
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
|
||||
|
||||
def skip(self, handle):
|
||||
handle.read(self.Size)
|
||||
|
||||
|
||||
class DNACatalog:
|
||||
'''
|
||||
DNACatalog is a catalog of all information in the DNA1 file-block
|
||||
|
||||
Header = None
|
||||
Names = None
|
||||
Types = None
|
||||
Structs = None
|
||||
'''
|
||||
|
||||
def __init__(self, fileheader, handle):
|
||||
log.debug("building DNA catalog")
|
||||
self.Names = []
|
||||
self.Types = []
|
||||
self.Structs = []
|
||||
self.Header = fileheader
|
||||
|
||||
SDNA = ReadString(handle, 4)
|
||||
|
||||
# names
|
||||
NAME = ReadString(handle, 4)
|
||||
numberOfNames = Read('uint', handle, fileheader)
|
||||
log.debug("building #{0} names".format(numberOfNames))
|
||||
for i in range(numberOfNames):
|
||||
name = ReadString(handle, 0)
|
||||
self.Names.append(DNAName(name))
|
||||
Align(handle)
|
||||
|
||||
# types
|
||||
TYPE = ReadString(handle, 4)
|
||||
numberOfTypes = Read('uint', handle, fileheader)
|
||||
log.debug("building #{0} types".format(numberOfTypes))
|
||||
for i in range(numberOfTypes):
|
||||
type = ReadString(handle, 0)
|
||||
self.Types.append(DNAType(type))
|
||||
Align(handle)
|
||||
|
||||
# type lengths
|
||||
TLEN = ReadString(handle, 4)
|
||||
log.debug("building #{0} type-lengths".format(numberOfTypes))
|
||||
for i in range(numberOfTypes):
|
||||
length = Read('ushort', handle, fileheader)
|
||||
self.Types[i].Size = length
|
||||
Align(handle)
|
||||
|
||||
# structs
|
||||
STRC = ReadString(handle, 4)
|
||||
numberOfStructures = Read('uint', handle, fileheader)
|
||||
log.debug("building #{0} structures".format(numberOfStructures))
|
||||
for structureIndex in range(numberOfStructures):
|
||||
type = Read('ushort', handle, fileheader)
|
||||
Type = self.Types[type]
|
||||
structure = DNAStructure(Type)
|
||||
self.Structs.append(structure)
|
||||
|
||||
numberOfFields = Read('ushort', handle, fileheader)
|
||||
for fieldIndex in range(numberOfFields):
|
||||
fTypeIndex = Read('ushort', handle, fileheader)
|
||||
fNameIndex = Read('ushort', handle, fileheader)
|
||||
fType = self.Types[fTypeIndex]
|
||||
fName = self.Names[fNameIndex]
|
||||
structure.Fields.append(DNAField(fType, fName))
|
||||
|
||||
|
||||
class DNAName:
|
||||
'''
|
||||
DNAName is a C-type name stored in the DNA.
|
||||
|
||||
Name = str
|
||||
'''
|
||||
|
||||
def __init__(self, name):
|
||||
self.Name = name
|
||||
|
||||
def AsReference(self, parent):
|
||||
if parent is None:
|
||||
result = ""
|
||||
else:
|
||||
result = parent + "."
|
||||
|
||||
result = result + self.ShortName()
|
||||
return result
|
||||
|
||||
def ShortName(self):
|
||||
result = self.Name
|
||||
result = result.replace("*", "")
|
||||
result = result.replace("(", "")
|
||||
result = result.replace(")", "")
|
||||
Index = result.find("[")
|
||||
if Index != -1:
|
||||
result = result[0:Index]
|
||||
return result
|
||||
|
||||
def IsPointer(self):
|
||||
return self.Name.find("*") > -1
|
||||
|
||||
def IsMethodPointer(self):
|
||||
return self.Name.find("(*") > -1
|
||||
|
||||
def ArraySize(self):
|
||||
result = 1
|
||||
Temp = self.Name
|
||||
Index = Temp.find("[")
|
||||
|
||||
while Index != -1:
|
||||
Index2 = Temp.find("]")
|
||||
result *= int(Temp[Index + 1:Index2])
|
||||
Temp = Temp[Index2 + 1:]
|
||||
Index = Temp.find("[")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class DNAType:
|
||||
'''
|
||||
DNAType is a C-type stored in the DNA
|
||||
|
||||
Name = str
|
||||
Size = int
|
||||
Structure = DNAStructure
|
||||
'''
|
||||
|
||||
def __init__(self, aName):
|
||||
self.Name = aName
|
||||
self.Structure = None
|
||||
|
||||
|
||||
class DNAStructure:
|
||||
'''
|
||||
DNAType is a C-type structure stored in the DNA
|
||||
|
||||
Type = DNAType
|
||||
Fields = [DNAField]
|
||||
'''
|
||||
|
||||
def __init__(self, aType):
|
||||
self.Type = aType
|
||||
self.Type.Structure = self
|
||||
self.Fields = []
|
||||
|
||||
def GetField(self, header, handle, path):
|
||||
splitted = path.partition(".")
|
||||
name = splitted[0]
|
||||
rest = splitted[2]
|
||||
offset = 0
|
||||
for field in self.Fields:
|
||||
if field.Name.ShortName() == name:
|
||||
log.debug("found " + name + "@" + str(offset))
|
||||
handle.seek(offset, os.SEEK_CUR)
|
||||
return field.DecodeField(header, handle, rest)
|
||||
else:
|
||||
offset += field.Size(header)
|
||||
|
||||
log.debug("error did not find " + path)
|
||||
return None
|
||||
|
||||
|
||||
class DNAField:
|
||||
'''
|
||||
DNAField is a coupled DNAType and DNAName.
|
||||
|
||||
Type = DNAType
|
||||
Name = DNAName
|
||||
'''
|
||||
|
||||
def __init__(self, aType, aName):
|
||||
self.Type = aType
|
||||
self.Name = aName
|
||||
|
||||
def Size(self, header):
|
||||
if self.Name.IsPointer() or self.Name.IsMethodPointer():
|
||||
return header.PointerSize * self.Name.ArraySize()
|
||||
else:
|
||||
return self.Type.Size * self.Name.ArraySize()
|
||||
|
||||
def DecodeField(self, header, handle, path):
|
||||
if path == "":
|
||||
if self.Name.IsPointer():
|
||||
return Read('pointer', handle, header)
|
||||
if self.Type.Name == "int":
|
||||
return Read('int', handle, header)
|
||||
if self.Type.Name == "short":
|
||||
return Read('short', handle, header)
|
||||
if self.Type.Name == "float":
|
||||
return Read('float', handle, header)
|
||||
if self.Type.Name == "char":
|
||||
return ReadString(handle, self.Name.ArraySize())
|
||||
else:
|
||||
return self.Type.Structure.GetField(header, handle, path)
|
||||
29
blender-5.2.0/doc/blender_file_format/README
Normal file
29
blender-5.2.0/doc/blender_file_format/README
Normal file
@@ -0,0 +1,29 @@
|
||||
To inspect the blend-file-format used by a certain version of blender 2.5x,
|
||||
navigate to this folder and run this command:
|
||||
|
||||
blender2.5 -b -P BlendFileDnaExporter_25.py
|
||||
|
||||
where "blender2.5" is your blender executable or a symlink to it.
|
||||
|
||||
This creates a temporary dna.blend to be inspected and it produces two new files:
|
||||
|
||||
* dna.html: the list of all the structures saved in a blend file with the blender2.5
|
||||
executable you have used. If you enable build information when you build blender,
|
||||
the dna.html file will also show which svn revision the html refers to.
|
||||
* dna.css: the css for the html above
|
||||
|
||||
Below you have the help message with a list of options you can use.
|
||||
|
||||
|
||||
Usage:
|
||||
blender2.5 --background --python BlendFileDnaExporter_25.py [-- [options]]
|
||||
Options:
|
||||
--dna-keep-blend: doesn't delete the produced blend file DNA export to html
|
||||
--dna-debug: sets the logging level to DEBUG (lots of additional info)
|
||||
--dna-versioned saves version information in the html and blend filenames
|
||||
--dna-overwrite-css overwrite dna.css, useful when modifying css in the script
|
||||
Examples:
|
||||
default: % blender2.5 --background --python BlendFileDnaExporter_25.py
|
||||
with options: % blender2.5 --background --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug
|
||||
|
||||
|
||||
204
blender-5.2.0/doc/blender_file_format/mystery_of_the_blend.css
Normal file
204
blender-5.2.0/doc/blender_file_format/mystery_of_the_blend.css
Normal file
@@ -0,0 +1,204 @@
|
||||
@CHARSET "ISO-8859-1";
|
||||
|
||||
table {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000000;
|
||||
border-collapse: collapse;
|
||||
width: 94%;
|
||||
margin: 10px 3%;
|
||||
}
|
||||
|
||||
DIV.title {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
DIV.subtitle {
|
||||
font-size: large;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
DIV.contact {
|
||||
margin:30px 3%;
|
||||
}
|
||||
|
||||
@media print {
|
||||
DIV.contact {
|
||||
margin-top: 300px;
|
||||
}
|
||||
DIV.title {
|
||||
margin-top: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
width: 100px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
label:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
TH {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
TR {
|
||||
}
|
||||
|
||||
TD {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #a0a0a0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
BODY {
|
||||
font-family: verdana;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
H1 {
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
H1, H2, H3, H4 {
|
||||
margin-top: 30px;
|
||||
margin-right: 3%;
|
||||
padding: 3px 3%;
|
||||
color: #404040;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
H1, H2 {
|
||||
background-color: #D3D3D3;
|
||||
}
|
||||
|
||||
H3, H4 {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
H1:hover, H2:hover, H3:hover, H4:hover {
|
||||
background-color: #EBEBEB;
|
||||
}
|
||||
|
||||
CODE.evidence {
|
||||
font-size:larger
|
||||
}
|
||||
|
||||
CODE.block {
|
||||
color: #000000;
|
||||
background-color: #DDDC75;
|
||||
margin: 10px 0;
|
||||
padding: 5px;
|
||||
border-width: 1px;
|
||||
border-style: dotted;
|
||||
border-color: #000000;
|
||||
white-space: pre;
|
||||
display: block;
|
||||
font-size: 2 em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 10px 3%;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0 -15px;
|
||||
}
|
||||
|
||||
ul.multicolumn {
|
||||
list-style: none;
|
||||
float: left;
|
||||
padding-right: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
li.multicolumn {
|
||||
float: left;
|
||||
width: 200px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
p {
|
||||
margin: 10px 3%;
|
||||
line-height: 130%;
|
||||
}
|
||||
}
|
||||
|
||||
span.fade {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
span.header {
|
||||
color: green;
|
||||
}
|
||||
|
||||
span.header-greyed {
|
||||
color: #4CBE4B;
|
||||
}
|
||||
|
||||
span.data {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
span.data-greyed {
|
||||
color: #5D99C4;
|
||||
}
|
||||
|
||||
span.descr {
|
||||
color: red;
|
||||
}
|
||||
|
||||
div.box {
|
||||
margin: 15px 3%;
|
||||
border-style: dotted;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
div.box-solid {
|
||||
margin: 15px 3%;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
p.box-title {
|
||||
font-style: italic;
|
||||
font-size: 110%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p.box-title:hover {
|
||||
background-color: #EBEBEB;
|
||||
}
|
||||
|
||||
p.code {
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #a000a0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #a000a0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
td.skip {
|
||||
color: #808080;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
835
blender-5.2.0/doc/blender_file_format/mystery_of_the_blend.html
Normal file
835
blender-5.2.0/doc/blender_file_format/mystery_of_the_blend.html
Normal file
@@ -0,0 +1,835 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="mystery_of_the_blend.css" media="screen, print">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>The mystery of the blend</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="title">The mystery of the blend</div>
|
||||
<div class="subtitle">The blender file-format explained</div>
|
||||
<div class="contact">
|
||||
<label>Author</label> Jeroen Bakker<br>
|
||||
<label>Email</label> <a href="mailto:j.bakker@atmind.nl">j.bakker@atmind.nl</a><br>
|
||||
<label>Website</label> <a href="http://www.atmind.nl/blender/">http://www.atmind.nl/blender</a><br>
|
||||
<label>Version</label> 06-10-2010<br>
|
||||
</div>
|
||||
|
||||
<a name="introduction" href="#introduction" ><h2>Introduction</h2></a>
|
||||
</a>
|
||||
|
||||
<p>In this article I will describe the
|
||||
blend-file-format with a request to tool-makers to support blend-file.
|
||||
|
||||
</p>
|
||||
<p>First I'll describe how Blender works with blend-files. You'll notice
|
||||
why the blend-file-format is not that well documented, as from
|
||||
Blender's perspective this is not needed.
|
||||
We look at the global file-structure of a blend-file (the file-header
|
||||
and file-blocks).
|
||||
After this is explained, we go deeper to the core of the blend-file, the
|
||||
DNA-structures. They hold the blue-prints of the blend-file and the key
|
||||
asset of understanding blend-files.
|
||||
When that's done we can use these DNA-structures to read information
|
||||
from elsewhere in the blend-file.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
In this article we'll be using the default blend-file from Blender 2.54,
|
||||
with the goal to read the output resolution from the Scene.
|
||||
The article is written to be programming language independent and I've
|
||||
setup a web-site for support.
|
||||
</p>
|
||||
|
||||
<a name="loading-and-saving-in-blender" href="#loading-and-saving-in-blender">
|
||||
<h2>Loading and saving in Blender</h2>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
Loading and saving in Blender is very fast and Blender is known to
|
||||
have excellent downward and upward compatibility. Ton Roosendaal
|
||||
demonstrated that in December 2008 by loading a 1.0 blend-file using
|
||||
Blender 2.48a [ref: <a href="http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/">http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/</a>].
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Saving complex scenes in Blender is done within seconds. Blender
|
||||
achieves this by saving data in memory to disk without any
|
||||
transformations or translations. Blender only adds file-block-headers to
|
||||
this data. A file-block-header contains clues on how to interpret the
|
||||
data. After the data, all internally Blender structures are stored.
|
||||
These structures will act as blue-prints when Blender loads the file.
|
||||
Blend-files can be different when stored on different hardware platforms
|
||||
or Blender releases. There is no effort taken to make blend-files
|
||||
binary the same. Blender creates the blend-files in this manner since
|
||||
release 1.0. Backward and upwards compatibility is not implemented when
|
||||
saving the file, this is done during loading.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When Blender loads a blend-file, the DNA-structures are read first.
|
||||
Blender creates a catalog of these DNA-structures. Blender uses this
|
||||
catalog together with the data in the file, the internal Blender
|
||||
structures of the Blender release you're using and a lot of
|
||||
transformation and translation logic to implement the backward and
|
||||
upward compatibility. In the source code of blender there is actually
|
||||
logic which can transform and translate every structure used by a
|
||||
Blender release to the one of the release you're using [ref: <a href="http://download.blender.org/source/blender-2.48a.tar.gz">http://download.blender.org/source/blender-2.48a.tar.gz</a>
|
||||
<a href="https://svn.blender.org/svnroot/bf-blender/tags/blender-2.48-release/source/blender/blenloader/intern/readfile.c">blender/blenloader/intern/readfile.c</a> lines
|
||||
4946-7960]. The more difference between releases the more logic is
|
||||
executed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The blend-file-format is not well documented, as it does not differ from
|
||||
internally used structures and the file can really explain itself.
|
||||
</p>
|
||||
|
||||
<a name="global-file-structure" href="#global-file-structure">
|
||||
<h2>Global file-structure</h2>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
This section explains how the global file-structure can be read.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>A blend-file always start with the <b>file-header</b></li>
|
||||
<li>After the file-header, follows a list of <b>file-blocks</b> (the default blend file of Blender 2.48 contains more than 400 of these file-blocks).</li>
|
||||
<li>Each file-block has a <b>file-block header</b> and <b>file-block data</b></li>
|
||||
<li>At the end of the blend-file there is a section called "<a href="#structure-DNA" style="font-weight:bold">Structure DNA</a>", which lists all the internal structures of the Blender release the file was created in</li>
|
||||
<li>The blend-file ends with a file-block called 'ENDB'</li>
|
||||
</ul>
|
||||
|
||||
<!-- file scheme -->
|
||||
<div class="box-solid" style="width:20%; margin-left:35%; font-size:0.8em;">
|
||||
|
||||
<p class="code"><b>File.blend</b></p>
|
||||
|
||||
<div class="box"><p class="code">File-header</p></div>
|
||||
|
||||
<div class="box-solid"><p class="code">File-block</p>
|
||||
<div class="box"><p class="code">Header</p></div>
|
||||
<div class="box"><p class="code">Data</p></div>
|
||||
</div>
|
||||
|
||||
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
|
||||
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
|
||||
|
||||
<div class="box-solid"><p class="code">File-block 'Structure DNA'</p>
|
||||
<div class="box"><p class="code">Header ('DNA1')</p></div>
|
||||
<div class="box-solid">
|
||||
<p class="code">Data ('SDNA')</p>
|
||||
<div class="box">
|
||||
<p class="code">Names ('NAME')</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p class="code">Types ('TYPE')</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p class="code">Lengths ('TLEN')</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p class="code">Structures ('STRC')</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box-solid"><p class="code">File-Block 'ENDB'</p></div>
|
||||
|
||||
</div><!-- end of file scheme -->
|
||||
|
||||
<a name="file-header" href="#file-header">
|
||||
<h3>File-Header</h3>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
The first 12 bytes of every blend-file is the file-header. The
|
||||
file-header has information on Blender (version-number) and the PC the
|
||||
blend-file was saved on (pointer-size and endianness). This is required
|
||||
as all data inside the blend-file is ordered in that way, because no
|
||||
translation or transformation is done during saving.
|
||||
The next table describes the information in the file-header.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<caption>File-header</caption>
|
||||
<thead>
|
||||
<tr><th>reference</th>
|
||||
<th>structure</th>
|
||||
<th>type</th>
|
||||
<th>offset</th>
|
||||
<th>size</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>identifier</td>
|
||||
<td>char[7]</td>
|
||||
<td>File identifier (always 'BLENDER')</td>
|
||||
<td>0</td>
|
||||
<td>7</td></tr>
|
||||
<tr><td>pointer-size</td>
|
||||
<td>char</td>
|
||||
<td>Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes or 32 bit and '-' means 8 bytes or 64 bits.</td>
|
||||
<td>7</td>
|
||||
<td>1</td></tr>
|
||||
<tr><td>endianness</td>
|
||||
<td>char</td>
|
||||
<td>Type of byte ordering used; 'v' means little endian and 'V' means big endian.</td>
|
||||
<td>8</td>
|
||||
<td>1</td></tr>
|
||||
<tr><td>version-number</td>
|
||||
<td>char[3]</td>
|
||||
<td>Version of Blender the file was created in; '254' means version 2.54</td>
|
||||
<td>9</td>
|
||||
<td>3</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<a href="https://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <a href="#example-endianess">example</a> below):
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>in a big endian ordering, the largest part of the value is placed on the first byte and
|
||||
the lowest part of the value is placed on the last byte,</li>
|
||||
<li>in a little endian ordering, largest part of the value is placed on the last byte
|
||||
and the smallest part of the value is placed on the first byte.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Nowadays, little-endian is the most commonly used.
|
||||
</p>
|
||||
|
||||
<a name="example-endianess"></a>
|
||||
<div class="box">
|
||||
<p onclick="location.href='#example-endianess'" class="box-title">
|
||||
Endianness Example
|
||||
</p>
|
||||
<p>
|
||||
Writing the integer <code class="evidence">0x4A3B2C1Dh</code>, will be ordered:
|
||||
<ul>
|
||||
<li>in big endian as <code class="evidence">0x4Ah</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x1Dh</code></li>
|
||||
<li>in little endian as <code class="evidence">0x1Dh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x4Ah</code></li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Blender supports little-endian and big-endian.<br>
|
||||
This means that when the endianness
|
||||
is different between the blend-file and the PC your using, Blender changes it to the byte ordering
|
||||
of your PC.
|
||||
</p>
|
||||
|
||||
<a name="example-file-header"></a>
|
||||
<div class="box">
|
||||
<p onclick="location.href='#example-file-header'" class="box-title">
|
||||
File-header Example
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This hex-dump describes a file-header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
|
||||
<code class="block"> <span class="descr">pointer-size version-number
|
||||
| |</span>
|
||||
0000 0000: [42 4C 45 4E 44 45 52] [5F] [76] [32 35 34] BLENDER_v254 <span class="descr">
|
||||
| |
|
||||
identifier endianness</span></code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a name="file-blocks" href="#file-blocks"><h3>File-blocks</h3></a>
|
||||
|
||||
<p>
|
||||
File-blocks contain a "<a href="#file-block-header">file-block header</a>" and "file-block data".
|
||||
</p>
|
||||
|
||||
<a name="file-block-header" href="#file-block-header"><h3>File-block headers</h3></a>
|
||||
|
||||
<p>
|
||||
The file-block-header describes:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>the type of information stored in the
|
||||
file-block</li>
|
||||
<li>the total length of the data</li>
|
||||
<li>the old memory
|
||||
pointer at the moment the data was written to disk</li>
|
||||
<li>the number of items of this information</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
As we can see below, depending on the pointer-size stored in the file-header, a file-block-header
|
||||
can be 20 or 24 bytes long, hence it is always aligned at 4 bytes.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<caption>File-block-header</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>reference</th>
|
||||
<th>structure</th>
|
||||
<th>type</th>
|
||||
<th>offset</th>
|
||||
<th>size</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>code</td>
|
||||
<td>char[4]</td>
|
||||
<td>File-block identifier</td>
|
||||
<td>0</td>
|
||||
<td>4</td></tr>
|
||||
<tr><td>size</td>
|
||||
<td>integer</td>
|
||||
<td>Total length of the data after the file-block-header</td>
|
||||
<td>4</td>
|
||||
<td>4</td></tr>
|
||||
<tr><td>old memory address</td>
|
||||
<td>void*</td>
|
||||
<td>Memory address the structure was located when written to disk</td>
|
||||
<td>8</td>
|
||||
<td>pointer-size (4/8)</td></tr>
|
||||
<tr><td>SDNA index</td>
|
||||
<td>integer</td>
|
||||
<td>Index of the SDNA structure</td>
|
||||
<td>8+pointer-size</td>
|
||||
<td>4</td></tr>
|
||||
<tr><td>count</td>
|
||||
<td>integer</td>
|
||||
<td>Number of structure located in this file-block</td>
|
||||
<td>12+pointer-size</td>
|
||||
<td>4</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
The above table describes how a file-block-header is structured:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><code>Code</code> describes different types of file-blocks. The code determines with what logic the data must be read. <br>
|
||||
These codes also allows fast finding of data like Library, Scenes, Object or Materials as they all have a specific code. </li>
|
||||
<li><code>Size</code> contains the total length of data after the file-block-header.
|
||||
After the data a new file-block starts. The last file-block in the file
|
||||
has code 'ENDB'.</li>
|
||||
<li><code>Old memory address</code> contains the memory address when the structure
|
||||
was last stored. When loading the file the structures can be placed on
|
||||
different memory addresses. Blender updates pointers to these structures
|
||||
to the new memory addresses.</li>
|
||||
<li><code>SDNA index</code> contains the index in the DNA structures to be used when
|
||||
reading this file-block-data. <br>
|
||||
More information about this subject will be explained in the <a href="#reading-scene-information">Reading scene information section</a>.</li>
|
||||
<li><code>Count</code> tells how many elements of the specific SDNA structure can be found in the data.</li>
|
||||
</ul>
|
||||
|
||||
<a name="example-file-block-header"></a>
|
||||
<div class="box">
|
||||
<p onclick="location.href='#example-file-block-header'" class="box-title">
|
||||
Example
|
||||
</p>
|
||||
<p>
|
||||
This hex-dump describes a File-block (= <span class="header">File-block header</span> + <span class="data">File-block data</span>) created with <code>blender</code> <code>2.54</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
|
||||
<code class="block"><span class="descr"> file-block
|
||||
identifier='SC' data size=1404 old pointer SDNA index=150
|
||||
| | | |</span>
|
||||
0000 4420: <span class="header">[53 43 00 00] [7C 05 00 00] [68 34 FB 0B] [96 00 00 00]</span> SC.. `... ./.. ....
|
||||
0000 4430: <span class="header">[01 00 00 00]</span> <span class="data">[xx xx xx xx xx xx xx xx xx xx xx xx</span> .... xxxx xxxx xxxx<span class="descr">
|
||||
| |
|
||||
count=1 file-block data (next 1404 bytes)</span>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>The code <code>'SC'+0x00h</code> identifies that it is a Scene. </li>
|
||||
<li>Size of the data is 1404 bytes (0x0000057Ch = 0x7Ch + 0x05h * 256 = 124 + 1280)</li>
|
||||
<li>The old pointer is 0x0BFB3468h</li>
|
||||
<li>The SDNA index is 150 (0x00000096h = 6 + 9 * 16 = 6 + 144)</li>
|
||||
<li>The section contains a single scene (count = 1).</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Before we can interpret the data of this file-block we first have to read the DNA structures in the file.
|
||||
The section "<a href="#structure-DNA">Structure DNA</a>" will show how to do that.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a name="structure-DNA" href="#structure-DNA"><h2>Structure DNA</h2></a>
|
||||
|
||||
<a name="DNA1-file-block" href="#DNA1-file-block"><h3>The DNA1 file-block</h3></a>
|
||||
|
||||
<p>
|
||||
Structure DNA is stored in a file-block with code 'DNA1'. It can be just before the 'ENDB' file-block.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The 'DNA1' file-block contains all internal structures of the Blender release the
|
||||
file was created in. <br>
|
||||
These structure can be described as C-structures: they can hold fields, arrays and
|
||||
pointers to other structures, just like a normal C-structure.
|
||||
|
||||
<p>
|
||||
<code class="block">struct SceneRenderLayer {
|
||||
struct SceneRenderLayer *next, *prev;
|
||||
char name[32];
|
||||
struct Material *mat_override;
|
||||
struct Group *light_override;
|
||||
unsigned int lay;
|
||||
unsigned int lay_zmask;
|
||||
int layflag;
|
||||
int pad;
|
||||
int passflag;
|
||||
int pass_xor;
|
||||
};
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example,a blend-file created with Blender 2.54 the 'DNA1' file-block is 57796 bytes long and contains 398 structures.
|
||||
</p>
|
||||
|
||||
<a name="DNA1-file-block-header" href="#DNA1-file-block-header"><h3>DNA1 file-block-header</h3></a>
|
||||
|
||||
<p>
|
||||
The DNA1 file-block header follows the same rules of any other file-block, see the example below.
|
||||
</p>
|
||||
|
||||
<a name="example-DNA1-file-block-header"></a>
|
||||
<div class="box">
|
||||
<p onclick="location.href='#example-DNA1-file-block-header'" class="box-title">
|
||||
Example
|
||||
</p>
|
||||
<p>
|
||||
This hex-dump describes the file-block 'DNA1' header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
|
||||
<code class="block"><span class="descr"> (file-block
|
||||
identifier='DNA1') data size=57796 old pointer SDNA index=0
|
||||
| | | |</span>
|
||||
0004 B060 <span class="header">[44 4E 41 31] [C4 E1 00 00] [C8 00 84 0B] [00 00 00 00]</span> DNA1............
|
||||
0004 B070 <span class="header">[01 00 00 00]</span> <span class="fade">[53 44 4E 41 4E 41 4D 45 CB 0B 00 00</span> ....<span class="fade">SDNANAME....</span><span class="descr">
|
||||
| |
|
||||
count=1 'DNA1' file-block data (next 57796 bytes)</span>
|
||||
</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a name="DNA1-file-block-data" href="#DNA1-file-block-data"><h3>DNA1 file-block data</h3></a>
|
||||
<p>
|
||||
The next section describes how this information is ordered in the <b>data</b> of the 'DNA1' file-block.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<caption>Structure of the DNA file-block-data</caption>
|
||||
<thead>
|
||||
<tr><th colspan="2">repeat condition</th>
|
||||
<th>name</th>
|
||||
<th>type</th>
|
||||
<th>length</th>
|
||||
<th>description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>identifier</td>
|
||||
<td>char[4]</td>
|
||||
<td>4</td>
|
||||
<td>'SDNA'</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>name identifier</td>
|
||||
<td>char[4]</td>
|
||||
<td>4</td>
|
||||
<td>'NAME'</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>#names</td>
|
||||
<td>integer</td>
|
||||
<td>4</td>
|
||||
<td>Number of names follows</td></tr>
|
||||
<tr><td>for(#names)</td>
|
||||
<td></td>
|
||||
<td>name</td>
|
||||
<td>char[]</td>
|
||||
<td>?</td>
|
||||
<td>Zero terminating string of name, also contains pointer and simple array definitions (e.g. '*vertex[3]\0')</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>type identifier</td>
|
||||
<td>char[4]</td>
|
||||
<td>4</td>
|
||||
<td>'TYPE' this field is aligned at 4 bytes</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>#types</td>
|
||||
<td>integer</td>
|
||||
<td>4</td>
|
||||
<td>Number of types follows</td></tr>
|
||||
<tr><td>for(#types)</td>
|
||||
<td></td>
|
||||
<td>type</td>
|
||||
<td>char[]</td>
|
||||
<td>?</td>
|
||||
<td>Zero terminating string of type (e.g. 'int\0')</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>length identifier</td>
|
||||
<td>char[4]</td>
|
||||
<td>4</td>
|
||||
<td>'TLEN' this field is aligned at 4 bytes</td></tr>
|
||||
<tr><td>for(#types)</td>
|
||||
<td></td>
|
||||
<td>length</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
<td>Length in bytes of type (e.g. 4)</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>structure identifier</td>
|
||||
<td>char[4]</td>
|
||||
<td>4</td>
|
||||
<td>'STRC' this field is aligned at 4 bytes</td></tr>
|
||||
<tr><td></td>
|
||||
<td></td>
|
||||
<td>#structures</td>
|
||||
<td>integer</td>
|
||||
<td>4</td>
|
||||
<td>Number of structures follows</td></tr>
|
||||
<tr><td>for(#structures)</td>
|
||||
<td></td>
|
||||
<td>structure type</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
<td>Index in types containing the name of the structure</td></tr>
|
||||
<tr><td>..</td>
|
||||
<td></td>
|
||||
<td>#fields</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
<td>Number of fields in this structure</td></tr>
|
||||
<tr><td>..</td>
|
||||
<td>for(#field)</td>
|
||||
<td>field type</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
<td>Index in type</td></tr>
|
||||
<tr><td>for end</td>
|
||||
<td>for end</td>
|
||||
<td>field name</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
<td>Index in name</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
As you can see, the structures are stored in 4 arrays: names, types,
|
||||
lengths and structures. Every structure also contains an array of
|
||||
fields. A field is the combination of a type and a name. From this
|
||||
information a catalog of all structures can be constructed.
|
||||
The names are stored as how a C-developer defines them. This means that
|
||||
the name also defines pointers and arrays.
|
||||
(When a name starts with '*' it is used as a pointer. when the name
|
||||
contains for example '[3]' it is used as a array of 3 long.)
|
||||
In the types you'll find simple-types (like: 'integer', 'char',
|
||||
'float'), but also complex-types like 'Scene' and 'MetaBall'.
|
||||
'TLEN' part describes the length of the types. A 'char' is 1 byte, an
|
||||
'integer' is 4 bytes and a 'Scene' is 1376 bytes long.
|
||||
</p>
|
||||
|
||||
<div class="box">
|
||||
<p class="box-title">
|
||||
Note
|
||||
</p>
|
||||
<p>
|
||||
All identifiers, are arrays of 4 chars, hence they are all aligned at 4 bytes.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a name="example-DNA1-file-block-data"></a>
|
||||
<div class="box">
|
||||
<p onclick="location.href='#example-DNA1-file-block-data'" class="box-title">
|
||||
Example
|
||||
</p>
|
||||
<p>
|
||||
Created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
|
||||
</p>
|
||||
|
||||
<a name="DNA1-data-array-names" href="#DNA1-data-array-names"><h4>The names array</h4></a>
|
||||
<p>
|
||||
The first names are: *next, *prev, *data, *first, *last, x, y, xmin, xmax, ymin, ymax, *pointer, group, val, val2, type, subtype, flag, name[32], ...
|
||||
<code class="block"><span class="descr"> file-block-data identifier='SDNA' array-id='NAME' number of names=3019
|
||||
| | |</span>
|
||||
0004 B070 <span class="fade">01 00 00 00 [53 44 4E 41]</span><span class="data">[4E 41 4D 45] [CB 0B 00 00]</span> <span class="fade">....SDNA</span>NAME....
|
||||
0004 B080 <span class="data">[2A 6E 65 78 74 00][2A 70 72 65 76 00] [2A 64 61 74</span> *next.*prev.*dat<span class="descr">
|
||||
| | |
|
||||
'*next\0' '*prev\0' '*dat'</span><span class="fade">
|
||||
....
|
||||
.... (3019 names)</span>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<div class="box">
|
||||
<p class="box-title">
|
||||
Note
|
||||
</p>
|
||||
<p>
|
||||
While reading the DNA you'll will come across some strange
|
||||
names like '(*doit)()'. These are method pointers and Blender updates
|
||||
them to the correct methods.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a name="DNA1-data-array-types" href="#DNA1-data-array-types"><h4>The types array</h4></a>
|
||||
<p>
|
||||
The first types are: char, uchar, short, ushort, int, long, ulong, float, double, void, Link, LinkData, ListBase, vec2s, vec2f, ...
|
||||
<code class="block"><span class="descr"> array-id='TYPE'
|
||||
|</span>
|
||||
0005 2440 <span class="fade">6F 6C 64 5B 34 5D 5B 34 5D 00 00 00</span> [54 59 50 45] <span class="fade">old[4][4]...</span>TYPE
|
||||
0005 2450 [C9 01 00 00] [63 68 61 72 00] [75 63 68 61 72 00][73 ....char.uchar.s<span class="descr">
|
||||
| | | |
|
||||
number of types=457 'char\0' 'uchar\0' 's'</span><span class="fade">
|
||||
....
|
||||
.... (457 types)</span>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<a name="DNA1-data-array-lengths" href="#DNA1-data-array-lengths"><h4>The lengths array</h4></a>
|
||||
<p>
|
||||
<code class="block"><span class="descr"> char uchar ushort short
|
||||
array-id length length length length
|
||||
'TLEN' 1 1 2 2</span>
|
||||
0005 3AA0 <span class="fade">45 00 00 00</span> [54 4C 45 4E] [01 00] [01 00] [02 00] [02 00] <span class="fade">E...</span>TLEN........
|
||||
<span class="fade">....</span>
|
||||
0005 3AC0 [08 00] [04 00] [08 00] [10 00] [10 00] [14 00] [4C 00] [34 00] ............L.4.<span class="descr">
|
||||
8 4 8
|
||||
ListBase vec2s vec2f ... etc
|
||||
length len length </span><span class="fade">
|
||||
....
|
||||
.... (457 lengths, same as number of types)</span>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<a name="DNA1-data-array-structures" href="#DNA1-data-array-structures"><h4>The structures array</h4></a>
|
||||
<p>
|
||||
<code class="block"><span class="descr"> array-id='STRC'
|
||||
|</span>
|
||||
0005 3E30 <span class="fade">40 00 38 00 60 00 00 00 00 00 00 00</span> [53 54 52 43] <span class="fade">@.8.`.......</span>STRC
|
||||
0005 3E40 [8E 01 00 00] [0A 00] [02 00] [0A 00] [00 00] [0A 00] [01 00] ................<span class="descr">
|
||||
398 10 2 10 0 10 0
|
||||
number of index fields index index index index
|
||||
structures in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a></span><span class="fade">
|
||||
' '----------------' '-----------------' '
|
||||
' field 0 field 1 '
|
||||
'--------------------------------------------------------'
|
||||
structure 0
|
||||
....
|
||||
.... (398 structures, each one describeing own type, and type/name for each field)</span>
|
||||
</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The DNA structures inside a Blender 2.48 blend-file can be found at <a href="http://www.atmind.nl/blender/blender-sdna.html">http://www.atmind.nl/blender/blender-sdna.html</a>.
|
||||
|
||||
If we understand the DNA part of the file it is now possible to read
|
||||
information from other parts file-blocks. The next section will tell us
|
||||
how.
|
||||
</p>
|
||||
|
||||
<a name="reading-scene-information" href="#reading-scene-information"><h2>Reading scene information</h2></a>
|
||||
|
||||
<p>
|
||||
Let us look at <a href="#example-file-block-header">the file-block header we have seen earlier</a>:<br>
|
||||
</p>
|
||||
<ul>
|
||||
<li>the file-block identifier is <code>'SC'+0x00h</code></li>
|
||||
<li>the SDNA index is 150</li>
|
||||
<li>the file-block size is 1404 bytes</li>
|
||||
</ul>
|
||||
<p>
|
||||
Now note that:
|
||||
<ul>
|
||||
<li>the structure at index 150 in the DNA is a structure of type 'Scene' (counting from 0).</li>
|
||||
<li>the associated type ('Scene') in the DNA has the length of 1404 bytes.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We can map the Scene structure on the data of the file-blocks.
|
||||
But before we can do that, we have to flatten the Scene-structure.
|
||||
|
||||
<code class="block">struct Scene {
|
||||
ID id; <span class="descr">// 52 bytes long (ID is different a structure)</span>
|
||||
AnimData *adt; <span class="descr">// 4 bytes long (pointer to an AnimData structure)</span>
|
||||
Object *camera; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
|
||||
World *world; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
|
||||
...
|
||||
float cursor[3]; <span class="descr">// 12 bytes long (array of 3 floats)</span>
|
||||
...
|
||||
};
|
||||
</code>
|
||||
|
||||
The first field in the Scene-structure is of type 'ID' with the name 'id'.
|
||||
Inside the list of DNA structures there is a structure defined for type 'ID' (structure index 17).
|
||||
|
||||
<code class="block">struct ID {
|
||||
void *next, *prev;
|
||||
struct ID *newid;
|
||||
struct Library *lib;
|
||||
char name[24];
|
||||
short us;
|
||||
short flag;
|
||||
int icon_id;
|
||||
IDProperty *properties;
|
||||
};
|
||||
</code>
|
||||
|
||||
The first field in this structure has type 'void' and name '*next'. <br>
|
||||
Looking in the structure list there is no structure defined for type 'void': it is a simple type and therefore the data should be read.
|
||||
The name '*next' describes a pointer.
|
||||
As we see, the first 4 bytes of the data can be mapped to 'id.next'.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using this method we'll map a structure to its data. If we want to
|
||||
read a specific field we know at which offset in the data it is located
|
||||
and how much space it takes.<br>
|
||||
The next table shows the output of this flattening process for some
|
||||
parts of the Scene-structure. Not all rows are described in the table as
|
||||
there is a lot of information in a Scene-structure.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<caption>Flattened SDNA structure 150: Scene</caption>
|
||||
<thead>
|
||||
<tr><th>reference</th>
|
||||
<th>structure</th>
|
||||
<th>type</th><th>name</th>
|
||||
<th>offset</th><th>size</th>
|
||||
<th>description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>id.next</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>void</td><td>*next</td>
|
||||
<td>0</td>
|
||||
<td>4</td>
|
||||
<td>Refers to the next scene</td></tr>
|
||||
<tr><td>id.prev</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>void</td><td>*prev</td>
|
||||
<td>4</td>
|
||||
<td>4</td>
|
||||
<td>Refers to the previous scene</td></tr>
|
||||
<tr><td>id.newid</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>ID</td><td>*newid</td>
|
||||
<td>8</td>
|
||||
<td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>id.lib</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>Library</td><td>*lib</td>
|
||||
<td>12</td>
|
||||
<td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>id.name</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>char</td><td>name[24]</td>
|
||||
<td>16</td>
|
||||
<td>24</td>
|
||||
<td>'SC'+the name of the scene as displayed in Blender</td></tr>
|
||||
<tr><td>id.us</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>short</td><td>us</td>
|
||||
<td>40</td>
|
||||
<td>2</td>
|
||||
<td></td></tr>
|
||||
<tr><td>id.flag</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>short</td><td>flag</td><td>42</td><td>2</td>
|
||||
<td></td></tr>
|
||||
<tr><td>id.icon_id</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>int</td><td>icon_id</td><td>44</td>
|
||||
<td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>id.properties</td><td><a href="#struct:ID">ID</a></td>
|
||||
<td>IDProperty</td><td>*properties</td>
|
||||
<td>48</td>
|
||||
<td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>adt</td><td>Scene</td><td>AnimData</td>
|
||||
<td>*adt</td>
|
||||
<td>52</td>
|
||||
<td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>camera</td><td>Scene</td>
|
||||
<td>Object</td>
|
||||
<td>*camera</td>
|
||||
<td>56</td>
|
||||
<td>4</td>
|
||||
<td>Pointer to the current camera</td></tr>
|
||||
<tr><td>world</td><td>Scene</td>
|
||||
<td>World</td>
|
||||
<td>*world</td>
|
||||
<td>60</td>
|
||||
<td>4</td>
|
||||
<td>Pointer to the current world</td></tr>
|
||||
|
||||
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
|
||||
|
||||
<tr><td>r.xsch</td><td><a href="#struct:RenderData">RenderData</a>
|
||||
</td><td>short</td><td>xsch</td><td>382</td><td>2</td>
|
||||
<td>X-resolution of the output when rendered at 100%</td></tr>
|
||||
<tr><td>r.ysch</td><td><a href="#struct:RenderData">RenderData</a>
|
||||
</td><td>short</td><td>ysch</td><td>384</td><td>2</td>
|
||||
<td>Y-resolution of the output when rendered at 100%</td></tr>
|
||||
<tr><td>r.xparts</td><td><a href="#struct:RenderData">RenderData</a>
|
||||
</td><td>short</td><td>xparts</td><td>386</td><td>2</td>
|
||||
<td>Number of x-part used by the renderer</td></tr>
|
||||
<tr><td>r.yparts</td><td><a href="#struct:RenderData">RenderData</a>
|
||||
</td><td>short</td><td>yparts</td><td>388</td><td>2</td>
|
||||
<td>Number of x-part used by the renderer</td></tr>
|
||||
|
||||
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
|
||||
|
||||
<tr><td>gpd</td><td>Scene</td><td>bGPdata</td><td>*gpd</td><td>1376</td><td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>physics_settings.gravity</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
|
||||
</td><td>float</td><td>gravity[3]</td><td>1380</td><td>12</td>
|
||||
<td></td></tr>
|
||||
<tr><td>physics_settings.flag</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
|
||||
</td><td>int</td><td>flag</td><td>1392</td><td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>physics_settings.quick_cache_step</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
|
||||
</td><td>int</td><td>quick_cache_step</td><td>1396</td><td>4</td>
|
||||
<td></td></tr>
|
||||
<tr><td>physics_settings.rt</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
|
||||
</td><td>int</td><td>rt</td><td>1400</td><td>4</td>
|
||||
<td></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
We can now read the X and Y resolution of the Scene:
|
||||
<ul>
|
||||
<li>the X-resolution is located on offset 382 of the file-block-data and must be read as a
|
||||
short.</li>
|
||||
<li>the Y-resolution is located on offset 384 and is also a short</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<div class="box">
|
||||
<p class="box-title">
|
||||
Note
|
||||
</p>
|
||||
<p>
|
||||
An array of chars can mean 2 things. The field contains readable
|
||||
text or it contains an array of flags (not humanly readable).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<p class="box-title">
|
||||
Note
|
||||
</p>
|
||||
<p>
|
||||
A file-block containing a list refers to the DNA structure and has a count larger
|
||||
than 1. For example Vertices and Faces are stored in this way.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
2624
blender-5.2.0/doc/doxygen/Doxyfile
Normal file
2624
blender-5.2.0/doc/doxygen/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
25
blender-5.2.0/doc/doxygen/doxygen.extern.h
Normal file
25
blender-5.2.0/doc/doxygen/doxygen.extern.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \defgroup extern External libraries
|
||||
* \section externabout External libraries
|
||||
* As with \ref intern these libraries are
|
||||
* provided in the Blender codebase. This is
|
||||
* to make building Blender easier. The main
|
||||
* development of these libraries is \b not part
|
||||
* of the normal Blender development process, but
|
||||
* each of the library is developed separately.
|
||||
* Whenever deemed necessary libraries in \c extern/
|
||||
* folder are updated.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \defgroup curve_fit Curve Fitting Library
|
||||
* \ingroup extern
|
||||
*/
|
||||
|
||||
/** \defgroup bullet Bullet Physics Library
|
||||
* \ingroup extern
|
||||
* \see \ref bulletdoc
|
||||
*/
|
||||
101
blender-5.2.0/doc/doxygen/doxygen.intern.h
Normal file
101
blender-5.2.0/doc/doxygen/doxygen.intern.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \defgroup intern Internal libraries
|
||||
* \section internabout Internal libraries
|
||||
* Blender comes with some of its dependencies
|
||||
* directly included in the codebase. Libraries
|
||||
* that are in the \c intern/ folder are maintained
|
||||
* as part of the normal development process.
|
||||
*/
|
||||
|
||||
/* TODO: other modules.
|
||||
* - `libmv`
|
||||
* - `cycles`
|
||||
* - `opencolorio`
|
||||
* - `opensubdiv`
|
||||
* - `openvdb`
|
||||
* - `quadriflow`
|
||||
*/
|
||||
|
||||
/** \defgroup intern_atomic Atomic Operations
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_clog C-Logging (CLOG)
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_eigen Eigen
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_glew-mx GLEW with Multiple Rendering Context's
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_iksolver Inverse Kinematics (Solver)
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_itasc Inverse Kinematics (ITASC)
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_libc_compat libc Compatibility For Linux
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_locale Locale
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_mantaflow Manta-Flow Fluid Simulation
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_mem Guarded Memory (de)allocation
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_memutil Memory Utilities (memutil)
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_mikktspace MikktSpace
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_rigidbody Rigid-Body C-API
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_sky_model Sky Model
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_slim SLIM Solver for UV Unwrapping
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup intern_utf_conv UTF8/UTF16 Conversion (utfconv)
|
||||
* \ingroup intern */
|
||||
|
||||
/** \defgroup audaspace Audaspace
|
||||
* \ingroup intern undoc
|
||||
* \todo add to doxygen */
|
||||
/** \defgroup audcoreaudio Audaspace CoreAudio
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audfx Audaspace FX
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audopenal Audaspace OpenAL
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audpulseaudio Audaspace PulseAudio
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audwasapi Audaspace WASAPI
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audpython Audaspace Python
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audsdl Audaspace SDL
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audsrc Audaspace SRC
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audffmpeg Audaspace FFMpeg
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audfftw Audaspace FFTW
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audjack Audaspace Jack
|
||||
* \ingroup audaspace */
|
||||
/** \defgroup audsndfile Audaspace sndfile
|
||||
* \ingroup audaspace */
|
||||
|
||||
/** \defgroup GHOST GHOST API
|
||||
* \ingroup intern GUI
|
||||
* \ref GHOSTPage
|
||||
*/
|
||||
26
blender-5.2.0/doc/doxygen/doxygen.main.h
Normal file
26
blender-5.2.0/doc/doxygen/doxygen.main.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* SPDX-FileCopyrightText: 2003-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \mainpage Blender
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* Blender is an integrated 3d package.
|
||||
*
|
||||
* These pages document the source code of blender.
|
||||
*
|
||||
* \subsection implinks Important Links
|
||||
* - <a href="https://developer.blender.org">developer.blender.org</a> with bug tracker.
|
||||
* - <a href="https://developer.blender.org/docs/">Development documentation</a>.
|
||||
*
|
||||
* \subsection blother Other
|
||||
* For more information on using Blender browse to https://www.blender.org
|
||||
*
|
||||
*/
|
||||
|
||||
/** \defgroup undoc Undocumented
|
||||
*
|
||||
* \brief Modules and libraries that are still undocumented,
|
||||
* or lacking proper integration into the doxygen system, are marked in this group.
|
||||
*/
|
||||
313
blender-5.2.0/doc/doxygen/doxygen.source.h
Normal file
313
blender-5.2.0/doc/doxygen/doxygen.source.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/* SPDX-FileCopyrightText: 2003-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \defgroup render Rendering
|
||||
* \ingroup blender
|
||||
*/
|
||||
/** \defgroup bmesh BMesh
|
||||
* \ingroup blender
|
||||
*/
|
||||
/** \defgroup compositor Compositing
|
||||
* \ingroup blender */
|
||||
|
||||
/** \defgroup python Python
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup pygen Python Generic
|
||||
* \ingroup python
|
||||
*/
|
||||
|
||||
/** \defgroup pymathutils Python Mathutils
|
||||
* \ingroup python
|
||||
*/
|
||||
|
||||
/** \defgroup pythonintern Python RNA and Operators
|
||||
* \ingroup python
|
||||
*/
|
||||
|
||||
/* ================================ */
|
||||
|
||||
/** \defgroup blender Blender */
|
||||
|
||||
/** \defgroup balembic BlenderAlembic
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup blt BlenTranslation
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup blf BlenFont
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup bke BlenKernel
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup bli BlenLib
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup depsgraph Dependency Graph
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup bph Physics
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup nodes Nodes
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup cmpnodes Nodes (Compositor)
|
||||
* \ingroup nodes
|
||||
*/
|
||||
|
||||
/** \defgroup shdnodes Nodes (Shader)
|
||||
* \ingroup nodes
|
||||
*/
|
||||
|
||||
/** \defgroup texnodes Nodes (Texture)
|
||||
* \ingroup nodes
|
||||
*/
|
||||
/** \defgroup modifiers Object Modifiers
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup shader_fx Shader Effects
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup data DNA, RNA and .blend access
|
||||
* \ingroup blender */
|
||||
|
||||
/** \defgroup gpu GPU
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup ikplugin IK Plugin
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup DNA Struct DNA (File Format)
|
||||
* \ingroup blender data
|
||||
*/
|
||||
/** \defgroup RNA RNA (Data API)
|
||||
* \ingroup blender data
|
||||
*/
|
||||
|
||||
/** \defgroup blenloader Blend file IO
|
||||
* \ingroup blender data
|
||||
* \todo check if \ref blo and \ref blenloader groups can be
|
||||
* merged in docs.
|
||||
*/
|
||||
|
||||
/** \defgroup gui GUI
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup wm Window Manager
|
||||
* \ingroup gui */
|
||||
|
||||
/* ================================ */
|
||||
|
||||
/** \defgroup editors Editors
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup edanimation animation
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edarmature armature
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edasset asset
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edcurve curve
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup eddatafiles datafiles
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edgizmolib gizmo library
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edgpencil gpencil
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edinterface interface
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edlattice lattice
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edmesh mesh
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edmeta metaball
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edobj object
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edphys physics
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edrend render
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edscr screen
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edscene scene
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edsculpt sculpt and paint
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edsnd sound
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spaction action space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spapi space API
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spbuttons buttons space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spconsole console space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spfile fileselector
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spgraph graph editor
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spimage image and UV editor
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spinfo info space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spnla NLA editor
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spnode node editor
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spoutliner outliner space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spscript script space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spseq sequencer
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spsnd sound space
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup sptext text editor
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup sptime time line
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spuserpref user preferences
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spview3d 3D view
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edtransform transform
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edutil editor utilities
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup edundo undo utilities
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/** \defgroup spuv UV editing
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
/* ================================ */
|
||||
|
||||
/** \defgroup editorui Interface and Widgets
|
||||
* \ingroup gui
|
||||
*/
|
||||
|
||||
/** \defgroup externformats External Formats
|
||||
* \ingroup blender */
|
||||
|
||||
/** \defgroup avi AVI
|
||||
* \ingroup externformats
|
||||
*/
|
||||
|
||||
/** \defgroup imbuf Image Buffer (ImBuf)
|
||||
* \ingroup blender
|
||||
*/
|
||||
|
||||
/** \defgroup imbcineon Cineon
|
||||
* \ingroup imbuf
|
||||
*/
|
||||
|
||||
/** \defgroup openexr OpenEXR
|
||||
* \ingroup imbuf
|
||||
*/
|
||||
|
||||
/* ================================ */
|
||||
|
||||
/** \defgroup undoc Undocumented
|
||||
*
|
||||
* \brief Modules and libraries that are still undocumented,
|
||||
* or lacking proper integration into the doxygen system, are marked in this group.
|
||||
*/
|
||||
9
blender-5.2.0/doc/doxygen/footer.html
Normal file
9
blender-5.2.0/doc/doxygen/footer.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<hr class="footer"/>
|
||||
<address class="footer">
|
||||
<small>Generated on $datetime for $projectname by 
|
||||
<a href="http://www.doxygen.org/index.html"> doxygen</a>
|
||||
$doxygenversion
|
||||
</small>
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
202
blender-5.2.0/doc/license/Apache2-license.txt
Normal file
202
blender-5.2.0/doc/license/Apache2-license.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
35
blender-5.2.0/doc/license/BL-license.txt
Normal file
35
blender-5.2.0/doc/license/BL-license.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
Blender License (the "BL", see http://www.blender.org/BL/ ).
|
||||
|
||||
Copyright (C) 2002-2005 Blender Foundation. All Rights Reserved.
|
||||
|
||||
This text supersedes the previous BL description, called Blender License 1.0.
|
||||
|
||||
When the Blender source code was released in 2002, the Blender Foundation reserved
|
||||
the right to offer licenses outside of the GNU GPL. This so-called "dual license"
|
||||
model was chosen to provide potential revenues for the Blender Foundation.
|
||||
|
||||
The BL has not been activated yet. Partially because;
|
||||
|
||||
- there has to be a clear benefit for Blender itself and its community of
|
||||
developers and users.
|
||||
- the developers who have copyrighted additions to the source code need to approve
|
||||
the decision.
|
||||
- the (c) holder NaN Holding has to approve on a standard License Contract
|
||||
|
||||
But most important;
|
||||
|
||||
- the Blender Foundation is financially healthy, based on community support
|
||||
(e-shop sales), sponsoring and subsidy grants
|
||||
- current focus for the Blender Foundation is to not set up any commercial
|
||||
activity related to Blender development.
|
||||
- the GNU GPL provides sufficient freedom for third parties to conduct business
|
||||
with Blender
|
||||
|
||||
For these reasons we've decided to cancel the BL offering for an indefinite period.
|
||||
|
||||
Third parties interested to discuss usage or exploitation of Blender can email
|
||||
license@blender.org for further information.
|
||||
|
||||
Ton Roosendaal
|
||||
Chairman Blender Foundation.
|
||||
June 2005
|
||||
22
blender-5.2.0/doc/license/BSD-2-Clause-license.txt
Normal file
22
blender-5.2.0/doc/license/BSD-2-Clause-license.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
BSD 2-Clause License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
26
blender-5.2.0/doc/license/BSD-3-Clause-license.txt
Normal file
26
blender-5.2.0/doc/license/BSD-3-Clause-license.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
23
blender-5.2.0/doc/license/Boost-license.txt
Normal file
23
blender-5.2.0/doc/license/Boost-license.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
340
blender-5.2.0/doc/license/GPL-license.txt
Normal file
340
blender-5.2.0/doc/license/GPL-license.txt
Normal file
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
674
blender-5.2.0/doc/license/GPL3-license.txt
Normal file
674
blender-5.2.0/doc/license/GPL3-license.txt
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
502
blender-5.2.0/doc/license/LGPL2.1-license.txt
Normal file
502
blender-5.2.0/doc/license/LGPL2.1-license.txt
Normal file
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
19
blender-5.2.0/doc/license/MIT-license.txt
Normal file
19
blender-5.2.0/doc/license/MIT-license.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
373
blender-5.2.0/doc/license/MPL2-license.txt
Normal file
373
blender-5.2.0/doc/license/MPL2-license.txt
Normal file
@@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
12
blender-5.2.0/doc/license/SPDX-license-identifiers.txt
Normal file
12
blender-5.2.0/doc/license/SPDX-license-identifiers.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Corresponding SPDX license identifiers in the source code:
|
||||
|
||||
Apache-2.0 Apache-2-license.txt https://spdx.org/licenses/Apache-2.0.html
|
||||
BSD-2-Clause BSD-2-Clause-license.txt https://spdx.org/licenses/BSD-2-Clause.html
|
||||
BSD-3-Clause BSD-3-Clause-license.txt https://spdx.org/licenses/BSD-3-Clause.html
|
||||
BSL-1.0 Boost-license.txt https://spdx.org/licenses/BSL-1.0.html
|
||||
GPL-2.0-or-later GPL-license.txt https://spdx.org/licenses/GPL-2.0-or-later.html
|
||||
GPL-3.0-or-later GPL3-license.txt https://spdx.org/licenses/GPL-3.0-or-later.html
|
||||
LGPL-2.1-or-later LGPL2.1-license.txt https://spdx.org/licenses/LGPL-2.1-or-later.html
|
||||
MIT MIT-license.txt https://spdx.org/licenses/MIT.html
|
||||
MPL-2.0 MPL-2.0.txt https://spdx.org/licenses/MPL-2.0.html
|
||||
Zlib Zlib-license.txt https://spdx.org/licenses/Zlib.html
|
||||
17
blender-5.2.0/doc/license/Zlib-license.txt
Normal file
17
blender-5.2.0/doc/license/Zlib-license.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Zlib License
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
1393
blender-5.2.0/doc/license/bf-members.txt
Normal file
1393
blender-5.2.0/doc/license/bf-members.txt
Normal file
File diff suppressed because it is too large
Load Diff
230
blender-5.2.0/doc/manpage/blender.1.py
Executable file
230
blender-5.2.0/doc/manpage/blender.1.py
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
This script generates the ``blender.1`` man page, embedding the help text
|
||||
from the Blender executable itself. Invoke it as follows:
|
||||
|
||||
blender.1.py --blender <path-to-blender> --output <output-filename>
|
||||
|
||||
where <path-to-blender> is the path to the Blender executable,
|
||||
and <output-filename> is where to write the generated man page.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from typing import (
|
||||
TextIO,
|
||||
Dict,
|
||||
)
|
||||
|
||||
|
||||
def man_format(data: str) -> str:
|
||||
data = data.replace("-", "\\-")
|
||||
data = data.replace("\t", " ")
|
||||
# Single quotes prevent text rendering when found at the beginning of lines.
|
||||
data = data.replace("'", "\\(aq")
|
||||
return data
|
||||
|
||||
|
||||
def blender_extract_info(blender_bin: str) -> Dict[str, str]:
|
||||
blender_env = {
|
||||
"ASAN_OPTIONS": (
|
||||
os.environ.get("ASAN_OPTIONS", "") +
|
||||
":exitcode=0:check_initialization_order=0:strict_init_order=0"
|
||||
).lstrip(":"),
|
||||
}
|
||||
|
||||
# NOTE: in some ways it's more elegant to use `bpy.app.help_text()` which was done but had to be reverted.
|
||||
# however - this requires Blender to run with a full environment (initializing it's Python environment).
|
||||
# See #115056 & !115320 for details.
|
||||
|
||||
blender_help = subprocess.run(
|
||||
[blender_bin, "--help"],
|
||||
env=blender_env,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.decode(encoding="utf-8")
|
||||
|
||||
blender_version_output = subprocess.run(
|
||||
[blender_bin, "--version"],
|
||||
env=blender_env,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.decode(encoding="utf-8")
|
||||
|
||||
# Extract information from the version string.
|
||||
# Note that some internal modules may print errors (e.g. color management),
|
||||
# check for each lines prefix to ensure these aren't included.
|
||||
blender_version = ""
|
||||
blender_date = ""
|
||||
|
||||
# The full text (use to manipulate `blender_version_text`).
|
||||
blender_version_text = ""
|
||||
|
||||
for l in blender_version_output.split("\n"):
|
||||
if l.startswith("Blender "):
|
||||
if blender_version_text == "":
|
||||
blender_version_text = l
|
||||
# Remove `Blender` prefix.
|
||||
blender_version = l.split(" ", 1)[1].strip()
|
||||
elif l.lstrip().startswith("build date:"):
|
||||
# Remove `build date:` prefix.
|
||||
blender_date = l.split(":", 1)[1].strip()
|
||||
if blender_version and blender_date:
|
||||
break
|
||||
|
||||
# The `--help` text also contains the version, skip it so as not to include it twice.
|
||||
if blender_version_text:
|
||||
i = blender_help.find(blender_version_text)
|
||||
if i != -1:
|
||||
blender_help = blender_help[i + len(blender_version_text) + 1:]
|
||||
del i
|
||||
|
||||
if not blender_date:
|
||||
# Happens when built without WITH_BUILD_INFO e.g.
|
||||
date_string = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
|
||||
else:
|
||||
date_string = time.strftime("%B %d, %Y", time.strptime(blender_date, "%Y-%m-%d"))
|
||||
|
||||
return {
|
||||
"help": blender_help,
|
||||
"version": blender_version,
|
||||
"date": date_string,
|
||||
}
|
||||
|
||||
|
||||
def man_page_from_blender_help(fh: TextIO, blender_bin: str, verbose: bool) -> None:
|
||||
if verbose:
|
||||
print("Extracting help text:", blender_bin)
|
||||
blender_info = blender_extract_info(blender_bin)
|
||||
|
||||
# Header Content.
|
||||
fh.write(
|
||||
'.TH "BLENDER" "1" "{:s}" "Blender {:s}"\n'.format(
|
||||
blender_info["date"], blender_info["version"].replace(".", "\\&.")
|
||||
)
|
||||
)
|
||||
|
||||
fh.write(r"""
|
||||
.SH NAME
|
||||
blender \- a full-featured 3D application""")
|
||||
|
||||
fh.write(r"""
|
||||
.SH SYNOPSIS
|
||||
.B blender [args ...] [file] [args ...]""")
|
||||
|
||||
fh.write(r"""
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.B blender
|
||||
is a full-featured 3D application. It supports the entirety of the 3D pipeline - """
|
||||
"""modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
|
||||
|
||||
Use Blender to create 3D images and animations, films and commercials, content for games, """
|
||||
r"""architectural and industrial visualizations, and scientific visualizations.
|
||||
|
||||
https://www.blender.org""")
|
||||
|
||||
fh.write(r"""
|
||||
.SH OPTIONS""")
|
||||
|
||||
fh.write("\n\n")
|
||||
|
||||
# Body Content.
|
||||
|
||||
lines = [line.rstrip() for line in blender_info["help"].split("\n")]
|
||||
|
||||
while lines:
|
||||
l = lines.pop(0)
|
||||
if l.startswith("Environment Variables:"):
|
||||
fh.write('.SH "ENVIRONMENT VARIABLES"\n')
|
||||
elif l.endswith(":"): # One line.
|
||||
fh.write('.SS "{:s}"\n\n'.format(l))
|
||||
elif l.startswith("-") or l.startswith("/"): # Can be multi line.
|
||||
fh.write('.TP\n')
|
||||
fh.write('.B {:s}\n'.format(man_format(l)))
|
||||
|
||||
while lines:
|
||||
# line with no
|
||||
if lines[0].strip() and len(lines[0].lstrip()) == len(lines[0]): # No white space.
|
||||
break
|
||||
|
||||
if not l: # Second blank line.
|
||||
fh.write('.IP\n')
|
||||
else:
|
||||
fh.write('.br\n')
|
||||
|
||||
l = lines.pop(0)
|
||||
if l:
|
||||
assert l.startswith('\t')
|
||||
l = l[1:] # Remove first white-space (tab).
|
||||
|
||||
fh.write('{:s}\n'.format(man_format(l)))
|
||||
|
||||
else:
|
||||
if not l.strip():
|
||||
fh.write('.br\n')
|
||||
else:
|
||||
fh.write('{:s}\n'.format(man_format(l)))
|
||||
|
||||
# Footer Content.
|
||||
|
||||
fh.write(r"""
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.B luxrender(1)
|
||||
|
||||
.br
|
||||
.SH AUTHORS
|
||||
This manpage was written for a Debian GNU/Linux system by Daniel Mester
|
||||
<mester@uni-bremen.de> and updated by Cyril Brulebois
|
||||
<cyril.brulebois@enst-bretagne.fr> and Dan Eicher <dan@trollwerks.org>.
|
||||
""")
|
||||
|
||||
|
||||
def create_argparse() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
required=True,
|
||||
help="The man page to write to."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--blender",
|
||||
required=True,
|
||||
help="Path to the Blender binary."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose",
|
||||
default=False,
|
||||
required=False,
|
||||
action='store_true',
|
||||
help="Print additional progress."
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = create_argparse()
|
||||
args = parser.parse_args()
|
||||
|
||||
output_filename = args.output
|
||||
blender_bin = args.blender
|
||||
verbose = args.verbose
|
||||
|
||||
with open(output_filename, "w", encoding="utf-8") as fh:
|
||||
man_page_from_blender_help(fh, blender_bin, verbose)
|
||||
if verbose:
|
||||
print("Written:", output_filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
123
blender-5.2.0/doc/python_api/check_stubs.py
Normal file
123
blender-5.2.0/doc/python_api/check_stubs.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Type-check Blender Python examples and templates against generated stubs.
|
||||
Each file is checked in a separate MYPY process, running in parallel.
|
||||
|
||||
NOTE(@ideasman42): we are nowhere near close to having Blender scripts type check without any type warnings.
|
||||
This is mainly as a way to check:
|
||||
|
||||
- The stubs are valid can be loaded into MYPY.
|
||||
- The stubs are working as expected,
|
||||
since errors in the stubs *do* point to errors in the RST documentation.
|
||||
|
||||
However, it is not as a way to ensure we have zero typing errors,
|
||||
as there are too many false positives.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import multiprocessing
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Project root derived from this file's location (doc/python_api/).
|
||||
SOURCE_DIR = Path(__file__).resolve().parents[2]
|
||||
|
||||
STUB_DIR = SOURCE_DIR / "doc" / "python_api" / "stubs"
|
||||
|
||||
SKIP = {
|
||||
"doc/python_api/examples/aud.0.py",
|
||||
"doc/python_api/examples/bpy.types.HydraRenderEngine.py",
|
||||
"scripts/templates_py/ui_list_generic.py",
|
||||
}
|
||||
|
||||
|
||||
def check_file(filepath: str) -> tuple[str, str]:
|
||||
"""Run mypy on a single file, return (filepath, error_output)."""
|
||||
env = os.environ.copy()
|
||||
env["MYPYPATH"] = str(STUB_DIR)
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable, "-m", "mypy", filepath,
|
||||
"--no-error-summary",
|
||||
"--explicit-package-bases",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
env=env,
|
||||
)
|
||||
prefix = filepath + ":"
|
||||
lines = [
|
||||
line for line in result.stdout.splitlines()
|
||||
if line.startswith(prefix)
|
||||
# Mix-in classes that narrow `bl_*` Literal attributes cause diamond
|
||||
# inheritance conflicts - a `mypy` limitation, not a stub bug.
|
||||
and "incompatible with definition in base class" not in line
|
||||
]
|
||||
return filepath, "\n".join(lines)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"-j", "--jobs", type=int, default=0,
|
||||
help=(
|
||||
"Parallel jobs (default 0 uses CPU count; 1 runs synchronously, "
|
||||
"streaming each mypy invocation's output directly to the terminal)."
|
||||
),
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
os.chdir(SOURCE_DIR)
|
||||
|
||||
# `Path.as_posix()` normalizes backslashes for WIN32 so SKIP paths match.
|
||||
all_files = [
|
||||
path.as_posix() for pattern in (
|
||||
"doc/python_api/examples/*.py",
|
||||
"scripts/templates_py/*.py",
|
||||
"tests/python/*.py",
|
||||
"scripts/modules/**/*.py",
|
||||
"scripts/startup/**/*.py",
|
||||
"scripts/addons_core/**/*.py",
|
||||
) for path in Path().glob(pattern)
|
||||
]
|
||||
files = sorted(f for f in all_files if f not in SKIP)
|
||||
|
||||
jobs = args.jobs
|
||||
if jobs <= 0:
|
||||
jobs = multiprocessing.cpu_count()
|
||||
|
||||
errors = 0
|
||||
|
||||
if jobs == 1:
|
||||
# Synchronous: print each file's result as soon as it's ready.
|
||||
for filepath in files:
|
||||
_, output = check_file(filepath)
|
||||
if output:
|
||||
errors += 1
|
||||
print(output)
|
||||
print()
|
||||
else:
|
||||
results: dict[str, str] = {}
|
||||
with multiprocessing.Pool(jobs) as pool:
|
||||
for filepath, output in pool.imap_unordered(check_file, files):
|
||||
results[filepath] = output
|
||||
|
||||
# Print results in file order.
|
||||
for filepath in files:
|
||||
output = results[filepath]
|
||||
if output:
|
||||
errors += 1
|
||||
print(output)
|
||||
print()
|
||||
|
||||
print("Checked {:d} files, {:d} with errors.".format(len(files), errors))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
185
blender-5.2.0/doc/python_api/conf.py
Normal file
185
blender-5.2.0/doc/python_api/conf.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
def has_module(module_name):
|
||||
found = False
|
||||
try:
|
||||
__import__(module_name)
|
||||
found = True
|
||||
except ModuleNotFoundError as ex:
|
||||
if ex.name != module_name:
|
||||
raise ex
|
||||
return found
|
||||
|
||||
|
||||
# These are substituted when this file is copied to the build directory.
|
||||
BLENDER_VERSION_STRING = "${BLENDER_VERSION_STRING}"
|
||||
BLENDER_VERSION_DOTS = "${BLENDER_VERSION_DOTS}"
|
||||
BLENDER_REVISION = "${BLENDER_REVISION}"
|
||||
BLENDER_REVISION_TIMESTAMP = "${BLENDER_REVISION_TIMESTAMP}"
|
||||
BLENDER_VERSION_DATE = time.strftime(
|
||||
"%d/%m/%Y",
|
||||
time.localtime(int(BLENDER_REVISION_TIMESTAMP) if BLENDER_REVISION_TIMESTAMP != "0" else None),
|
||||
)
|
||||
|
||||
if BLENDER_REVISION != "Unknown":
|
||||
# SHA1 GIT hash.
|
||||
BLENDER_VERSION_HASH = BLENDER_REVISION
|
||||
BLENDER_VERSION_HASH_HTML_LINK = (
|
||||
"<a href=https://projects.blender.org/blender/blender/commit/{:s}>{:s}</a>".format(
|
||||
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
|
||||
)
|
||||
)
|
||||
else:
|
||||
# Fallback: Should not be used.
|
||||
BLENDER_VERSION_HASH = "Hash Unknown"
|
||||
BLENDER_VERSION_HASH_HTML_LINK = BLENDER_VERSION_HASH
|
||||
|
||||
extensions = []
|
||||
|
||||
# Downloading can be slow and get in the way of development,
|
||||
# support "offline" builds.
|
||||
if not os.environ.get("BLENDER_DOC_OFFLINE", "").strip("0"):
|
||||
extensions.append("sphinx.ext.intersphinx")
|
||||
intersphinx_mapping = {"blender_manual": ("https://docs.blender.org/manual/en/dev/", None)}
|
||||
|
||||
# Provides copy button next to code-blocks (nice to have but not essential).
|
||||
if has_module("sphinx_copybutton"):
|
||||
extensions.append("sphinx_copybutton")
|
||||
|
||||
# Exclude line numbers, prompts, and console text.
|
||||
copybutton_exclude = ".linenos, .gp, .go"
|
||||
|
||||
|
||||
project = "Blender {:s} Python API".format(BLENDER_VERSION_STRING)
|
||||
root_doc = "index"
|
||||
copyright = "Blender Authors"
|
||||
version = BLENDER_VERSION_DOTS
|
||||
release = BLENDER_VERSION_DOTS
|
||||
|
||||
# Set this as the default is a super-set of Python3.
|
||||
highlight_language = "python3"
|
||||
# No need to detect encoding.
|
||||
highlight_options = {"default": {"encoding": "utf-8"}}
|
||||
|
||||
# Quiet file not in table-of-contents warnings.
|
||||
exclude_patterns = [
|
||||
"include__bmesh.rst",
|
||||
]
|
||||
|
||||
html_title = "Blender Python API"
|
||||
|
||||
# The fallback to a built-in theme when `furo` is not found.
|
||||
html_theme = "default"
|
||||
|
||||
if has_module("furo"):
|
||||
html_theme = "furo"
|
||||
html_theme_options = {
|
||||
"light_css_variables": {
|
||||
"color-brand-primary": "#265787",
|
||||
"color-brand-content": "#265787",
|
||||
},
|
||||
}
|
||||
|
||||
html_sidebars = {
|
||||
"**": [
|
||||
"sidebar/brand.html",
|
||||
"sidebar/search.html",
|
||||
"sidebar/scroll-start.html",
|
||||
"sidebar/navigation.html",
|
||||
"sidebar/scroll-end.html",
|
||||
"sidebar/variant-selector.html",
|
||||
]
|
||||
}
|
||||
|
||||
# Not helpful since the source is generated, adds to upload size.
|
||||
html_copy_source = False
|
||||
html_show_sphinx = False
|
||||
html_baseurl = "https://docs.blender.org/api/current/"
|
||||
html_use_opensearch = "https://docs.blender.org/api/current"
|
||||
html_show_search_summary = True
|
||||
html_split_index = True
|
||||
html_static_path = ["static"]
|
||||
templates_path = ["templates"]
|
||||
html_context = {
|
||||
"commit": "{:s} - {:s}".format(BLENDER_VERSION_HASH_HTML_LINK, BLENDER_VERSION_DATE),
|
||||
}
|
||||
html_extra_path = ["static"]
|
||||
html_favicon = "static/favicon.png"
|
||||
html_logo = "static/blender_logo.svg"
|
||||
# Disable default `last_updated` value, since this is the date of doc generation, not the one of the source commit.
|
||||
html_last_updated_fmt = None
|
||||
if html_theme == "furo":
|
||||
html_css_files = ["css/theme_overrides.css", "css/version_switch.css"]
|
||||
html_js_files = ["js/version_switch.js"]
|
||||
|
||||
# Needed for latex, PDF generation.
|
||||
latex_elements = {
|
||||
"papersize": "a4paper",
|
||||
}
|
||||
|
||||
latex_documents = [
|
||||
("contents", "contents.tex", "Blender Index", "Blender Foundation", "manual"),
|
||||
]
|
||||
|
||||
# Workaround for useless links leading to compile errors
|
||||
# See https://github.com/sphinx-doc/sphinx/issues/3866
|
||||
from sphinx.domains.python import PythonDomain
|
||||
|
||||
|
||||
class PatchedPythonDomain(PythonDomain):
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
if "refspecific" in node:
|
||||
del node["refspecific"]
|
||||
return super(PatchedPythonDomain, self).resolve_xref(
|
||||
env, fromdocname, builder, typ, target, node, contnode)
|
||||
|
||||
|
||||
def register_details_directive(app):
|
||||
"""
|
||||
Register a `.. details:: Title` directive.
|
||||
|
||||
Wraps content in an HTML ``<details>`` widget so verbose-but-uninteresting
|
||||
sections (e.g. dunder methods) are foldable. Implemented via ``nodes.raw``
|
||||
around the parsed content - this avoids needing a custom node class
|
||||
(Sphinx pickles the doctree for parallel/incremental builds and cannot
|
||||
reach classes defined in ``conf.py``, which is exec-loaded). Non-HTML
|
||||
builders ignore ``raw`` nodes and render the content inline.
|
||||
"""
|
||||
from html import escape
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
|
||||
class DetailsDirective(Directive):
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
summary = self.arguments[0] if self.arguments else "Details"
|
||||
container = nodes.Element()
|
||||
self.state.nested_parse(self.content, self.content_offset, container)
|
||||
children = list(container.children)
|
||||
container.children = []
|
||||
for child in children:
|
||||
child.parent = None
|
||||
open_tag = nodes.raw(
|
||||
"",
|
||||
"<details><summary>{:s}</summary>".format(escape(summary)),
|
||||
format="html",
|
||||
)
|
||||
close_tag = nodes.raw("", "</details>", format="html")
|
||||
return [open_tag, *children, close_tag]
|
||||
|
||||
app.add_directive("details", DetailsDirective)
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(PatchedPythonDomain, override=True)
|
||||
register_details_directive(app)
|
||||
22
blender-5.2.0/doc/python_api/examples/aud.0.py
Normal file
22
blender-5.2.0/doc/python_api/examples/aud.0.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Basic Sound Playback
|
||||
++++++++++++++++++++
|
||||
|
||||
This script shows how to use the classes: :class:`Device`, :class:`Sound` and
|
||||
:class:`Handle`.
|
||||
"""
|
||||
import aud
|
||||
|
||||
device = aud.Device()
|
||||
# Load sound file (it can be a video file with audio).
|
||||
sound = aud.Sound('music.ogg')
|
||||
|
||||
# Play the audio, this return a handle to control play/pause.
|
||||
handle = device.play(sound)
|
||||
# If the audio is not too big and will be used often you can buffer it.
|
||||
sound_buffered = aud.Sound.cache(sound)
|
||||
handle_buffered = device.play(sound_buffered)
|
||||
|
||||
# Stop the sounds (otherwise they play until their ends).
|
||||
handle.stop()
|
||||
handle_buffered.stop()
|
||||
45
blender-5.2.0/doc/python_api/examples/blf.0.py
Normal file
45
blender-5.2.0/doc/python_api/examples/blf.0.py
Normal file
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
Hello World Text Example
|
||||
++++++++++++++++++++++++
|
||||
|
||||
Example of using the blf module. For this module to work we
|
||||
need to use the GPU module :mod:`gpu` as well.
|
||||
"""
|
||||
# Import stand alone modules.
|
||||
import blf
|
||||
import bpy
|
||||
|
||||
font_info = {
|
||||
"font_id": 0,
|
||||
"handler": None,
|
||||
}
|
||||
|
||||
|
||||
def init():
|
||||
"""init function - runs once"""
|
||||
import os
|
||||
# Create a new font object, use external TTF file.
|
||||
font_path = bpy.path.abspath('//Zeyada.ttf')
|
||||
# Store the font index - to use later.
|
||||
if os.path.exists(font_path):
|
||||
font_info["font_id"] = blf.load(font_path)
|
||||
else:
|
||||
# Default font.
|
||||
font_info["font_id"] = 0
|
||||
|
||||
# Set the font drawing routine to run every frame.
|
||||
font_info["handler"] = bpy.types.SpaceView3D.draw_handler_add(
|
||||
draw_callback_px, (None, None), 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
|
||||
def draw_callback_px(self, context):
|
||||
"""Draw on the viewports"""
|
||||
# BLF drawing routine.
|
||||
font_id = font_info["font_id"]
|
||||
blf.position(font_id, 2, 80, 0)
|
||||
blf.size(font_id, 50.0)
|
||||
blf.draw(font_id, "Hello World")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
init()
|
||||
29
blender-5.2.0/doc/python_api/examples/blf.1.py
Normal file
29
blender-5.2.0/doc/python_api/examples/blf.1.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Drawing Text to an Image
|
||||
++++++++++++++++++++++++
|
||||
|
||||
Example showing how text can be drawn into an image.
|
||||
This can be done by binding an image buffer (:mod:`imbuf`) to the font's ID.
|
||||
"""
|
||||
|
||||
import blf
|
||||
import imbuf
|
||||
|
||||
image_size = 512, 512
|
||||
font_size = 20
|
||||
|
||||
ibuf = imbuf.new(image_size)
|
||||
|
||||
font_id = blf.load("/path/to/font.ttf")
|
||||
|
||||
blf.color(font_id, 1.0, 1.0, 1.0, 1.0)
|
||||
blf.size(font_id, font_size)
|
||||
blf.position(font_id, 0, image_size[1] - font_size, 0)
|
||||
|
||||
blf.enable(font_id, blf.WORD_WRAP)
|
||||
blf.word_wrap(font_id, image_size[0])
|
||||
|
||||
with blf.bind_imbuf(font_id, ibuf, display_name="sRGB"):
|
||||
blf.draw_buffer(font_id, "Lots of wrapped text. " * 50)
|
||||
|
||||
imbuf.write(ibuf, filepath="/path/to/image.png")
|
||||
107
blender-5.2.0/doc/python_api/examples/bmesh.ops.1.py
Normal file
107
blender-5.2.0/doc/python_api/examples/bmesh.ops.1.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# This script uses bmesh operators to make 2 links of a chain.
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
import math
|
||||
import mathutils
|
||||
|
||||
# Make a new BMesh
|
||||
bm = bmesh.new()
|
||||
|
||||
# Add a circle XXX, should return all geometry created, not just verts.
|
||||
bmesh.ops.create_circle(
|
||||
bm,
|
||||
cap_ends=False,
|
||||
radius=0.2,
|
||||
segments=8)
|
||||
|
||||
|
||||
# Spin and deal with geometry on side 'a'
|
||||
edges_start_a = bm.edges[:]
|
||||
geom_start_a = bm.verts[:] + edges_start_a
|
||||
ret = bmesh.ops.spin(
|
||||
bm,
|
||||
geom=geom_start_a,
|
||||
angle=math.radians(180.0),
|
||||
steps=8,
|
||||
axis=(1.0, 0.0, 0.0),
|
||||
cent=(0.0, 1.0, 0.0))
|
||||
edges_end_a = [ele for ele in ret["geom_last"]
|
||||
if isinstance(ele, bmesh.types.BMEdge)]
|
||||
del ret
|
||||
|
||||
|
||||
# Extrude and create geometry on side 'b'
|
||||
ret = bmesh.ops.extrude_edge_only(
|
||||
bm,
|
||||
edges=edges_start_a)
|
||||
geom_extrude_mid = ret["geom"]
|
||||
del ret
|
||||
|
||||
|
||||
# Collect the edges to spin XXX, 'extrude_edge_only' could return this.
|
||||
verts_extrude_b = [ele for ele in geom_extrude_mid
|
||||
if isinstance(ele, bmesh.types.BMVert)]
|
||||
edges_extrude_b = [ele for ele in geom_extrude_mid
|
||||
if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
|
||||
bmesh.ops.translate(
|
||||
bm,
|
||||
verts=verts_extrude_b,
|
||||
vec=(0.0, 0.0, 1.0))
|
||||
|
||||
|
||||
# Create the circle on side 'b'
|
||||
ret = bmesh.ops.spin(
|
||||
bm,
|
||||
geom=verts_extrude_b + edges_extrude_b,
|
||||
angle=-math.radians(180.0),
|
||||
steps=8,
|
||||
axis=(1.0, 0.0, 0.0),
|
||||
cent=(0.0, 1.0, 1.0))
|
||||
edges_end_b = [ele for ele in ret["geom_last"]
|
||||
if isinstance(ele, bmesh.types.BMEdge)]
|
||||
del ret
|
||||
|
||||
|
||||
# Bridge the resulting edge loops of both spins 'a & b'
|
||||
bmesh.ops.bridge_loops(
|
||||
bm,
|
||||
edges=edges_end_a + edges_end_b)
|
||||
|
||||
|
||||
# Now we have made a links of the chain, make a copy and rotate it
|
||||
# (so this looks something like a chain)
|
||||
|
||||
ret = bmesh.ops.duplicate(
|
||||
bm,
|
||||
geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
|
||||
geom_dupe = ret["geom"]
|
||||
verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
|
||||
del ret
|
||||
|
||||
# position the new link
|
||||
bmesh.ops.translate(
|
||||
bm,
|
||||
verts=verts_dupe,
|
||||
vec=(0.0, 0.0, 2.0))
|
||||
bmesh.ops.rotate(
|
||||
bm,
|
||||
verts=verts_dupe,
|
||||
cent=(0.0, 1.0, 0.0),
|
||||
matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
|
||||
|
||||
# Done with creating the mesh, simply link it into the scene so we can see it
|
||||
|
||||
# Finish up, write the bmesh into a new mesh
|
||||
me = bpy.data.meshes.new("Mesh")
|
||||
bm.to_mesh(me)
|
||||
bm.free()
|
||||
|
||||
|
||||
# Add the mesh to the scene
|
||||
obj = bpy.data.objects.new("Object", me)
|
||||
bpy.context.collection.objects.link(obj)
|
||||
|
||||
# Select and make active
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
File Loading & Order of Initialization
|
||||
Since drivers may be evaluated immediately after loading a blend-file it is necessary
|
||||
to ensure the driver name-space is initialized beforehand.
|
||||
|
||||
This can be done by registering text data-blocks to execute on startup,
|
||||
which executes the scripts before drivers are evaluated.
|
||||
See *Text -> Register* from Blender's text editor.
|
||||
|
||||
.. hint::
|
||||
|
||||
You may prefer to use external files instead of Blender's text-blocks.
|
||||
This can be done using a text-block which executes an external file.
|
||||
|
||||
This example runs ``driver_namespace.py`` located in the same directory as the text-blocks blend-file:
|
||||
|
||||
.. code-block::
|
||||
|
||||
import os
|
||||
import bpy
|
||||
blend_dir = os.path.normpath(os.path.join(__file__, "..", ".."))
|
||||
bpy.utils.execfile(os.path.join(blend_dir, "driver_namespace.py"))
|
||||
|
||||
Using ``__file__`` ensures the text resolves to the expected path even when library-linked from another file.
|
||||
|
||||
Other methods of populating the drivers name-space can be made to work but tend to be error prone:
|
||||
|
||||
Using The ``--python`` command line argument to populate name-space often fails to achieve the desired goal
|
||||
because the initial evaluation will lookup a function that doesn't exist yet,
|
||||
marking the driver as invalid - preventing further evaluation.
|
||||
|
||||
Populating the driver name-space before the blend-file loads also doesn't work
|
||||
since opening a file clears the name-space.
|
||||
|
||||
It is possible to run a script via the ``--python`` command line argument, before the blend file.
|
||||
This can register a load-post handler (:mod:`bpy.app.handlers.load_post`) that initializes the name-space.
|
||||
While this works for background tasks it has the downside that opening the file from the file selector
|
||||
won't setup the name-space.
|
||||
"""
|
||||
15
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.0.py
Normal file
15
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.0.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Basic Handler Example
|
||||
+++++++++++++++++++++
|
||||
|
||||
This script shows the most simple example of adding a handler.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def my_handler(scene):
|
||||
print("Frame Change", scene.frame_current)
|
||||
|
||||
|
||||
bpy.app.handlers.frame_change_pre.append(my_handler)
|
||||
21
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.1.py
Normal file
21
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.1.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
Persistent Handler Example
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
By default handlers are freed when loading new files, in some cases you may
|
||||
want the handler stay running across multiple files (when the handler is
|
||||
part of an add-on for example).
|
||||
|
||||
For this the :data:`bpy.app.handlers.persistent` decorator needs to be used.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy.app.handlers import persistent
|
||||
|
||||
|
||||
@persistent
|
||||
def load_handler(dummy):
|
||||
print("Load Handler:", bpy.data.filepath)
|
||||
|
||||
|
||||
bpy.app.handlers.load_post.append(load_handler)
|
||||
24
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.2.py
Normal file
24
blender-5.2.0/doc/python_api/examples/bpy.app.handlers.2.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Note on Altering Data
|
||||
+++++++++++++++++++++
|
||||
|
||||
Altering data from handlers should be done carefully. While rendering the
|
||||
``frame_change_pre`` and ``frame_change_post`` handlers are called from one
|
||||
thread and the viewport updates from a different thread. If the handler changes
|
||||
data that is accessed by the viewport, this can cause a crash of Blender. In
|
||||
such cases, lock the interface (Render → Lock Interface or
|
||||
:data:`bpy.types.RenderSettings.use_lock_interface`) before starting a render.
|
||||
|
||||
Below is an example of a mesh that is altered from a handler:
|
||||
"""
|
||||
|
||||
|
||||
def frame_change_pre(scene):
|
||||
# A triangle that shifts in the z direction.
|
||||
zshift = scene.frame_current * 0.1
|
||||
vertices = [(-1, -1, zshift), (1, -1, zshift), (0, 1, zshift)]
|
||||
triangles = [(0, 1, 2)]
|
||||
|
||||
object = bpy.data.objects["The Object"]
|
||||
object.data.clear_geometry()
|
||||
object.data.from_pydata(vertices, [], triangles)
|
||||
12
blender-5.2.0/doc/python_api/examples/bpy.app.timers.1.py
Normal file
12
blender-5.2.0/doc/python_api/examples/bpy.app.timers.1.py
Normal file
@@ -0,0 +1,12 @@
|
||||
"""
|
||||
Run a Function in x Seconds
|
||||
---------------------------
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
def in_5_seconds():
|
||||
print("Hello World")
|
||||
|
||||
|
||||
bpy.app.timers.register(in_5_seconds, first_interval=5)
|
||||
13
blender-5.2.0/doc/python_api/examples/bpy.app.timers.2.py
Normal file
13
blender-5.2.0/doc/python_api/examples/bpy.app.timers.2.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""
|
||||
Run a Function every x Seconds
|
||||
------------------------------
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
def every_2_seconds():
|
||||
print("Hello World")
|
||||
return 2.0
|
||||
|
||||
|
||||
bpy.app.timers.register(every_2_seconds)
|
||||
19
blender-5.2.0/doc/python_api/examples/bpy.app.timers.3.py
Normal file
19
blender-5.2.0/doc/python_api/examples/bpy.app.timers.3.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
Run a Function n times every x seconds
|
||||
--------------------------------------
|
||||
"""
|
||||
import bpy
|
||||
|
||||
counter = 0
|
||||
|
||||
|
||||
def run_10_times():
|
||||
global counter
|
||||
counter += 1
|
||||
print(counter)
|
||||
if counter == 10:
|
||||
return None
|
||||
return 0.1
|
||||
|
||||
|
||||
bpy.app.timers.register(run_10_times)
|
||||
14
blender-5.2.0/doc/python_api/examples/bpy.app.timers.4.py
Normal file
14
blender-5.2.0/doc/python_api/examples/bpy.app.timers.4.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Assign parameters to functions
|
||||
------------------------------
|
||||
"""
|
||||
import bpy
|
||||
import functools
|
||||
|
||||
|
||||
def print_message(message):
|
||||
print("Message:", message)
|
||||
|
||||
|
||||
bpy.app.timers.register(functools.partial(print_message, "Hello"), first_interval=2.0)
|
||||
bpy.app.timers.register(functools.partial(print_message, "World"), first_interval=3.0)
|
||||
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
Introduction
|
||||
------------
|
||||
|
||||
.. warning::
|
||||
|
||||
Most of this object should only be useful if you actually manipulate i18n stuff from Python.
|
||||
If you are a regular add-on, you should only bother about :const:`contexts` member,
|
||||
and the :func:`register`/:func:`unregister` functions! The :func:`pgettext` family of functions
|
||||
should only be used in rare, specific cases (like e.g. complex "composited" UI strings...).
|
||||
|
||||
To add translations to your Python script, you must define a dictionary formatted like that:
|
||||
``{locale: {msg_key: msg_translation, ...}, ...}`` where:
|
||||
|
||||
- locale is either a lang ISO code (e.g. ``fr``), a lang+country code (e.g. ``pt_BR``),
|
||||
a lang+variant code (e.g. ``sr@latin``), or a full code (e.g. ``uz_UZ@cyrilic``).
|
||||
- msg_key is a tuple (context, org message) - use, as much as possible, the predefined :const:`contexts`.
|
||||
- msg_translation is the translated message in given language!
|
||||
|
||||
Then, call ``bpy.app.translations.register(__name__, your_dict)`` in your ``register()`` function, and
|
||||
``bpy.app.translations.unregister(__name__)`` in your ``unregister()`` one.
|
||||
|
||||
The ``Manage UI translations`` add-on has several functions to help you collect strings to translate, and
|
||||
generate the needed Python code (the translation dictionary), as well as optional intermediary po files
|
||||
if you want some... See
|
||||
`How to Translate Blender <https://developer.blender.org/docs/handbook/translating/translator_guide/>`_ and
|
||||
`Using i18n in Blender Code <https://developer.blender.org/docs/handbook/translating/developer_guide/>`_
|
||||
for more info.
|
||||
|
||||
Module References
|
||||
-----------------
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
# This block can be automatically generated by UI translations addon, which also handles conversion with PO format.
|
||||
# See also https://developer.blender.org/docs/handbook/translating/translator_guide/#translating-non-official-add-ons
|
||||
# It can (should) also be put in a different, specific py file.
|
||||
|
||||
# ##### BEGIN AUTOGENERATED I18N SECTION #####
|
||||
# NOTE: You can safely move around this auto-generated block (with the begin/end markers!),
|
||||
# and edit the translations by hand.
|
||||
# Just carefully respect the format of the tuple!
|
||||
|
||||
# Tuple of tuples ((msgctxt, msgid), (sources, gen_comments), (lang, translation, (is_fuzzy, comments)), ...)
|
||||
translations_tuple = (
|
||||
(("*", ""),
|
||||
((), ()),
|
||||
("fr_FR", "Project-Id-Version: Copy Settings 0.1.5 (r0)\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: 2013-04-18 15:27:45.563524\nPO-Revision-Date: 2013-04-18 15:38+0100\nLast-Translator: Bastien Montagne <montagne29@wanadoo.fr>\nLanguage-Team: LANGUAGE <LL@li.org>\nLanguage: __POT__\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\n",
|
||||
(False,
|
||||
("Blender's translation file (po format).",
|
||||
"Copyright (C) 2013 The Blender Foundation.",
|
||||
"This file is distributed under the same license as the Blender package.",
|
||||
"FIRST AUTHOR <EMAIL@ADDRESS>, YEAR."))),
|
||||
),
|
||||
(("Operator", "Render: Copy Settings"),
|
||||
(("bpy.types.SCENE_OT_render_copy_settings",),
|
||||
()),
|
||||
("fr_FR", "Rendu: copier réglages",
|
||||
(False, ())),
|
||||
),
|
||||
(("*", "Copy render settings from current scene to others"),
|
||||
(("bpy.types.SCENE_OT_render_copy_settings",),
|
||||
()),
|
||||
("fr_FR", "Copier les réglages de rendu depuis la scène courante vers d’autres",
|
||||
(False, ())),
|
||||
),
|
||||
# ... etc, all messages from your addon.
|
||||
)
|
||||
|
||||
translations_dict = {}
|
||||
for msg in translations_tuple:
|
||||
key = msg[0]
|
||||
for lang, trans, (is_fuzzy, comments) in msg[2:]:
|
||||
if trans and not is_fuzzy:
|
||||
translations_dict.setdefault(lang, {})[key] = trans
|
||||
|
||||
# ##### END AUTOGENERATED I18N SECTION #####
|
||||
|
||||
# Define remaining addon (operators, UI...) here.
|
||||
|
||||
|
||||
def register():
|
||||
# Usual operator/UI/etc. registration...
|
||||
|
||||
bpy.app.translations.register(__name__, translations_dict)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.app.translations.unregister(__name__)
|
||||
|
||||
# Usual operator/UI/etc. unregistration...
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
Get the property associated with a hovered button.
|
||||
Returns a tuple of the data-block, data path to the property, and array index.
|
||||
|
||||
.. note::
|
||||
|
||||
When the property doesn't have an associated :class:`bpy.types.ID` non-ID data may be returned.
|
||||
This may occur when accessing windowing data, for example, operator properties.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Example inserting keyframe for the hovered property.
|
||||
active_property = bpy.context.property
|
||||
if active_property:
|
||||
datablock, data_path, index = active_property
|
||||
datablock.keyframe_insert(data_path=data_path, index=index, frame=1)
|
||||
24
blender-5.2.0/doc/python_api/examples/bpy.data.0.py
Normal file
24
blender-5.2.0/doc/python_api/examples/bpy.data.0.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import bpy
|
||||
|
||||
|
||||
# Print all objects.
|
||||
for obj in bpy.data.objects:
|
||||
print(obj.name)
|
||||
|
||||
|
||||
# Print all scene names in a list.
|
||||
print(bpy.data.scenes.keys())
|
||||
|
||||
|
||||
# Remove mesh Cube.
|
||||
if "Cube" in bpy.data.meshes:
|
||||
mesh = bpy.data.meshes["Cube"]
|
||||
print("removing mesh", mesh)
|
||||
bpy.data.meshes.remove(mesh)
|
||||
|
||||
|
||||
# Write images into a file next to the blend.
|
||||
import os
|
||||
with open(os.path.splitext(bpy.data.filepath)[0] + ".txt", 'w') as fs:
|
||||
for image in bpy.data.images:
|
||||
fs.write("{:s} {:d} x {:d}\n".format(image.filepath, image.size[0], image.size[1]))
|
||||
53
blender-5.2.0/doc/python_api/examples/bpy.msgbus.1.py
Normal file
53
blender-5.2.0/doc/python_api/examples/bpy.msgbus.1.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""
|
||||
The message bus system can be used to receive notifications when properties of
|
||||
Blender data-blocks are changed via the data API.
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
The message bus system is triggered by updates via the RNA system. This means
|
||||
that the following updates will result in a notification on the message bus:
|
||||
|
||||
- Changes via the Python API, for example ``some_object.location.x += 3``.
|
||||
- Changes via the sliders, fields, and buttons in the user interface.
|
||||
|
||||
The following updates do **not** trigger message bus notifications:
|
||||
|
||||
- Moving objects in the 3D Viewport.
|
||||
- Changes performed by the animation system.
|
||||
|
||||
Changes done from ``msgbus`` callbacks are not included in related undo steps,
|
||||
so users can easily skip their effects by using Undo followed by Redo.
|
||||
|
||||
Unlike properties ``update`` callbacks, message bus update callbacks are postponed
|
||||
until all operators have finished executing.
|
||||
Additionally, for each property the callback is only triggered once per update cycle,
|
||||
even if the property was changed multiple times during that period.
|
||||
|
||||
Example Use
|
||||
-----------
|
||||
|
||||
Below is an example of subscription to changes in the active object's location.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
# Any Python object can act as the subscription's owner.
|
||||
owner = object()
|
||||
|
||||
subscribe_to = bpy.context.object.location
|
||||
|
||||
|
||||
def msgbus_callback(*args):
|
||||
# This will print:
|
||||
# Something changed! (1, 2, 3)
|
||||
print("Something changed!", args)
|
||||
|
||||
|
||||
bpy.msgbus.subscribe_rna(
|
||||
key=subscribe_to,
|
||||
owner=owner,
|
||||
args=(1, 2, 3),
|
||||
notify=msgbus_callback,
|
||||
)
|
||||
8
blender-5.2.0/doc/python_api/examples/bpy.msgbus.2.py
Normal file
8
blender-5.2.0/doc/python_api/examples/bpy.msgbus.2.py
Normal file
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
Some properties are converted to Python objects when you retrieve them. This
|
||||
needs to be avoided in order to create the subscription, by using
|
||||
``datablock.path_resolve("property_name", False)``:
|
||||
"""
|
||||
import bpy
|
||||
|
||||
subscribe_to = bpy.context.object.path_resolve("name", False)
|
||||
7
blender-5.2.0/doc/python_api/examples/bpy.msgbus.3.py
Normal file
7
blender-5.2.0/doc/python_api/examples/bpy.msgbus.3.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
It is also possible to create subscriptions on a property of all instances of a
|
||||
certain type:
|
||||
"""
|
||||
import bpy
|
||||
|
||||
subscribe_to = (bpy.types.Object, "location")
|
||||
56
blender-5.2.0/doc/python_api/examples/bpy.ops.0.py
Normal file
56
blender-5.2.0/doc/python_api/examples/bpy.ops.0.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
Calling Operators
|
||||
-----------------
|
||||
|
||||
Provides Python access to calling operators, this includes operators written in
|
||||
C++, Python or macros.
|
||||
|
||||
Only keyword arguments can be used to pass operator properties.
|
||||
|
||||
Operators don't have return values as you might expect,
|
||||
instead they return a set() which is made up of:
|
||||
``{'RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH'}``.
|
||||
Common return values are ``{'FINISHED'}`` and ``{'CANCELLED'}``, the latter
|
||||
meaning that the operator execution was aborted without making any changes or
|
||||
saving an undo history entry.
|
||||
|
||||
If operator was cancelled but there wasn't any reports from it with ``{'ERROR'}`` type,
|
||||
it will just return ``{'CANCELLED'}`` without raising any exceptions.
|
||||
However, if there are error reports, a ``RuntimeError`` will be raised
|
||||
after the operator finishes execution, including all error report messages,
|
||||
regardless of the return status (even if it was ``{'FINISHED'}``).
|
||||
|
||||
Calling an operator in the wrong context will raise a ``RuntimeError``,
|
||||
there is a poll() method to avoid this problem.
|
||||
|
||||
Note that the operator ID (bl_idname) in this example is ``mesh.subdivide``,
|
||||
``bpy.ops`` is just the access path for Python.
|
||||
|
||||
|
||||
Keywords and Positional Arguments
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For calling operators keywords are used for operator properties and
|
||||
positional arguments are used to define how the operator is called.
|
||||
|
||||
There are 2 optional positional arguments (documented in detail below).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.ops.test.operator(execution_context, undo)
|
||||
|
||||
- execution_context - ``str`` (enum).
|
||||
- undo - ``bool`` type.
|
||||
|
||||
|
||||
Each of these arguments is optional, but must be given in the order above.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Calling an operator.
|
||||
bpy.ops.mesh.subdivide(number_cuts=3, smoothness=0.5)
|
||||
|
||||
|
||||
# Check poll() to avoid exception.
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
31
blender-5.2.0/doc/python_api/examples/bpy.ops.1.py
Normal file
31
blender-5.2.0/doc/python_api/examples/bpy.ops.1.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Overriding Context
|
||||
------------------
|
||||
|
||||
It is possible to override context members that the operator sees, so that they
|
||||
act on specified rather than the selected or active data, or to execute an
|
||||
operator in the different part of the user interface.
|
||||
|
||||
The context overrides are passed in as keyword arguments,
|
||||
with keywords matching the context member names in ``bpy.context``.
|
||||
For example to override ``bpy.context.active_object``,
|
||||
you would pass ``active_object=object`` to :class:`bpy.types.Context.temp_override`.
|
||||
|
||||
.. note::
|
||||
|
||||
You will nearly always want to use a copy of the actual current context as basis
|
||||
(otherwise, you'll have to find and gather all needed data yourself).
|
||||
|
||||
.. note::
|
||||
|
||||
Context members are names which Blender uses for data access,
|
||||
overrides do not extend to overriding methods or any Python specific functionality.
|
||||
"""
|
||||
|
||||
# Remove all objects in scene rather than the selected ones.
|
||||
import bpy
|
||||
from bpy import context
|
||||
context_override = context.copy()
|
||||
context_override["selected_objects"] = list(context.scene.objects)
|
||||
with context.temp_override(**context_override):
|
||||
bpy.ops.object.delete()
|
||||
34
blender-5.2.0/doc/python_api/examples/bpy.ops.2.py
Normal file
34
blender-5.2.0/doc/python_api/examples/bpy.ops.2.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
.. _operator-execution_context:
|
||||
|
||||
Execution Context
|
||||
-----------------
|
||||
|
||||
When calling an operator you may want to pass the execution context.
|
||||
|
||||
This determines the context that is given for the operator to run in, and whether
|
||||
invoke() is called or only execute().
|
||||
|
||||
``EXEC_DEFAULT`` is used by default, running only the ``execute()`` method, but you may
|
||||
want the operator to take user interaction with ``INVOKE_DEFAULT`` which will also
|
||||
call invoke() if existing.
|
||||
|
||||
The execution context is one of:
|
||||
|
||||
- ``INVOKE_DEFAULT``
|
||||
- ``INVOKE_REGION_WIN``
|
||||
- ``INVOKE_REGION_CHANNELS``
|
||||
- ``INVOKE_REGION_PREVIEW``
|
||||
- ``INVOKE_AREA``
|
||||
- ``INVOKE_SCREEN``
|
||||
- ``EXEC_DEFAULT``
|
||||
- ``EXEC_REGION_WIN``
|
||||
- ``EXEC_REGION_CHANNELS``
|
||||
- ``EXEC_REGION_PREVIEW``
|
||||
- ``EXEC_AREA``
|
||||
- ``EXEC_SCREEN``
|
||||
"""
|
||||
|
||||
# Collection add popup.
|
||||
import bpy
|
||||
bpy.ops.object.collection_instance_add('INVOKE_DEFAULT')
|
||||
16
blender-5.2.0/doc/python_api/examples/bpy.ops.3.py
Normal file
16
blender-5.2.0/doc/python_api/examples/bpy.ops.3.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
It is also possible to run an operator in a particular part of the user
|
||||
interface. For this we need to pass the window, area and sometimes a region.
|
||||
"""
|
||||
|
||||
# Maximize 3d view in all windows.
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
for window in context.window_manager.windows:
|
||||
screen = window.screen
|
||||
for area in screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
with context.temp_override(window=window, area=area):
|
||||
bpy.ops.screen.screen_full_area()
|
||||
break
|
||||
27
blender-5.2.0/doc/python_api/examples/bpy.props.0.py
Normal file
27
blender-5.2.0/doc/python_api/examples/bpy.props.0.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Assigning to Existing Classes
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
Custom properties can be added to any subclass of an :class:`ID`,
|
||||
:class:`Bone` and :class:`PoseBone`.
|
||||
|
||||
These properties can be animated, accessed by the user interface and Python
|
||||
like Blender's existing properties.
|
||||
|
||||
.. warning::
|
||||
|
||||
Access to these properties might happen in threaded context, on a per-data-block level.
|
||||
This has to be carefully considered when using accessors or update callbacks.
|
||||
|
||||
Typically, these callbacks should not affect any other data that the one owned by their data-block.
|
||||
When accessing external non-Blender data, thread safety mechanisms should be considered.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
# Assign a custom property to an existing type.
|
||||
bpy.types.Material.custom_float = bpy.props.FloatProperty(name="Test Property")
|
||||
|
||||
# Test the property is there.
|
||||
bpy.data.materials[0].custom_float = 5.0
|
||||
64
blender-5.2.0/doc/python_api/examples/bpy.props.1.py
Normal file
64
blender-5.2.0/doc/python_api/examples/bpy.props.1.py
Normal file
@@ -0,0 +1,64 @@
|
||||
"""
|
||||
Operator Example
|
||||
++++++++++++++++
|
||||
|
||||
A common use of custom properties is for Python based :class:`Operator`
|
||||
classes. Test this code by running it in the text editor, or by clicking the
|
||||
button in the 3D Viewport's Tools panel. The latter will show the properties
|
||||
in the Redo panel and allow you to change them.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_property_example(bpy.types.Operator):
|
||||
bl_idname = "object.property_example"
|
||||
bl_label = "Property Example"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
self.report(
|
||||
{'INFO'}, "F: {:.2f} B: {!s} S: {!r}".format(
|
||||
self.my_float, self.my_bool, self.my_string,
|
||||
)
|
||||
)
|
||||
print('My float:', self.my_float)
|
||||
print('My bool:', self.my_bool)
|
||||
print('My string:', self.my_string)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class OBJECT_PT_property_example(bpy.types.Panel):
|
||||
bl_idname = "object_PT_property_example"
|
||||
bl_label = "Property Example"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Tool"
|
||||
|
||||
def draw(self, context):
|
||||
# You can set the property values that should be used when the user
|
||||
# presses the button in the UI.
|
||||
props = self.layout.operator('object.property_example')
|
||||
props.my_bool = True
|
||||
props.my_string = "Shouldn't that be 47?"
|
||||
|
||||
# You can set properties dynamically:
|
||||
if context.object:
|
||||
props.my_float = context.object.location.x
|
||||
else:
|
||||
props.my_float = 327
|
||||
|
||||
|
||||
bpy.utils.register_class(OBJECT_OT_property_example)
|
||||
bpy.utils.register_class(OBJECT_PT_property_example)
|
||||
|
||||
# Demo call. Be sure to also test in the 3D Viewport.
|
||||
bpy.ops.object.property_example(
|
||||
my_float=47,
|
||||
my_bool=True,
|
||||
my_string="Shouldn't that be 327?",
|
||||
)
|
||||
27
blender-5.2.0/doc/python_api/examples/bpy.props.2.py
Normal file
27
blender-5.2.0/doc/python_api/examples/bpy.props.2.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
PropertyGroup Example
|
||||
+++++++++++++++++++++
|
||||
|
||||
PropertyGroups can be used for collecting custom settings into one value
|
||||
to avoid many individual settings mixed in together.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class MaterialSettings(bpy.types.PropertyGroup):
|
||||
my_int: bpy.props.IntProperty()
|
||||
my_float: bpy.props.FloatProperty()
|
||||
my_string: bpy.props.StringProperty()
|
||||
|
||||
|
||||
bpy.utils.register_class(MaterialSettings)
|
||||
|
||||
bpy.types.Material.my_settings = bpy.props.PointerProperty(type=MaterialSettings)
|
||||
|
||||
# Test the new settings work.
|
||||
material = bpy.data.materials[0]
|
||||
|
||||
material.my_settings.my_int = 5
|
||||
material.my_settings.my_float = 3.0
|
||||
material.my_settings.my_string = "Foo"
|
||||
34
blender-5.2.0/doc/python_api/examples/bpy.props.3.py
Normal file
34
blender-5.2.0/doc/python_api/examples/bpy.props.3.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
Collection Example
|
||||
++++++++++++++++++
|
||||
|
||||
Custom properties can be added to any subclass of an :class:`ID`,
|
||||
:class:`Bone` and :class:`PoseBone`.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
# Assign a collection.
|
||||
class SceneSettingItem(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty(name="Test Property", default="Unknown")
|
||||
value: bpy.props.IntProperty(name="Test Property", default=22)
|
||||
|
||||
|
||||
bpy.utils.register_class(SceneSettingItem)
|
||||
|
||||
bpy.types.Scene.my_settings = bpy.props.CollectionProperty(type=SceneSettingItem)
|
||||
|
||||
# Assume an armature object selected.
|
||||
print("Adding 2 values!")
|
||||
|
||||
my_item = bpy.context.scene.my_settings.add()
|
||||
my_item.name = "Spam"
|
||||
my_item.value = 1000
|
||||
|
||||
my_item = bpy.context.scene.my_settings.add()
|
||||
my_item.name = "Eggs"
|
||||
my_item.value = 30
|
||||
|
||||
for my_item in bpy.context.scene.my_settings:
|
||||
print(my_item.name, my_item.value)
|
||||
34
blender-5.2.0/doc/python_api/examples/bpy.props.4.py
Normal file
34
blender-5.2.0/doc/python_api/examples/bpy.props.4.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
Update Example
|
||||
++++++++++++++
|
||||
|
||||
It can be useful to perform an action when a property is changed and can be
|
||||
used to update other properties or synchronize with external data.
|
||||
|
||||
All properties define update functions except for CollectionProperty.
|
||||
|
||||
.. warning::
|
||||
|
||||
Remember that these callbacks may be executed in threaded context.
|
||||
|
||||
.. warning::
|
||||
|
||||
If the property belongs to an Operator, the update callback's first
|
||||
parameter will be an OperatorProperties instance, rather than an instance
|
||||
of the operator itself. This means you can't access other internal functions
|
||||
of the operator, only its other properties.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def update_func(self, context):
|
||||
print("my test function", self)
|
||||
|
||||
|
||||
bpy.types.Scene.testprop = bpy.props.FloatProperty(update=update_func)
|
||||
|
||||
bpy.context.scene.testprop = 11.0
|
||||
|
||||
# >>> my test function <bpy_struct, Scene("Scene")>
|
||||
205
blender-5.2.0/doc/python_api/examples/bpy.props.5.py
Normal file
205
blender-5.2.0/doc/python_api/examples/bpy.props.5.py
Normal file
@@ -0,0 +1,205 @@
|
||||
"""
|
||||
Getter/Setter Example
|
||||
+++++++++++++++++++++
|
||||
|
||||
Accessor functions can be used for boolean, int, float, string and enum properties.
|
||||
|
||||
If ``get`` or ``set`` callbacks are defined, the property will not be stored in the ID properties
|
||||
automatically. Instead, the ``get`` and ``set`` functions will be called when the property
|
||||
is respectively read or written from the API, and are responsible to handle the data storage.
|
||||
|
||||
Note that:
|
||||
|
||||
- It is illegal to define a ``set`` callback without a matching ``get`` one.
|
||||
- When a ``get`` callback is defined but no ``set`` one, the property is read-only.
|
||||
|
||||
``get_transform`` and ``set_transform`` can be used when the returned value needs to be modified,
|
||||
but the default internal storage is still used. They can only transform the value before it is
|
||||
set or returned, but do not control how/where that data is stored.
|
||||
|
||||
.. note::
|
||||
|
||||
It is possible to define both ``get``/``set`` and ``get_transform``/``set_transform`` callbacks
|
||||
for the same property. In practice however, this should rarely be needed, as most 'transform'
|
||||
operation can also happen within a ``get``/``set`` callback.
|
||||
|
||||
.. warning::
|
||||
|
||||
Remember that these callbacks may be executed in threaded context.
|
||||
|
||||
.. warning::
|
||||
|
||||
Take care when accessing other properties in these callbacks, as it can easily trigger
|
||||
complex issues, such as infinite loops (if e.g. two properties try to also set the other
|
||||
property's value in their own ``set`` callback), or unexpected side effects due to changes
|
||||
in data, caused e.g. by an ``update`` callback.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
|
||||
# Simple property reading/writing from 'custom' IDProperties.
|
||||
# This is similar to what the RNA would do internally, albeit using it own separate,
|
||||
# internal 'system' IDProperty storage, since Blender 5.0.
|
||||
def get_float(self):
|
||||
return self.get("testprop", 0.0)
|
||||
|
||||
|
||||
def set_float(self, value):
|
||||
self["testprop"] = value
|
||||
|
||||
|
||||
bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
|
||||
|
||||
# Testing the property:
|
||||
print("test_float:", scene.test_float)
|
||||
scene.test_float = 7.5
|
||||
print("test_float:", scene.test_float)
|
||||
|
||||
# The above outputs:
|
||||
# test_float: 0.0
|
||||
# test_float: 7.5
|
||||
|
||||
|
||||
# Read-only string property, returns the current date.
|
||||
def get_date(self):
|
||||
import datetime
|
||||
return str(datetime.datetime.now())
|
||||
|
||||
|
||||
bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
|
||||
|
||||
# Testing the property:
|
||||
# scene.test_date = "blah" # This would fail, property is read-only.
|
||||
print("test_date:", scene.test_date)
|
||||
|
||||
# The above outputs something like:
|
||||
# test_date: 2018-03-14 11:36:53.158653
|
||||
|
||||
|
||||
# Boolean array.
|
||||
# - Set function stores a single boolean value, returned as the second component.
|
||||
# - Array getters must return a list or tuple.
|
||||
# - Array size must match the property vector size exactly.
|
||||
def get_array(self):
|
||||
return (True, self.get("somebool", True))
|
||||
|
||||
|
||||
def set_array(self, values):
|
||||
self["somebool"] = values[0] and values[1]
|
||||
|
||||
|
||||
bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
|
||||
|
||||
# Testing the property:
|
||||
print("test_array:", tuple(scene.test_array))
|
||||
scene.test_array = (True, False)
|
||||
print("test_array:", tuple(scene.test_array))
|
||||
|
||||
# The above outputs:
|
||||
# test_array: (True, True)
|
||||
# test_array: (True, False)
|
||||
|
||||
|
||||
# Boolean array, using 'transform' accessors.
|
||||
# Note how the same result is achieved as with previous get/set example, but using default RNA storage.
|
||||
# Transform accessors also have access to more information.
|
||||
# Also note how the stored data _is_ a two-items array.
|
||||
# - Set function stores a single boolean value, returned as the second component.
|
||||
# - Array getters must return a list or tuple.
|
||||
# - Array size must match the property vector size exactly.
|
||||
def get_array_transform(self, curr_value, is_set):
|
||||
print("Stored data:", curr_value, "(is set:", is_set, ")")
|
||||
return (True, curr_value[1])
|
||||
|
||||
|
||||
def set_array_transform(self, new_value, curr_value, is_set):
|
||||
print("New data:", new_value, "; Stored data:", curr_value, "(is set:", is_set, ")")
|
||||
return True, new_value[0] and new_value[1]
|
||||
|
||||
|
||||
bpy.types.Scene.test_array_transform = bpy.props.BoolVectorProperty(
|
||||
size=2, get_transform=get_array_transform, set_transform=set_array_transform)
|
||||
|
||||
# Testing the property:
|
||||
print("test_array_transform:", tuple(scene.test_array_transform))
|
||||
scene.test_array_transform = (True, False)
|
||||
print("test_array_transform:", tuple(scene.test_array_transform))
|
||||
|
||||
# The above outputs:
|
||||
# Stored data: (False, False) (is set: False )
|
||||
# test_array_transform: (True, False)
|
||||
# New data: (True, False) ; Stored data: (False, False) (is set: False )
|
||||
# Stored data: (True, False) (is set: True )
|
||||
# test_array_transform: (True, False)
|
||||
|
||||
|
||||
# Enum property.
|
||||
# Note: the getter/setter callback must use integer identifiers!
|
||||
test_items = [
|
||||
("RED", "Red", "", 1),
|
||||
("GREEN", "Green", "", 2),
|
||||
("BLUE", "Blue", "", 3),
|
||||
("YELLOW", "Yellow", "", 4),
|
||||
]
|
||||
|
||||
|
||||
def get_enum(self):
|
||||
import random
|
||||
return random.randint(1, 4)
|
||||
|
||||
|
||||
def set_enum(self, value):
|
||||
print("setting value", value)
|
||||
|
||||
|
||||
bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)
|
||||
|
||||
# Testing the property:
|
||||
print("test_enum:", scene.test_enum)
|
||||
scene.test_enum = 'BLUE'
|
||||
print("test_enum:", scene.test_enum)
|
||||
|
||||
# The above outputs something like:
|
||||
# test_enum: YELLOW
|
||||
# setting value 3
|
||||
# test_enum: GREEN
|
||||
|
||||
|
||||
# String, using 'transform' accessors to validate data before setting/returning it.
|
||||
def get_string_transform(self, curr_value, is_set):
|
||||
import os
|
||||
is_valid_path = os.path.exists(curr_value)
|
||||
print("Stored data:", curr_value, "(is set:", is_set, ", is valid path:", is_valid_path, ")")
|
||||
return curr_value if is_valid_path else ""
|
||||
|
||||
|
||||
def set_string_transform(self, new_value, curr_value, is_set):
|
||||
import os
|
||||
is_valid_path = os.path.exists(new_value)
|
||||
print("New data:", new_value, "(is_valid_path:", is_valid_path, ");",
|
||||
"Stored data:", curr_value, "(is set:", is_set, ")")
|
||||
return new_value if is_valid_path else curr_value
|
||||
|
||||
|
||||
bpy.types.Scene.test_string_transform = bpy.props.StringProperty(
|
||||
subtype='DIR_PATH',
|
||||
default="an/invalid/path",
|
||||
get_transform=get_string_transform,
|
||||
set_transform=set_string_transform,
|
||||
)
|
||||
|
||||
# Testing the property:
|
||||
print("test_string_transform:", scene.test_string_transform)
|
||||
scene.test_string_transform = "try\\to\\find\\me"
|
||||
print("test_string_transform:", scene.test_string_transform)
|
||||
|
||||
# The above outputs something like:
|
||||
# Stored data: an/invalid/path (is set: False , is valid path: False )
|
||||
# test_string_transform:
|
||||
# New data: try\to\find\me (is_valid_path: False ) ; Stored data: an/invalid/path (is set: False )
|
||||
# Stored data: an/invalid/path (is set: True , is valid path: False )
|
||||
# test_string_transform:
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Action Slots organize animation data within an action. Each action has slots with specific animation
|
||||
data. An animated data-block specifies an action and a slot, determining the animation data it uses.
|
||||
See the `Blender Manual <https://docs.blender.org/manual/en/5.1/animation/actions.html#action-slots>`_
|
||||
for how Action Slots are used, or the
|
||||
`technical documentation <https://developer.blender.org/docs/features/animation/>`_
|
||||
for details on the animation system's architecture.
|
||||
|
||||
Create & Access an Action Slot
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
To get started with Action Slots, you can easily create them by inserting a keyframe on an object. When you do this,
|
||||
Blender automatically creates an Action & Slot for that data-block.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Assume Suzanne mesh is present in the scene.
|
||||
suzanne = bpy.data.objects["Suzanne"]
|
||||
|
||||
# Create animation data and an action for Suzanne:
|
||||
# Slot will be automatically created.
|
||||
suzanne.keyframe_insert("location", index=0)
|
||||
|
||||
# Action slots can be accessed like this:
|
||||
action = suzanne.animation_data.action
|
||||
for slot in action.slots:
|
||||
print(f"Slot Identifier {slot.identifier!r} "
|
||||
f"with name {slot.name_display!r} "
|
||||
f"targets ID type {slot.target_id_type!r}")
|
||||
@@ -0,0 +1,23 @@
|
||||
"""
|
||||
Manually Create an Action Slot
|
||||
++++++++++++++++++++++++++++++
|
||||
If required you can also manually create Action Slots on an Action. Note the ``target_id_type``
|
||||
that matches the data-block type. Identifiers start with a prefix based on the ID type,
|
||||
e.g. "OB" for objects, followed by the name. There can be identifiers like ``OBSuzanne``
|
||||
and ``MESuzanne`` and the name (``Suzanne``) can be shared between them. This is intentional,
|
||||
so that the slots and the datablocks can have the same name.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Actions creation.
|
||||
action = bpy.data.actions.new("SuzanneAction")
|
||||
|
||||
# Creation of slots requires an ID type and a name.
|
||||
slot = action.slots.new(id_type='OBJECT', name="Suzanne")
|
||||
print(f"slot type={slot.target_id_type!r} "
|
||||
f"name={slot.name_display!r} "
|
||||
f"identifier={slot.identifier!r}")
|
||||
|
||||
# Output:
|
||||
# slot type=OBJECT name=Suzanne identifier=OBSuzanne
|
||||
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Explicitly Assigning Action Slots
|
||||
+++++++++++++++++++++++++++++++++
|
||||
An action slot is compatible with a data-block if the slot's ``target_id_type`` matches the data-block's type.
|
||||
If there are multiple slots on the Action, and you want to just pick the first one that's
|
||||
compatible, use the following code. ``anim_data.action_suitable_slots`` can be used `after` the
|
||||
Action has been assigned; it is a list of action slots of that Action, but only the ones that
|
||||
are actually compatible with the owner of anim_data (in this case, Suzanne).
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Assume Suzanne mesh is present in the scene.
|
||||
suzanne = bpy.data.objects["Suzanne"]
|
||||
|
||||
# Create an action with an object slot.
|
||||
action = bpy.data.actions.new("SuzanneAction")
|
||||
action.slots.new(id_type='OBJECT', name="Suzanne")
|
||||
|
||||
# If there are multiple slots on the Action, pick the first one that's compatible.
|
||||
anim_data = suzanne.animation_data_create()
|
||||
anim_data.action = action
|
||||
assert anim_data.action_suitable_slots, "expecting at least one suitable slot"
|
||||
anim_data.action_slot = anim_data.action_suitable_slots[0]
|
||||
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Finding Action Slot Users
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
To return a list of the data-blocks that are animated by a specific slot of an Action,
|
||||
use the ``users()`` method of the ActionSlot.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# Iterate through all actions in the Blender data.
|
||||
print("Action & slot users:")
|
||||
for action in bpy.data.actions:
|
||||
for slot in action.slots:
|
||||
# Return the data-blocks that are animated by this slot of this action
|
||||
users = slot.users()
|
||||
print(f"{action.name:20} slot={slot.identifier:12s} users: {users}")
|
||||
@@ -0,0 +1,73 @@
|
||||
bl_info = {
|
||||
"name": "Example Add-on Preferences",
|
||||
"author": "Your Name Here",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 65, 0),
|
||||
"location": "SpaceBar Search -> Add-on Preferences Example",
|
||||
"description": "Example Add-on",
|
||||
"warning": "",
|
||||
"doc_url": "",
|
||||
"tracker_url": "",
|
||||
"category": "Object",
|
||||
}
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator, AddonPreferences
|
||||
from bpy.props import StringProperty, IntProperty, BoolProperty
|
||||
|
||||
|
||||
class ExampleAddonPreferences(AddonPreferences):
|
||||
# This must match the add-on name, use `__package__`
|
||||
# when defining this for add-on extensions or a sub-module of a Python package.
|
||||
bl_idname = __name__
|
||||
|
||||
filepath: StringProperty(
|
||||
name="Example File Path",
|
||||
subtype='FILE_PATH',
|
||||
)
|
||||
number: IntProperty(
|
||||
name="Example Number",
|
||||
default=4,
|
||||
)
|
||||
boolean: BoolProperty(
|
||||
name="Example Boolean",
|
||||
default=False,
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="This is a preferences view for our add-on")
|
||||
layout.prop(self, "filepath")
|
||||
layout.prop(self, "number")
|
||||
layout.prop(self, "boolean")
|
||||
|
||||
|
||||
class OBJECT_OT_addon_prefs_example(Operator):
|
||||
"""Display example preferences"""
|
||||
bl_idname = "object.addon_prefs_example"
|
||||
bl_label = "Add-on Preferences Example"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
preferences = context.preferences
|
||||
addon_prefs = preferences.addons[__name__].preferences
|
||||
|
||||
info = "Path: {:s}, Number: {:d}, Boolean {!r}".format(
|
||||
addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean,
|
||||
)
|
||||
self.report({'INFO'}, info)
|
||||
print(info)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# Registration
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_addon_prefs_example)
|
||||
bpy.utils.register_class(ExampleAddonPreferences)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_addon_prefs_example)
|
||||
bpy.utils.unregister_class(ExampleAddonPreferences)
|
||||
114
blender-5.2.0/doc/python_api/examples/bpy.types.Attribute.0.py
Normal file
114
blender-5.2.0/doc/python_api/examples/bpy.types.Attribute.0.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""
|
||||
Attributes are used to store data that corresponds to geometry elements.
|
||||
Geometry elements are items in one of the geometry domains like points, curves, or faces.
|
||||
|
||||
An attribute has a ``name``, a ``type``, and is stored on a ``domain``.
|
||||
|
||||
``name``
|
||||
The name of this attribute. Names have to be unique within the same geometry.
|
||||
If the name starts with a ``.``, the attribute is hidden from the UI.
|
||||
``type``
|
||||
The type of data that this attribute stores, e.g. a float, integer, color, etc.
|
||||
See `Attribute Type Items <bpy_types_enum_items/attribute_type_items.html>`__.
|
||||
``domain``
|
||||
The geometry domain that the attribute is stored on.
|
||||
See `Attribute Domain Items <bpy_types_enum_items/attribute_domain_items.html>`__.
|
||||
|
||||
|
||||
Using Attributes
|
||||
++++++++++++++++
|
||||
|
||||
Attributes can be stored on geometries like :class:`Mesh`, :class:`Curves`, :class:`PointCloud`, etc.
|
||||
These geometries have attribute groups (usually called ``attributes``).
|
||||
Using the groups, attributes can then be accessed by their name:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
radii = curves.attributes["radius"]
|
||||
|
||||
Creating and storing custom attributes is done using the ``attributes.new`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Add a new attribute named `my_attribute_name` of type `float` on the point domain of the geometry.
|
||||
my_attribute = curves.attributes.new("my_attribute_name", 'FLOAT', 'POINT')
|
||||
|
||||
Removing attributes can be done like so:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
attribute = drawing.attributes["some_attribute"]
|
||||
drawing.attributes.remove(attribute)
|
||||
|
||||
.. note::
|
||||
|
||||
Some attributes are required and cannot be removed, like ``"position"``.
|
||||
|
||||
Attribute values are read by accessing their ``attribute.data`` collection property.
|
||||
However, in cases where multiple values should be read at once,
|
||||
it is better to use the :class:`bpy_prop_collection.foreach_get` function and read the values into a ``numpy`` buffer.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import numpy as np
|
||||
|
||||
# Get the radius attribute.
|
||||
radii = curves.attributes["radius"]
|
||||
# Print the radius of the first point.
|
||||
print(radii.data[0].value)
|
||||
# Output: 0.005
|
||||
|
||||
# Get the total number of points.
|
||||
num_points = attributes.domain_size('POINT')
|
||||
# Create an empty buffer to read all the radii into.
|
||||
radii_data = np.zeros(num_points, dtype=np.float32)
|
||||
# Read all the radii of the curves into `radii_data` at once.
|
||||
radii.data.foreach_get('value', radii_data)
|
||||
# Print all the radii.
|
||||
print(radii_data)
|
||||
# Output: [0.1, 0.2, 0.3, 0.4, ... ]
|
||||
|
||||
.. note::
|
||||
|
||||
Some attribute types use different named properties to access their value.
|
||||
Instead of ``value``, vectors use ``vector``, and colors use ``color``.
|
||||
|
||||
Writing to different attribute types is very similar. You can simply assign to a value directly.
|
||||
Again, when writing to multiple values, it is recommended to use the :class:`bpy_prop_collection.foreach_set` function
|
||||
to write the values from a ``numpy`` buffer.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import numpy as np
|
||||
|
||||
radii = curves.attributes["radius"]
|
||||
# Write a radius with a value of 0.5 to the first point.
|
||||
radii.data[0].value = 0.5
|
||||
print(radii.data[0].value)
|
||||
# Output: 0.5
|
||||
|
||||
num_points = attributes.domain_size('POINT')
|
||||
# Generate random radii with values between 0.001 and 0.05 using numpy.
|
||||
new_radii = np.random.uniform(0.001, 0.05, num_points)
|
||||
# Write the new radii to the radius attribute.
|
||||
radii.data.foreach_set('value', new_radii)
|
||||
|
||||
|
||||
The :class:`bpy_prop_collection.foreach_get` / :class:`bpy_prop_collection.foreach_set` methods require a flat array.
|
||||
This is sometimes not desirable, e.g. when reading/writing positions, which are 3D vectors.
|
||||
In these cases, it's possible to use ``np.ravel`` to pass the data as a flat array:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
num_points = attributes.domain_size('POINT')
|
||||
positions = curves.attributes['position']
|
||||
# Here, we're using a numpy array with shape (num_points, 3) so that each
|
||||
# element is a 3d vector.
|
||||
positions_data = np.zeros((num_points, 3), dtype=np.float32)
|
||||
# The `np.ravel` function will pass the `positions_data` as a flat array
|
||||
# without changing the original shape.
|
||||
positions.data.foreach_get('vector', np.ravel(positions_data))
|
||||
print(positions_data)
|
||||
# Output: [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], ...]
|
||||
|
||||
"""
|
||||
@@ -0,0 +1,34 @@
|
||||
import bpy
|
||||
|
||||
filepath = "//link_library.blend"
|
||||
|
||||
# Load a single scene we know the name of.
|
||||
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
|
||||
data_dst.scenes = ["Scene"]
|
||||
|
||||
|
||||
# Load all meshes.
|
||||
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
|
||||
data_dst.meshes = data_src.meshes
|
||||
|
||||
|
||||
# Link all objects starting with "A".
|
||||
with bpy.data.libraries.load(filepath, link=True) as (data_src, data_dst):
|
||||
data_dst.objects = [name for name in data_src.objects if name.startswith("A")]
|
||||
|
||||
|
||||
# Append everything.
|
||||
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
|
||||
for attr in dir(data_dst):
|
||||
setattr(data_dst, attr, getattr(data_src, attr))
|
||||
|
||||
|
||||
# The loaded objects can be accessed from `data_dst` outside of the context
|
||||
# since loading the data replaces the strings for the data-blocks or None
|
||||
# if the data-block could not be loaded.
|
||||
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
|
||||
data_dst.meshes = data_src.meshes
|
||||
# Now operate directly on the loaded data.
|
||||
for mesh in data_dst.meshes:
|
||||
if mesh is not None:
|
||||
print(mesh.name)
|
||||
@@ -0,0 +1,18 @@
|
||||
import bpy
|
||||
|
||||
filepath = "//new_library.blend"
|
||||
|
||||
# Write selected objects and their data to a blend file.
|
||||
data_blocks = set(bpy.context.selected_objects)
|
||||
bpy.data.libraries.write(filepath, data_blocks)
|
||||
|
||||
|
||||
# Write all meshes starting with a capital letter and
|
||||
# set them with fake-user enabled so they aren't lost on re-saving.
|
||||
data_blocks = {mesh for mesh in bpy.data.meshes if mesh.name[:1].isupper()}
|
||||
bpy.data.libraries.write(filepath, data_blocks, fake_user=True)
|
||||
|
||||
|
||||
# Write all materials, textures and node groups to a library.
|
||||
data_blocks = {*bpy.data.materials, *bpy.data.textures, *bpy.data.node_groups}
|
||||
bpy.data.libraries.write(filepath, data_blocks)
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
This method enables conversions between Local and Pose space for bones in
|
||||
the middle of updating the armature without having to update dependencies
|
||||
after each change, by manually carrying updated matrices in a recursive walk.
|
||||
"""
|
||||
|
||||
|
||||
def set_pose_matrices(obj, matrix_map):
|
||||
"Assign pose space matrices of all bones at once, ignoring constraints."
|
||||
|
||||
def rec(pbone, parent_matrix):
|
||||
if pbone.name in matrix_map:
|
||||
matrix = matrix_map[pbone.name]
|
||||
|
||||
# # Instead of:
|
||||
# pbone.matrix = matrix
|
||||
# bpy.context.view_layer.update()
|
||||
|
||||
# Compute and assign local matrix, using the new parent matrix.
|
||||
if pbone.parent:
|
||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||
matrix,
|
||||
pbone.bone.matrix_local,
|
||||
parent_matrix=parent_matrix,
|
||||
parent_matrix_local=pbone.parent.bone.matrix_local,
|
||||
invert=True
|
||||
)
|
||||
else:
|
||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||
matrix,
|
||||
pbone.bone.matrix_local,
|
||||
invert=True
|
||||
)
|
||||
else:
|
||||
# Compute the updated pose matrix from local and new parent matrix.
|
||||
if pbone.parent:
|
||||
matrix = pbone.bone.convert_local_to_pose(
|
||||
pbone.matrix_basis,
|
||||
pbone.bone.matrix_local,
|
||||
parent_matrix=parent_matrix,
|
||||
parent_matrix_local=pbone.parent.bone.matrix_local,
|
||||
)
|
||||
else:
|
||||
matrix = pbone.bone.convert_local_to_pose(
|
||||
pbone.matrix_basis,
|
||||
pbone.bone.matrix_local,
|
||||
)
|
||||
|
||||
# Recursively process children, passing the new matrix through.
|
||||
for child in pbone.children:
|
||||
rec(child, matrix)
|
||||
|
||||
# Scan all bone trees from their roots.
|
||||
for pbone in obj.pose.bones:
|
||||
if not pbone.parent:
|
||||
rec(pbone, None)
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
Overriding the context can be used to temporarily activate another ``window`` / ``area`` & ``region``,
|
||||
as well as other members such as the ``active_object`` or ``bone``.
|
||||
|
||||
Notes:
|
||||
|
||||
- When overriding window, area and regions: the arguments must be consistent,
|
||||
so any region argument that's passed in must be contained by the current area or the area passed in.
|
||||
The same goes for the area needing to be contained in the current window.
|
||||
|
||||
- Temporary context overrides may be nested, when this is done, members will be added to the existing overrides.
|
||||
|
||||
- Context members are restored outside the scope of the context-manager.
|
||||
The only exception to this is when the data is no longer available.
|
||||
|
||||
In the event windowing data was removed (for example), the state of the context is left as-is.
|
||||
While this isn't likely to happen, explicit window operation such as closing windows or loading a new file
|
||||
remove the windowing data that was set before the temporary context was created.
|
||||
"""
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Overriding the context can be useful to set the context after loading files
|
||||
(which would otherwise be None). For example:
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
# Reload the current file and select all.
|
||||
bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath)
|
||||
window = context.window_manager.windows[0]
|
||||
with context.temp_override(window=window):
|
||||
bpy.ops.mesh.primitive_uv_sphere_add()
|
||||
# The context override is needed so it's possible to set edit-mode.
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
This example shows how it's possible to add an object to the scene in another window.
|
||||
"""
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
win_active = context.window
|
||||
win_other = None
|
||||
for win_iter in context.window_manager.windows:
|
||||
if win_iter != win_active:
|
||||
win_other = win_iter
|
||||
break
|
||||
|
||||
# Add cube in the other window.
|
||||
with context.temp_override(window=win_other):
|
||||
bpy.ops.mesh.primitive_cube_add()
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
**Logging Context Member Access**
|
||||
|
||||
Context members can be logged by calling ``logging_set(True)`` on the "with" target of a temporary override.
|
||||
This will log the members that are being accessed during the operation and may
|
||||
assist in debugging when it is unclear which members need to be overridden.
|
||||
|
||||
In the event an operator fails to execute because of a missing context member, logging may help
|
||||
identify which member is required.
|
||||
|
||||
This example shows how to log which context members are being accessed.
|
||||
Log statements are printed to your system's console.
|
||||
|
||||
.. important::
|
||||
|
||||
Not all operators rely on Context Members and therefore will not be affected by
|
||||
:class:`bpy.types.Context.temp_override`, use logging to what members if any are accessed.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
my_objects = [context.scene.camera]
|
||||
|
||||
with context.temp_override(selected_objects=my_objects) as override:
|
||||
override.logging_set(
|
||||
True, # Enable logging.
|
||||
hide_missing=True, # Don't show failed attempts.
|
||||
)
|
||||
bpy.ops.object.delete()
|
||||
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Dependency graph: Evaluated ID example
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
This example demonstrates access to the evaluated ID (such as object, material, etc.) state from
|
||||
an original ID.
|
||||
This is needed every time one needs to access state with animation, constraints, and modifiers
|
||||
taken into account.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_evaluated_example(bpy.types.Operator):
|
||||
"""Access evaluated object state and do something with it"""
|
||||
bl_label = "DEG Access Evaluated Object"
|
||||
bl_idname = "object.evaluated_example"
|
||||
|
||||
def execute(self, context):
|
||||
# This is an original object. Its data does not have any modifiers applied.
|
||||
obj = context.object
|
||||
if obj is None or obj.type != 'MESH':
|
||||
self.report({'INFO'}, "No active mesh object to get info from")
|
||||
return {'CANCELLED'}
|
||||
# Evaluated object exists within a specific dependency graph.
|
||||
# We will request evaluated object from the dependency graph which corresponds to the
|
||||
# current scene and view layer.
|
||||
#
|
||||
# NOTE: This call ensure the dependency graph is fully evaluated. This might be expensive
|
||||
# if changes were made to the scene, but is needed to ensure no dangling or incorrect
|
||||
# pointers are exposed.
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
# Actually request evaluated object.
|
||||
#
|
||||
# This object has animation and drivers applied on it, together with constraints and
|
||||
# modifiers.
|
||||
#
|
||||
# For mesh objects the object.data will be a mesh with all modifiers applied.
|
||||
# This means that in access to vertices or faces after modifier stack happens via fields of
|
||||
# object_eval.object.
|
||||
#
|
||||
# For other types of objects the object_eval.data does not have modifiers applied on it,
|
||||
# but has animation applied.
|
||||
#
|
||||
# NOTE: All ID types have `evaluated_get()`, including materials, node trees, worlds.
|
||||
object_eval = obj.evaluated_get(depsgraph)
|
||||
mesh_eval = object_eval.data
|
||||
self.report({'INFO'}, f"Number of evaluated vertices: {len(mesh_eval.vertices)}")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_evaluated_example)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_evaluated_example)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
Dependency graph: Original object example
|
||||
+++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
This example demonstrates access to the original ID.
|
||||
Such access is needed to check whether object is selected, or to compare pointers.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_original_example(bpy.types.Operator):
|
||||
"""Access original object and do something with it"""
|
||||
bl_label = "DEG Access Original Object"
|
||||
bl_idname = "object.original_example"
|
||||
|
||||
def check_object_selected(self, object_eval):
|
||||
# Selection depends on a context and is only valid for original objects. This means we need
|
||||
# to request the original object from the known evaluated one.
|
||||
#
|
||||
# NOTE: All ID types have an `original` field.
|
||||
obj = object_eval.original
|
||||
return obj.select_get()
|
||||
|
||||
def execute(self, context):
|
||||
# NOTE: It seems redundant to iterate over original objects to request evaluated ones
|
||||
# just to get original back. But we want to keep example as short as possible, but in real
|
||||
# world there are cases when evaluated object is coming from a more meaningful source.
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
for obj in context.editable_objects:
|
||||
object_eval = obj.evaluated_get(depsgraph)
|
||||
if self.check_object_selected(object_eval):
|
||||
self.report({'INFO'}, f"Object is selected: {object_eval.name}")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_original_example)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_original_example)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
Dependency graph: Iterate over all object instances
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Sometimes it is needed to know all the instances with their matrices (for example, when writing an
|
||||
exporter or a custom render engine).
|
||||
This example shows how to access all objects and instances in the scene.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_object_instances(bpy.types.Operator):
|
||||
"""Access original object and do something with it"""
|
||||
bl_label = "DEG Iterate Object Instances"
|
||||
bl_idname = "object.object_instances"
|
||||
|
||||
def execute(self, context):
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
for object_instance in depsgraph.object_instances:
|
||||
# This is an object which is being instanced.
|
||||
obj = object_instance.object
|
||||
# `is_instance` denotes whether the object is coming from instances (as an opposite of
|
||||
# being an emitting object. )
|
||||
if not object_instance.is_instance:
|
||||
print(f"Object {obj.name} at {object_instance.matrix_world}")
|
||||
else:
|
||||
# Instanced will additionally have fields like uv, random_id and others which are
|
||||
# specific for instances. See Python API for DepsgraphObjectInstance for details,
|
||||
print(f"Instance of {obj.name} at {object_instance.matrix_world}")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_object_instances)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_object_instances)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
Dependency graph: Object.to_mesh()
|
||||
+++++++++++++++++++++++++++++++++++
|
||||
|
||||
Function to get a mesh from any object with geometry. It is typically used by exporters, render
|
||||
engines and tools that need to access the evaluated mesh as displayed in the viewport.
|
||||
|
||||
Object.to_mesh() is closely interacting with dependency graph: its behavior depends on whether it
|
||||
is used on original or evaluated object.
|
||||
|
||||
When is used on original object, the result mesh is calculated from the object without taking
|
||||
animation or modifiers into account:
|
||||
|
||||
- For meshes this is similar to duplicating the source mesh.
|
||||
- For curves this disables own modifiers, and modifiers of objects used as bevel and taper.
|
||||
- For meta-balls this produces an empty mesh since polygonization is done as a modifier evaluation.
|
||||
|
||||
When is used on evaluated object all modifiers are taken into account.
|
||||
|
||||
.. note:: The result mesh is owned by the object. It can be freed by calling :meth:`~Object.to_mesh_clear`.
|
||||
.. note::
|
||||
The result mesh must be treated as temporary, and cannot be referenced from objects in the main
|
||||
database. If the mesh intended to be used in a persistent manner use :meth:`~BlendDataMeshes.new_from_object`
|
||||
instead.
|
||||
.. note:: If object does not have geometry (i.e. camera) the functions returns None.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_object_to_mesh(bpy.types.Operator):
|
||||
"""Convert selected object to mesh and show number of vertices"""
|
||||
bl_label = "DEG Object to Mesh"
|
||||
bl_idname = "object.object_to_mesh"
|
||||
|
||||
def execute(self, context):
|
||||
# Access input original object.
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
self.report({'INFO'}, "No active mesh object to convert to mesh")
|
||||
return {'CANCELLED'}
|
||||
# Avoid annoying None checks later on.
|
||||
if obj.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
|
||||
self.report({'INFO'}, "Object cannot be converted to mesh")
|
||||
return {'CANCELLED'}
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
# Invoke to_mesh() for original object.
|
||||
mesh_from_orig = obj.to_mesh()
|
||||
self.report({'INFO'}, f"{len(mesh_from_orig.vertices)} in new mesh without modifiers.")
|
||||
# Remove temporary mesh.
|
||||
obj.to_mesh_clear()
|
||||
# Invoke to_mesh() for evaluated object.
|
||||
object_eval = obj.evaluated_get(depsgraph)
|
||||
mesh_from_eval = object_eval.to_mesh()
|
||||
self.report({'INFO'}, f"{len(mesh_from_eval.vertices)} in new mesh with modifiers.")
|
||||
# Remove temporary mesh.
|
||||
object_eval.to_mesh_clear()
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_object_to_mesh)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_object_to_mesh)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
Dependency graph: bpy.data.meshes.new_from_object()
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Function to copy a new mesh from any object with geometry. The mesh is added to the main
|
||||
database and can be referenced by objects. Typically used by tools that create new objects
|
||||
or apply modifiers.
|
||||
|
||||
When is used on original object, the result mesh is calculated from the object without taking
|
||||
animation or modifiers into account:
|
||||
|
||||
- For meshes this is similar to duplicating the source mesh.
|
||||
- For curves this disables own modifiers, and modifiers of objects used as bevel and taper.
|
||||
- For meta-balls this produces an empty mesh since polygonization is done as a modifier evaluation.
|
||||
|
||||
When is used on evaluated object all modifiers are taken into account.
|
||||
|
||||
All the references (such as materials) are re-mapped to original. This ensures validity and
|
||||
consistency of the main database.
|
||||
|
||||
.. note:: If object does not have geometry (i.e. camera) the functions returns None.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_mesh_from_object(bpy.types.Operator):
|
||||
"""Convert selected object to mesh and show number of vertices"""
|
||||
bl_label = "DEG Mesh From Object"
|
||||
bl_idname = "object.mesh_from_object"
|
||||
|
||||
def execute(self, context):
|
||||
# Access input original object.
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
self.report({'INFO'}, "No active mesh object to convert to mesh")
|
||||
return {'CANCELLED'}
|
||||
# Avoid annoying None checks later on.
|
||||
if obj.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
|
||||
self.report({'INFO'}, "Object cannot be converted to mesh")
|
||||
return {'CANCELLED'}
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
object_eval = obj.evaluated_get(depsgraph)
|
||||
mesh_from_eval = bpy.data.meshes.new_from_object(object_eval)
|
||||
self.report({'INFO'}, f"{len(mesh_from_eval.vertices)} in new mesh, and is ready for use!")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_mesh_from_object)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_mesh_from_object)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Dependency graph: Simple exporter
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
This example is a combination of all previous ones, and shows how to write a simple exporter
|
||||
script.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_simple_exporter(bpy.types.Operator):
|
||||
"""Simple (fake) exporter of selected objects"""
|
||||
bl_label = "DEG Export Selected"
|
||||
bl_idname = "object.simple_exporter"
|
||||
|
||||
apply_modifiers: bpy.props.BoolProperty(name="Apply Modifiers")
|
||||
|
||||
def execute(self, context):
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
for object_instance in depsgraph.object_instances:
|
||||
if not self.is_object_instance_from_selected(object_instance):
|
||||
# We only export selected objects.
|
||||
continue
|
||||
# NOTE: This will create a mesh for every instance, which is not ideal at all. In
|
||||
# reality destination format will support some sort of instancing mechanism, so the
|
||||
# code here will simply say "instance this object at object_instance.matrix_world".
|
||||
mesh = self.create_mesh_for_object_instance(object_instance)
|
||||
if mesh is None:
|
||||
# Happens for non-geometry objects.
|
||||
continue
|
||||
print(f"Exporting mesh with {len(mesh.vertices)} vertices "
|
||||
f"at {object_instance.matrix_world}")
|
||||
|
||||
self.clear_mesh_for_object_instance(object_instance)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def is_object_instance_from_selected(self, object_instance):
|
||||
# For instanced objects we check selection of their instancer (more accurately: check
|
||||
# selection status of the original object corresponding to the instancer).
|
||||
if object_instance.parent:
|
||||
return object_instance.parent.original.select_get()
|
||||
# For non-instanced objects we check selection state of the original object.
|
||||
return object_instance.object.original.select_get()
|
||||
|
||||
def create_mesh_for_object_instance(self, object_instance):
|
||||
if self.apply_modifiers:
|
||||
return object_instance.object.to_mesh()
|
||||
else:
|
||||
return object_instance.object.original.to_mesh()
|
||||
|
||||
def clear_mesh_for_object_instance(self, object_instance):
|
||||
if self.apply_modifiers:
|
||||
return object_instance.object.to_mesh_clear()
|
||||
else:
|
||||
return object_instance.object.original.to_mesh_clear()
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_simple_exporter)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_simple_exporter)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
Dependency graph: Object.to_curve()
|
||||
+++++++++++++++++++++++++++++++++++
|
||||
|
||||
Function to get a curve from text and curve objects. It is typically used by exporters, render
|
||||
engines, and tools that need to access the curve representing the object.
|
||||
|
||||
The function takes the evaluated dependency graph as a required parameter and optionally a boolean
|
||||
apply_modifiers which defaults to false. If apply_modifiers is true and the object is a curve object,
|
||||
the spline deform modifiers are applied on the control points. Note that constructive modifiers and
|
||||
modifiers that are not spline-enabled will not be applied. So modifiers like Array will not be applied
|
||||
and deform modifiers that have Apply On Spline disabled will not be applied.
|
||||
|
||||
If the object is a text object. The text will be converted into a 3D curve and returned. Modifiers are
|
||||
never applied on text objects and apply_modifiers will be ignored. If the object is neither a curve nor
|
||||
a text object, an error will be reported.
|
||||
|
||||
.. note:: The resulting curve is owned by the object. It can be freed by calling :meth:`~Object.to_curve_clear`.
|
||||
.. note::
|
||||
The resulting curve must be treated as temporary, and cannot be referenced from objects in the main
|
||||
database.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_object_to_curve(bpy.types.Operator):
|
||||
"""Convert selected object to curve and show number of splines"""
|
||||
bl_label = "DEG Object to Curve"
|
||||
bl_idname = "object.object_to_curve"
|
||||
|
||||
def execute(self, context):
|
||||
# Access input original object.
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
self.report({'INFO'}, "No active object to convert to curve")
|
||||
return {'CANCELLED'}
|
||||
if obj.type not in {'CURVE', 'FONT'}:
|
||||
self.report({'INFO'}, "Object cannot be converted to curve")
|
||||
return {'CANCELLED'}
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
# Invoke to_curve() without applying modifiers.
|
||||
curve_without_modifiers = obj.to_curve(depsgraph)
|
||||
self.report({'INFO'}, f"{len(curve_without_modifiers.splines)} splines in a new curve without modifiers.")
|
||||
# Remove temporary curve.
|
||||
obj.to_curve_clear()
|
||||
# Invoke to_curve() with applying modifiers.
|
||||
curve_with_modifiers = obj.to_curve(depsgraph, apply_modifiers=True)
|
||||
self.report({'INFO'}, f"{len(curve_with_modifiers.splines)} splines in new curve with modifiers.")
|
||||
# Remove temporary curve.
|
||||
obj.to_curve_clear()
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_object_to_curve)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_object_to_curve)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
Basic FileHandler for importing a single file
|
||||
---------------------------------------------
|
||||
|
||||
A file handler allows custom drag-and-drop behavior to be associated with a given ``Operator``
|
||||
(:class:`FileHandler.bl_import_operator`) and set of file extensions
|
||||
(:class:`FileHandler.bl_file_extensions`). Control over which area of the UI accepts the
|
||||
drag-in-drop action is specified using the :class:`FileHandler.poll_drop` method.
|
||||
|
||||
Similar to operators that use a file select window, operators participating in drag-and-drop, and
|
||||
only accepting a single file, must define the following property:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE'})
|
||||
|
||||
This ``filepath`` property will be set to the full path of the file dropped by the user.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class CurveTextImport(bpy.types.Operator):
|
||||
"""
|
||||
Creates a text object from a text file.
|
||||
"""
|
||||
bl_idname = "curve.text_import"
|
||||
bl_label = "Import a text file as text object"
|
||||
|
||||
# This Operator supports processing one `.txt` file at a time. The following file-path
|
||||
# property must be defined.
|
||||
filepath: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE'})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.area and context.area.type == "VIEW_3D")
|
||||
|
||||
def execute(self, context):
|
||||
# Direct calls to this Operator may use unsupported file-paths. Ensure the incoming
|
||||
# file-path is one that is supported.
|
||||
if not self.filepath or not self.filepath.endswith(".txt"):
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Create a Blender Text object from the contents of the provided file.
|
||||
with open(self.filepath) as file:
|
||||
text_curve = bpy.data.curves.new(type="FONT", name="Text")
|
||||
text_curve.body = ''.join(file.readlines())
|
||||
text_object = bpy.data.objects.new(name="Text", object_data=text_curve)
|
||||
bpy.context.scene.collection.objects.link(text_object)
|
||||
return {'FINISHED'}
|
||||
|
||||
# By default the file handler invokes the operator with the file-path property set. If the
|
||||
# operator also supports being invoked with no file-path set, and allows the user to pick from a
|
||||
# file select window instead, the following logic can be used.
|
||||
#
|
||||
# Note: It is important to use `options={'SKIP_SAVE'}` when defining the file-path property to
|
||||
# avoid prior values from being reused on subsequent calls.
|
||||
|
||||
def invoke(self, context, event):
|
||||
if self.filepath:
|
||||
return self.execute(context)
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
# Define a file handler that supports the following set of conditions:
|
||||
# - Execute the `curve.text_import` operator
|
||||
# - When `.txt` files are dropped in the 3D Viewport
|
||||
class CURVE_FH_text_import(bpy.types.FileHandler):
|
||||
bl_idname = "CURVE_FH_text_import"
|
||||
bl_label = "File handler for curve text object import"
|
||||
bl_import_operator = "curve.text_import"
|
||||
bl_file_extensions = ".txt"
|
||||
|
||||
@classmethod
|
||||
def poll_drop(cls, context):
|
||||
return (context.area and context.area.type == 'VIEW_3D')
|
||||
|
||||
|
||||
bpy.utils.register_class(CurveTextImport)
|
||||
bpy.utils.register_class(CURVE_FH_text_import)
|
||||
109
blender-5.2.0/doc/python_api/examples/bpy.types.FileHandler.2.py
Normal file
109
blender-5.2.0/doc/python_api/examples/bpy.types.FileHandler.2.py
Normal file
@@ -0,0 +1,109 @@
|
||||
"""
|
||||
FileHandler for Importing multiple files and exposing Operator options
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Operators which support being executed with multiple files from drag-and-drop require the
|
||||
following properties be defined:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
directory: StringProperty(subtype='DIR_PATH', options={'SKIP_SAVE', 'HIDDEN'})
|
||||
files: CollectionProperty(type=OperatorFileListElement, options={'SKIP_SAVE', 'HIDDEN'})
|
||||
|
||||
These ``directory`` and ``files`` properties will be set with the necessary data from the
|
||||
drag-and-drop operation.
|
||||
|
||||
Additionally, if the operator provides operator properties that need to be accessible to the user,
|
||||
the :class:`ImportHelper.invoke_popup` method can be used to show a dialog leveraging the standard
|
||||
:class:`Operator.draw` method for layout and display.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
class ShaderScriptImport(bpy.types.Operator, ImportHelper):
|
||||
"""
|
||||
Creates one or more Shader Script nodes from text files.
|
||||
"""
|
||||
bl_idname = "shader.script_import"
|
||||
bl_label = "Import a text file as a script node"
|
||||
|
||||
# This Operator supports processing multiple `.txt` files at a time. The following properties
|
||||
# must be defined.
|
||||
directory: bpy.props.StringProperty(subtype='DIR_PATH', options={'SKIP_SAVE', 'HIDDEN'})
|
||||
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'SKIP_SAVE', 'HIDDEN'})
|
||||
|
||||
# Allow the user to choose whether the node's label is set or not
|
||||
set_label: bpy.props.BoolProperty(name="Set Label", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (
|
||||
context.region and context.region.type == 'WINDOW' and
|
||||
context.area and context.area.ui_type == 'ShaderNodeTree' and
|
||||
context.object and context.object.type == 'MESH' and
|
||||
context.material
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
# The directory property must be set.
|
||||
if not self.directory:
|
||||
return {'CANCELLED'}
|
||||
|
||||
x = 0.0
|
||||
y = 0.0
|
||||
for file in self.files:
|
||||
# Direct calls to this Operator may use unsupported file-paths. Ensure the incoming
|
||||
# files are ones that are supported.
|
||||
if file.name.endswith(".txt"):
|
||||
import os
|
||||
filepath = os.path.join(self.directory, file.name)
|
||||
|
||||
node_tree = context.material.node_tree
|
||||
text_node = node_tree.nodes.new(type="ShaderNodeScript")
|
||||
text_node.mode = 'EXTERNAL'
|
||||
text_node.filepath = filepath
|
||||
text_node.location = Vector((x, y))
|
||||
|
||||
# Set the node's title to the file name.
|
||||
if self.set_label:
|
||||
text_node.label = file.name
|
||||
|
||||
x += 20.0
|
||||
y -= 20.0
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
# Use ImportHelper's invoke_popup() to handle the invocation so that this operator's properties
|
||||
# are shown in a popup. This allows the user to configure additional settings on the operator
|
||||
# like the `set_label` property. Consider having a draw() method on the operator in order to
|
||||
# layout the properties in the UI appropriately.
|
||||
#
|
||||
# If filepath information is not provided the file select window will be invoked instead.
|
||||
|
||||
def invoke(self, context, event):
|
||||
return self.invoke_popup(context)
|
||||
|
||||
|
||||
# Define a file handler that supports the following set of conditions:
|
||||
# - Execute the `shader.script_import` operator
|
||||
# - When `.txt` files are dropped in the Shader Editor
|
||||
class SHADER_FH_script_import(bpy.types.FileHandler):
|
||||
bl_idname = "SHADER_FH_script_import"
|
||||
bl_label = "File handler for shader script node import"
|
||||
bl_import_operator = "shader.script_import"
|
||||
bl_file_extensions = ".txt"
|
||||
|
||||
@classmethod
|
||||
def poll_drop(cls, context):
|
||||
return (
|
||||
context.region and context.region.type == 'WINDOW' and
|
||||
context.area and context.area.ui_type == 'ShaderNodeTree'
|
||||
)
|
||||
|
||||
|
||||
bpy.utils.register_class(ShaderScriptImport)
|
||||
bpy.utils.register_class(SHADER_FH_script_import)
|
||||
@@ -0,0 +1,53 @@
|
||||
"""
|
||||
Accessing Evaluated Geometry
|
||||
++++++++++++++++++++++++++++
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# The GeometrySet can only be retrieved from an evaluated object. So one always
|
||||
# needs a depsgraph that has evaluated the object.
|
||||
depsgraph = bpy.context.view_layer.depsgraph
|
||||
ob = bpy.context.active_object
|
||||
ob_eval = depsgraph.id_eval_get(ob)
|
||||
|
||||
# Get the final evaluated geometry of an object.
|
||||
geometry = ob_eval.evaluated_geometry()
|
||||
|
||||
# Print basic information like the number of elements.
|
||||
print(geometry)
|
||||
|
||||
# A geometry set may have a name. It can be set with the Set Geometry Name node.
|
||||
print(geometry.name)
|
||||
|
||||
# Access "realized" geometry components.
|
||||
print(geometry.mesh)
|
||||
print(geometry.pointcloud)
|
||||
print(geometry.curves)
|
||||
print(geometry.volume)
|
||||
print(geometry.grease_pencil)
|
||||
|
||||
# Access the mesh without final subdivision applied.
|
||||
print(geometry.mesh_base)
|
||||
|
||||
# Accessing instances is a bit more tricky, because there is no specific
|
||||
# mechanism to expose instances. Instead, two accessors are provided which
|
||||
# are easy to keep working in the future even if we get a proper Instances type.
|
||||
|
||||
# This is a pointcloud that provides access to all the instance attributes.
|
||||
# There is a point per instances. May return None if there is no instances data.
|
||||
instances_pointcloud = geometry.instances_pointcloud()
|
||||
|
||||
if instances_pointcloud is not None:
|
||||
# This is a list containing the data that is instanced. The list may contain
|
||||
# None, objects, collections or other GeometrySets. If the geometry does not
|
||||
# have instances, the list is empty.
|
||||
references = geometry.instance_references()
|
||||
|
||||
# Besides normal generic attributes, there are also two important
|
||||
# instance-specific attributes. "instance_transform" is a 4x4 matrix attribute
|
||||
# containing the transforms of each instance.
|
||||
instance_transforms = instances_pointcloud.attributes["instance_transform"]
|
||||
|
||||
# ".reference_index" contains indices into the `references` list above and
|
||||
# determines what geometry each instance uses.
|
||||
reference_indices = instances_pointcloud.attributes[".reference_index"]
|
||||
@@ -0,0 +1,61 @@
|
||||
"""
|
||||
Base class for integrating USD Hydra based renderers.
|
||||
|
||||
USD Hydra Based Renderer
|
||||
++++++++++++++++++++++++
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
|
||||
# Identifier and name in the user interface.
|
||||
bl_idname = "CUSTOM_HYDRA_RENDERER"
|
||||
bl_label = "Custom Hydra Renderer"
|
||||
|
||||
# Name of the render plugin.
|
||||
bl_delegate_id = "HdCustomRendererPlugin"
|
||||
|
||||
# Use MaterialX instead of `UsdPreviewSurface` for materials.
|
||||
bl_use_materialx = True
|
||||
|
||||
# Register path to plugin.
|
||||
@classmethod
|
||||
def register(cls):
|
||||
# Make `pxr` module available, for running as `bpy` PIP package.
|
||||
bpy.utils.expose_bundled_modules()
|
||||
|
||||
import pxr.Plug
|
||||
pxr.Plug.Registry().RegisterPlugins(['/path/to/plugin'])
|
||||
|
||||
# Render settings that will be passed to the delegate.
|
||||
def get_render_settings(self, engine_type):
|
||||
return {
|
||||
'myBoolean': True,
|
||||
'myValue': 8,
|
||||
'aovToken:Depth': "depth",
|
||||
}
|
||||
|
||||
# RenderEngine methods for update, render and draw are implemented in
|
||||
# HydraRenderEngine. Optionally extra work can be done before or after
|
||||
# by implementing the methods like this.
|
||||
def update(self, data, depsgraph):
|
||||
super().update(data, depsgraph)
|
||||
# Do extra work here.
|
||||
|
||||
def update_render_passes(self, scene, render_layer):
|
||||
if render_layer.use_pass_z:
|
||||
self.register_pass(scene, render_layer, 'Depth', 1, 'Z', 'VALUE')
|
||||
|
||||
|
||||
# Registration.
|
||||
def register():
|
||||
bpy.utils.register_class(CustomHydraRenderEngine)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CustomHydraRenderEngine)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
This function is for advanced use only, misuse can crash Blender since the user
|
||||
count is used to prevent data being removed when it is used.
|
||||
"""
|
||||
|
||||
# This example shows what _not_ to do, and will crash Blender.
|
||||
import bpy
|
||||
|
||||
# Object which is in the scene.
|
||||
obj = bpy.data.objects["Cube"]
|
||||
|
||||
# Without this, removal would raise an error.
|
||||
obj.user_clear()
|
||||
|
||||
# Runs without an exception but will crash on redraw.
|
||||
bpy.data.objects.remove(obj)
|
||||
46
blender-5.2.0/doc/python_api/examples/bpy.types.Image.0.py
Normal file
46
blender-5.2.0/doc/python_api/examples/bpy.types.Image.0.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
Image Data
|
||||
++++++++++
|
||||
|
||||
The Image data-block is a shallow wrapper around image or video file(s)
|
||||
(on disk, as packed data, or generated).
|
||||
|
||||
All actual data like the pixel buffer, size, resolution etc. is
|
||||
cached in an :class:`imbuf.types.ImBuf` image buffer (or several buffers
|
||||
in some cases, like UDIM textures, multi-views, animations...).
|
||||
|
||||
Several properties and functions of the Image data-block are then actually
|
||||
using/modifying its image buffer, and not the Image data-block itself.
|
||||
|
||||
.. warning::
|
||||
|
||||
One key limitation is that image buffers are not shared between different
|
||||
Image data-blocks, and they are not duplicated when copying an image.
|
||||
|
||||
So until a modified image buffer is saved on disk, duplicating its Image
|
||||
data-block will not propagate the underlying buffer changes to the new Image.
|
||||
|
||||
|
||||
This example script generates an Image data-block with a given size,
|
||||
change its first pixel, rescale it, and duplicates the image.
|
||||
|
||||
The duplicated image still has the same size and colors as the original image
|
||||
at its creation, all editing in the original image's buffer is 'lost' in its copy.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
image_src = bpy.data.images.new('src', 1024, 102)
|
||||
print(image_src.size)
|
||||
print(image_src.pixels[0:4])
|
||||
|
||||
image_src.scale(1024, 720)
|
||||
image_src.pixels[0:4] = (0.5, 0.5, 0.5, 0.5)
|
||||
image_src.update()
|
||||
print(image_src.size)
|
||||
print(image_src.pixels[0:4])
|
||||
|
||||
image_dest = image_src.copy()
|
||||
image_dest.update()
|
||||
print(image_dest.size)
|
||||
print(image_dest.pixels[0:4])
|
||||
@@ -0,0 +1,23 @@
|
||||
"""
|
||||
Inline Shader Nodes
|
||||
+++++++++++++++++++
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# The materials should be retrieved from the evaluated object to make sure that
|
||||
# e.g. edits of Geometry Nodes are applied.
|
||||
depsgraph = bpy.context.view_layer.depsgraph
|
||||
ob = bpy.context.active_object
|
||||
ob_eval = depsgraph.id_eval_get(ob)
|
||||
material_eval = ob_eval.material_slots[0].material
|
||||
|
||||
# Compute the inlined shader nodes.
|
||||
# Important: Do not loose the reference to this object while accessing the inlined
|
||||
# node tree. Otherwise there will be a crash due to a dangling pointer.
|
||||
inline_shader_nodes = material_eval.inline_shader_nodes()
|
||||
|
||||
# Get the actual inlined `bpy.types.NodeTree`.
|
||||
tree = inline_shader_nodes.node_tree
|
||||
|
||||
for node in tree.nodes:
|
||||
print(node.name)
|
||||
73
blender-5.2.0/doc/python_api/examples/bpy.types.KeyMaps.1.py
Normal file
73
blender-5.2.0/doc/python_api/examples/bpy.types.KeyMaps.1.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Add-on Keymap Registration
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
This example shows how an add-on can register custom keyboard shortcuts.
|
||||
Keymaps are added to ``keyconfigs.addon`` and removed when unregistered.
|
||||
|
||||
Store ``(keymap, keymap_item)`` tuples for safe cleanup, as multiple add-ons may use the same keymap.
|
||||
|
||||
.. note::
|
||||
|
||||
Users can customize add-on shortcuts in the Keymap Preferences.
|
||||
Add-on keymaps appear under their respective editors and can be
|
||||
modified or disabled without editing the add-on code.
|
||||
|
||||
Add-ons should only manipulate keymaps in ``keyconfigs.addon`` and not manipulate the user's keymaps
|
||||
because add-on keymaps serve as a default which users may customize.
|
||||
Modifying user keymaps directly interferes with users' own preferences.
|
||||
|
||||
.. warning::
|
||||
|
||||
Add-ons can add items to existing modal keymaps but cannot create
|
||||
new modal keymaps via Python. Use ``modal=True`` when targeting
|
||||
an existing modal keymap such as "Knife Tool Modal Map".
|
||||
"""
|
||||
|
||||
# In this example keymap registration functions are only split out for clarity,
|
||||
# so skipping keymap registration in background mode doesn't interfere with other registration logic.
|
||||
|
||||
import bpy
|
||||
|
||||
# Store (keymap, keymap_item) for cleanup on unregister.
|
||||
addon_keymaps = []
|
||||
|
||||
|
||||
def register_keymaps():
|
||||
wm = bpy.context.window_manager
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc is None:
|
||||
return # Can be None in background mode.
|
||||
|
||||
# Target the 3D View; name must match Blender's built-in keymap exactly.
|
||||
km = kc.keymaps.new(name="3D View", space_type='VIEW_3D')
|
||||
|
||||
# Bind Shift+Alt+K to frame selected objects.
|
||||
kmi = km.keymap_items.new(
|
||||
idname="view3d.view_selected",
|
||||
type='K',
|
||||
value='PRESS',
|
||||
shift=True,
|
||||
alt=True,
|
||||
)
|
||||
kmi.properties.use_all_regions = True
|
||||
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
|
||||
def unregister_keymaps():
|
||||
for km, kmi in addon_keymaps:
|
||||
km.keymap_items.remove(kmi)
|
||||
addon_keymaps.clear()
|
||||
|
||||
|
||||
def register():
|
||||
register_keymaps()
|
||||
|
||||
|
||||
def unregister():
|
||||
unregister_keymaps()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
50
blender-5.2.0/doc/python_api/examples/bpy.types.Macro.0.py
Normal file
50
blender-5.2.0/doc/python_api/examples/bpy.types.Macro.0.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
Example Macro
|
||||
+++++++++++++
|
||||
|
||||
This example creates a simple macro operator that
|
||||
moves the active object and then rotates it.
|
||||
It demonstrates:
|
||||
|
||||
- Defining a macro operator class.
|
||||
- Registering it and defining sub-operators.
|
||||
- Setting property values for each step.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class OBJECT_OT_simple_macro(bpy.types.Macro):
|
||||
bl_idname = "object.simple_macro"
|
||||
bl_label = "Simple Transform Macro"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object is not None
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_simple_macro)
|
||||
|
||||
# Define steps after registration and set operator values via .properties
|
||||
step = OBJECT_OT_simple_macro.define("transform.translate")
|
||||
props = step.properties
|
||||
props.value = (1.0, 0.0, 0.0)
|
||||
props.constraint_axis = (True, False, False)
|
||||
|
||||
step = OBJECT_OT_simple_macro.define("transform.rotate")
|
||||
props = step.properties
|
||||
props.value = 0.785398 # 45 degrees in radians
|
||||
props.orient_axis = 'Z'
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_simple_macro)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# To run the macro:
|
||||
bpy.ops.object.simple_macro()
|
||||
42
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.0.py
Normal file
42
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.0.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
Basic Menu Example
|
||||
++++++++++++++++++
|
||||
|
||||
Here is an example of a simple menu. Menus differ from panels in that they must
|
||||
reference from a header, panel or another menu.
|
||||
|
||||
Notice the 'CATEGORY_MT_name' in :class:`Menu.bl_idname`, this is a naming
|
||||
convention for menus.
|
||||
|
||||
.. note::
|
||||
|
||||
Menu subclasses must be registered before referencing them from Blender.
|
||||
|
||||
.. note::
|
||||
|
||||
Menus have their :class:`UILayout.operator_context` initialized as
|
||||
'EXEC_REGION_WIN' rather than 'INVOKE_REGION_WIN' (see :ref:`Execution Context <rna_enum_operator_context_items>`).
|
||||
If the operator context needs to initialize inputs from the
|
||||
:class:`Operator.invoke` function, then this needs to be explicitly set.
|
||||
When a menu is added to UI elements such as a panel or header,
|
||||
the operator execution context will be inherited from them.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class BasicMenu(bpy.types.Menu):
|
||||
bl_idname = "OBJECT_MT_select_test"
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("object.select_random", text="Random")
|
||||
|
||||
|
||||
bpy.utils.register_class(BasicMenu)
|
||||
|
||||
# Test call to display immediately.
|
||||
bpy.ops.wm.call_menu(name="OBJECT_MT_select_test")
|
||||
38
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.1.py
Normal file
38
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.1.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
Submenus
|
||||
++++++++
|
||||
|
||||
This menu demonstrates some different functions.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class SubMenu(bpy.types.Menu):
|
||||
bl_idname = "OBJECT_MT_select_submenu"
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
|
||||
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("object.select_random", text="Random")
|
||||
|
||||
# Access this operator as a sub-menu.
|
||||
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type")
|
||||
|
||||
layout.separator()
|
||||
|
||||
# Expand each operator option into this menu.
|
||||
layout.operator_enum("object.light_add", "type")
|
||||
|
||||
layout.separator()
|
||||
|
||||
# Use existing menu.
|
||||
layout.menu("VIEW3D_MT_transform")
|
||||
|
||||
|
||||
bpy.utils.register_class(SubMenu)
|
||||
|
||||
# Test call to display immediately.
|
||||
bpy.ops.wm.call_menu(name="OBJECT_MT_select_submenu")
|
||||
18
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.2.py
Normal file
18
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.2.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""
|
||||
Extending Menus
|
||||
+++++++++++++++
|
||||
|
||||
When creating menus for add-ons you can't reference menus
|
||||
in Blender's default scripts.
|
||||
Instead, the add-on can add menu items to existing menus.
|
||||
|
||||
The function menu_draw acts like :class:`Menu.draw`.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
def menu_draw(self, context):
|
||||
self.layout.operator("wm.save_homefile")
|
||||
|
||||
|
||||
bpy.types.TOPBAR_MT_file.append(menu_draw)
|
||||
80
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.3.py
Normal file
80
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.3.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
Preset Menus
|
||||
++++++++++++
|
||||
|
||||
Preset menus are simply a convention that uses a menu sub-class
|
||||
to perform the common task of managing presets.
|
||||
|
||||
This example shows how you can add a preset menu.
|
||||
|
||||
This example uses the object display options,
|
||||
however you can use properties defined by your own scripts too.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator, Menu
|
||||
from bl_operators.presets import AddPresetBase
|
||||
|
||||
|
||||
class OBJECT_MT_display_presets(Menu):
|
||||
bl_label = "Object Display Presets"
|
||||
preset_subdir = "object/display"
|
||||
preset_operator = "script.execute_preset"
|
||||
draw = Menu.draw_preset
|
||||
|
||||
|
||||
class AddPresetObjectDisplay(AddPresetBase, Operator):
|
||||
'''Add a Object Display Preset'''
|
||||
bl_idname = "camera.object_display_preset_add"
|
||||
bl_label = "Add Object Display Preset"
|
||||
preset_menu = "OBJECT_MT_display_presets"
|
||||
|
||||
# Variable used for all preset values.
|
||||
preset_defines = [
|
||||
"obj = bpy.context.object"
|
||||
]
|
||||
|
||||
# Properties to store in the preset.
|
||||
preset_values = [
|
||||
"obj.display_type",
|
||||
"obj.show_bounds",
|
||||
"obj.display_bounds_type",
|
||||
"obj.show_name",
|
||||
"obj.show_axis",
|
||||
"obj.show_wire",
|
||||
]
|
||||
|
||||
# Where to store the preset.
|
||||
preset_subdir = "object/display"
|
||||
|
||||
|
||||
# Display into an existing panel.
|
||||
def panel_func(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.menu(OBJECT_MT_display_presets.__name__, text=OBJECT_MT_display_presets.bl_label)
|
||||
row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_IN')
|
||||
row.operator(AddPresetObjectDisplay.bl_idname, text="", icon='ZOOM_OUT').remove_active = True
|
||||
|
||||
|
||||
classes = (
|
||||
OBJECT_MT_display_presets,
|
||||
AddPresetObjectDisplay,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
bpy.types.OBJECT_PT_display.prepend(panel_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
bpy.types.OBJECT_PT_display.remove(panel_func)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
66
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.4.py
Normal file
66
blender-5.2.0/doc/python_api/examples/bpy.types.Menu.4.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
Extending the Button Context Menu
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
This example enables you to insert your own menu entry into the common
|
||||
right click menu that you get while hovering over a UI button (e.g. operator,
|
||||
value field, color, string, etc.)
|
||||
|
||||
To make the example work, you have to first select an object
|
||||
then right click on an user interface element (maybe a color in the
|
||||
material properties) and choose *Execute Custom Action*.
|
||||
|
||||
Executing the operator will then print all values.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def dump(obj, text):
|
||||
for attr in dir(obj):
|
||||
print("{!r}.{:s} = {!s}".format(obj, attr, getattr(obj, attr)))
|
||||
|
||||
|
||||
class WM_OT_button_context_test(bpy.types.Operator):
|
||||
"""Right click entry test"""
|
||||
bl_idname = "wm.button_context_test"
|
||||
bl_label = "Run Context Test"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object is not None
|
||||
|
||||
def execute(self, context):
|
||||
value = getattr(context, "button_pointer", None)
|
||||
if value is not None:
|
||||
dump(value, "button_pointer")
|
||||
|
||||
value = getattr(context, "button_prop", None)
|
||||
if value is not None:
|
||||
dump(value, "button_prop")
|
||||
|
||||
value = getattr(context, "button_operator", None)
|
||||
if value is not None:
|
||||
dump(value, "button_operator")
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def draw_menu(self, context):
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.operator(WM_OT_button_context_test.bl_idname)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(WM_OT_button_context_test)
|
||||
bpy.types.UI_MT_button_context_menu.append(draw_menu)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.UI_MT_button_context_menu.remove(draw_menu)
|
||||
bpy.utils.unregister_class(WM_OT_button_context_test)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
41
blender-5.2.0/doc/python_api/examples/bpy.types.Mesh.0.py
Normal file
41
blender-5.2.0/doc/python_api/examples/bpy.types.Mesh.0.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
Mesh Data
|
||||
+++++++++
|
||||
|
||||
The mesh data is accessed in object mode and intended for compact storage,
|
||||
for more flexible mesh editing from Python see :mod:`bmesh`.
|
||||
|
||||
Blender stores 4 main arrays to define mesh geometry.
|
||||
|
||||
- :class:`Mesh.vertices` (3 points in space)
|
||||
- :class:`Mesh.edges` (reference 2 vertices)
|
||||
- :class:`Mesh.loops` (reference a single vertex and edge)
|
||||
- :class:`Mesh.polygons`: (reference a range of loops)
|
||||
|
||||
|
||||
Each polygon references a slice in the loop array, this way,
|
||||
polygons do not store vertices or corner data such as UVs directly,
|
||||
only a reference to loops that the polygon uses.
|
||||
|
||||
:class:`Mesh.loops`, :class:`Mesh.uv_layers` :class:`Mesh.vertex_colors` are all aligned so the same polygon loop
|
||||
indices can be used to find the UVs and vertex colors as with as the vertices.
|
||||
|
||||
To compare mesh API options see: :ref:`NGons and Tessellation Faces <info_gotcha_mesh_faces>`
|
||||
|
||||
|
||||
This example script prints the vertices and UVs for each polygon, assumes the active object is a mesh with UVs.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
me = bpy.context.object.data
|
||||
uv_layer = me.uv_layers.active.data
|
||||
|
||||
for poly in me.polygons:
|
||||
print("Polygon index: {:d}, length: {:d}".format(poly.index, poly.loop_total))
|
||||
|
||||
# Range is used here to show how the polygons reference loops,
|
||||
# for convenience 'poly.loop_indices' can be used instead.
|
||||
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
||||
print(" Vertex: {:d}".format(me.loops[loop_index].vertex_index))
|
||||
print(" UV: {!r}".format(uv_layer[loop_index].uv))
|
||||
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Poll Function
|
||||
+++++++++++++++
|
||||
|
||||
The :class:`NodeTree.poll` function determines if a node tree is visible
|
||||
in the given context (similar to how :class:`Panel.poll`
|
||||
and :class:`Menu.poll` define visibility). If it returns False,
|
||||
the node tree type will not be selectable in the node editor.
|
||||
|
||||
A typical condition for shader nodes would be to check the active render engine
|
||||
of the scene and only show nodes of the renderer they are designed for.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class CyclesNodeTree(bpy.types.NodeTree):
|
||||
""" This operator is only visible when Cycles is the selected render engine"""
|
||||
bl_label = "Cycles Node Tree"
|
||||
bl_icon = 'NONE'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.render.engine == 'CYCLES'
|
||||
|
||||
|
||||
bpy.utils.register_class(CyclesNodeTree)
|
||||
28
blender-5.2.0/doc/python_api/examples/bpy.types.Object.0.py
Normal file
28
blender-5.2.0/doc/python_api/examples/bpy.types.Object.0.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
Basic Object Operations Example
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
This script demonstrates basic operations on object like creating new
|
||||
object, placing it into a view layer, selecting it and making it active.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
view_layer = bpy.context.view_layer
|
||||
|
||||
# Create new light data-block.
|
||||
light_data = bpy.data.lights.new(name="New Light", type='POINT')
|
||||
|
||||
# Create new object with our light data-block.
|
||||
light_object = bpy.data.objects.new(name="New Light", object_data=light_data)
|
||||
|
||||
# Link light object to the active collection of current view layer,
|
||||
# so that it'll appear in the current scene.
|
||||
view_layer.active_layer_collection.collection.objects.link(light_object)
|
||||
|
||||
# Place light to a specified location.
|
||||
light_object.location = (5.0, 5.0, 5.0)
|
||||
|
||||
# And finally select it and make it active.
|
||||
light_object.select_set(True)
|
||||
view_layer.objects.active = light_object
|
||||
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
Basic Operator Example
|
||||
++++++++++++++++++++++
|
||||
|
||||
This script shows simple operator which prints a message.
|
||||
|
||||
Since the operator only has an :class:`Operator.execute` function it takes no
|
||||
user input.
|
||||
|
||||
The function should return ``{'FINISHED'}`` or ``{'CANCELLED'}``, the latter
|
||||
meaning that operator execution was aborted without making any changes, and
|
||||
that no undo step will created (see next example for more info about undo).
|
||||
|
||||
.. note::
|
||||
|
||||
Operator subclasses must be registered before accessing them from Blender.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class HelloWorldOperator(bpy.types.Operator):
|
||||
bl_idname = "wm.hello_world"
|
||||
bl_label = "Minimal Operator"
|
||||
|
||||
def execute(self, context):
|
||||
print("Hello World")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(HelloWorldOperator.bl_idname, text="Hello World Operator")
|
||||
|
||||
|
||||
# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access).
|
||||
bpy.utils.register_class(HelloWorldOperator)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
||||
# Test call to the newly defined operator.
|
||||
bpy.ops.wm.hello_world()
|
||||
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
.. _operator_modifying_blender_data_undo:
|
||||
|
||||
Modifying Blender Data & Undo
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
Any operator modifying Blender data should enable the ``'UNDO'`` option.
|
||||
This will make Blender automatically create an undo step when the operator
|
||||
finishes its ``execute`` (or ``invoke``, see below) functions, and returns
|
||||
``{'FINISHED'}``.
|
||||
|
||||
Otherwise, no undo step will be created, which will at best corrupt the
|
||||
undo stack and confuse the user (since modifications done by the operator
|
||||
may either not be undoable, or be undone together with other edits done
|
||||
before). In many cases, this can even lead to data corruption and crashes.
|
||||
|
||||
Note that when an operator returns ``{'CANCELLED'}``, no undo step will be
|
||||
created. This means that if an error occurs *after* modifying some data
|
||||
already, it is better to return ``{'FINISHED'}``, unless it is possible to
|
||||
fully undo the changes before returning.
|
||||
|
||||
.. note::
|
||||
|
||||
Most examples in this page do not do any edit to Blender data, which is
|
||||
why it is safe to keep the default ``bl_options`` value for these operators.
|
||||
|
||||
.. note::
|
||||
|
||||
In some complex cases, the automatic undo step created on operator exit may
|
||||
not be enough. For example, if the operator does mode switching, or calls
|
||||
other operators that should create an extra undo step, etc.
|
||||
|
||||
Such manual undo push is possible using the :class:`bpy.ops.ed.undo_push`
|
||||
function. Be careful though, this is considered an advanced feature and
|
||||
requires some understanding of the actual undo system in Blender code.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class DataEditOperator(bpy.types.Operator):
|
||||
bl_idname = "object.data_edit"
|
||||
bl_label = "Data Editing Operator"
|
||||
# The default value is only 'REGISTER', 'UNDO' is mandatory when Blender data is modified
|
||||
# (and does require 'REGISTER' as well).
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
context.object.location.x += 1.0
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(DataEditOperator.bl_idname, text="Blender Data Editing Operator")
|
||||
|
||||
|
||||
# Register.
|
||||
bpy.utils.register_class(DataEditOperator)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
||||
# Test call to the newly defined operator.
|
||||
bpy.ops.object.data_edit()
|
||||
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Invoke Function
|
||||
+++++++++++++++
|
||||
|
||||
:class:`Operator.invoke` is used to initialize the operator from the context
|
||||
at the moment the operator is called.
|
||||
invoke() is typically used to assign properties which are then used by
|
||||
execute().
|
||||
Some operators don't have an execute() function, removing the ability to be
|
||||
repeated from a script or macro.
|
||||
|
||||
When an operator is called via :mod:`bpy.ops`, the execution context depends
|
||||
on the argument provided to :mod:`bpy.ops`. By default, it uses execute().
|
||||
When an operator is activated from a button or menu item, it follows
|
||||
the setting in :class:`UILayout.operator_context`. In most cases, invoke() is used.
|
||||
Running an operator via a key shortcut always uses invoke(),
|
||||
and this behavior cannot be changed.
|
||||
|
||||
This example shows how to define an operator which gets mouse input to
|
||||
execute a function and that this operator can be invoked or executed from
|
||||
the Python API.
|
||||
|
||||
Also notice this operator defines its own properties, these are different
|
||||
to typical class properties because Blender registers them with the
|
||||
operator, to use as arguments when called, saved for operator undo/redo and
|
||||
automatically added into the user interface.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class SimpleMouseOperator(bpy.types.Operator):
|
||||
""" This operator shows the mouse location,
|
||||
this string is used for the tooltip and API docs
|
||||
"""
|
||||
bl_idname = "wm.mouse_position"
|
||||
bl_label = "Invoke Mouse Operator"
|
||||
|
||||
x: bpy.props.IntProperty()
|
||||
y: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
# Rather than printing, use the report function,
|
||||
# this way the message appears in the header.
|
||||
self.report({'INFO'}, "Mouse coords are {:d} {:d}".format(self.x, self.y))
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.x = event.mouse_x
|
||||
self.y = event.mouse_y
|
||||
return self.execute(context)
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(SimpleMouseOperator.bl_idname, text="Simple Mouse Operator")
|
||||
|
||||
|
||||
# Register and add to the view menu (required to also use F3 search "Simple Mouse Operator" for quick access).
|
||||
bpy.utils.register_class(SimpleMouseOperator)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
||||
# Test call to the newly defined operator.
|
||||
# Here we call the operator and invoke it,
|
||||
# meaning that the settings are taken from the mouse.
|
||||
bpy.ops.wm.mouse_position('INVOKE_DEFAULT')
|
||||
|
||||
# Another test call, this time call execute() directly with pre-defined settings.
|
||||
bpy.ops.wm.mouse_position('EXEC_DEFAULT', x=20, y=66)
|
||||
@@ -0,0 +1,52 @@
|
||||
"""
|
||||
Calling a File Selector
|
||||
+++++++++++++++++++++++
|
||||
This example shows how an operator can use the file selector.
|
||||
|
||||
Notice the invoke function calls a window manager method and returns
|
||||
``{'RUNNING_MODAL'}``, this means the file selector stays open and the operator does not
|
||||
exit immediately after invoke finishes.
|
||||
|
||||
The file selector runs the operator, calling :class:`Operator.execute` when the
|
||||
user confirms.
|
||||
|
||||
The :class:`Operator.poll` function is optional, used to check if the operator
|
||||
can run.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class ExportSomeData(bpy.types.Operator):
|
||||
"""Test exporter which just writes hello world"""
|
||||
bl_idname = "export.some_data"
|
||||
bl_label = "Export Some Data"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.object is not None
|
||||
|
||||
def execute(self, context):
|
||||
file = open(self.filepath, 'w')
|
||||
file.write("Hello World " + context.object.name)
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator_context = 'INVOKE_DEFAULT'
|
||||
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
|
||||
|
||||
|
||||
# Register and add to the file selector (required to also use F3 search "Text Export Operator" for quick access).
|
||||
bpy.utils.register_class(ExportSomeData)
|
||||
bpy.types.TOPBAR_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
# Test call.
|
||||
bpy.ops.export.some_data('INVOKE_DEFAULT')
|
||||
@@ -0,0 +1,40 @@
|
||||
"""
|
||||
Dialog Box
|
||||
++++++++++
|
||||
|
||||
This operator uses its :class:`Operator.invoke` function to call a popup.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class DialogOperator(bpy.types.Operator):
|
||||
bl_idname = "object.dialog_operator"
|
||||
bl_label = "Simple Dialog Operator"
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
message = "Popup Values: {:f}, {:d}, '{:s}'".format(
|
||||
self.my_float, self.my_bool, self.my_string,
|
||||
)
|
||||
self.report({'INFO'}, message)
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(DialogOperator.bl_idname, text="Dialog Operator")
|
||||
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Dialog Operator" for quick access).
|
||||
bpy.utils.register_class(DialogOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# Test call.
|
||||
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
|
||||
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
Custom Drawing
|
||||
++++++++++++++
|
||||
|
||||
By default operator properties use an automatic user interface layout.
|
||||
If you need more control you can create your own layout with a
|
||||
:class:`Operator.draw` function.
|
||||
|
||||
This works like the :class:`Panel` and :class:`Menu` draw functions, its used
|
||||
for dialogs and file selectors.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class CustomDrawOperator(bpy.types.Operator):
|
||||
bl_idname = "object.custom_draw"
|
||||
bl_label = "Simple Modal Operator"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Float")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
print("Test", self)
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.label(text="Custom Interface!")
|
||||
|
||||
row = col.row()
|
||||
row.prop(self, "my_float")
|
||||
row.prop(self, "my_bool")
|
||||
|
||||
col.prop(self, "my_string")
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(CustomDrawOperator.bl_idname, text="Custom Draw Operator")
|
||||
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access).
|
||||
bpy.utils.register_class(CustomDrawOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# Test call.
|
||||
bpy.ops.object.custom_draw('INVOKE_DEFAULT')
|
||||
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
.. _modal_operator:
|
||||
|
||||
Modal Execution
|
||||
+++++++++++++++
|
||||
|
||||
This operator defines a :class:`Operator.modal` function that will keep being
|
||||
run to handle events until it returns ``{'FINISHED'}`` or ``{'CANCELLED'}``.
|
||||
|
||||
Modal operators run every time a new event is detected, such as a mouse click
|
||||
or key press. Conversely, when no new events are detected, the modal operator
|
||||
will not run. Modal operators are especially useful for interactive tools, an
|
||||
operator can have its own state where keys toggle options as the operator runs.
|
||||
Grab, Rotate, Scale, and Fly-Mode are examples of modal operators.
|
||||
|
||||
:class:`Operator.invoke` is used to initialize the operator as being active
|
||||
by returning ``{'RUNNING_MODAL'}``, initializing the modal loop.
|
||||
|
||||
Notice ``__init__()`` and ``__del__()`` are declared.
|
||||
For other operator types they are not useful but for modal operators they will
|
||||
be called before the :class:`Operator.invoke` and after the operator finishes.
|
||||
Also see the
|
||||
:ref:`class construction and destruction section <info_overview_class_construction_destruction>`.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
||||
class ModalOperator(bpy.types.Operator):
|
||||
bl_idname = "object.modal_operator"
|
||||
bl_label = "Simple Modal Operator"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
print("Start")
|
||||
|
||||
def __del__(self):
|
||||
print("End")
|
||||
super().__del__()
|
||||
|
||||
def execute(self, context):
|
||||
context.object.location.x = self.value / 100.0
|
||||
return {'FINISHED'}
|
||||
|
||||
def modal(self, context, event):
|
||||
if event.type == 'MOUSEMOVE': # Apply.
|
||||
self.value = event.mouse_x
|
||||
self.execute(context)
|
||||
elif event.type == 'LEFTMOUSE': # Confirm.
|
||||
return {'FINISHED'}
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}: # Cancel.
|
||||
# Revert all changes that have been made
|
||||
context.object.location.x = self.init_loc_x
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.init_loc_x = context.object.location.x
|
||||
self.value = event.mouse_x
|
||||
self.execute(context)
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ModalOperator.bl_idname, text="Modal Operator")
|
||||
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access).
|
||||
bpy.utils.register_class(ModalOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# Test call.
|
||||
bpy.ops.object.modal_operator('INVOKE_DEFAULT')
|
||||
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
Enum Search Popup
|
||||
+++++++++++++++++
|
||||
|
||||
You may want to have an operator prompt the user to select an item
|
||||
from a search field, this can be done using :class:`bpy.types.Operator.invoke_search_popup`.
|
||||
"""
|
||||
import bpy
|
||||
from bpy.props import EnumProperty
|
||||
|
||||
|
||||
class SearchEnumOperator(bpy.types.Operator):
|
||||
bl_idname = "object.search_enum_operator"
|
||||
bl_label = "Search Enum Operator"
|
||||
bl_property = "my_search"
|
||||
|
||||
my_search: EnumProperty(
|
||||
name="My Search",
|
||||
items=(
|
||||
('FOO', "Foo", ""),
|
||||
('BAR', "Bar", ""),
|
||||
('BAZ', "Baz", ""),
|
||||
),
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
self.report({'INFO'}, "Selected:" + self.my_search)
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu.
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(SearchEnumOperator.bl_idname, text="Search Enum Operator")
|
||||
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Search Enum Operator" for quick access).
|
||||
bpy.utils.register_class(SearchEnumOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# Test call.
|
||||
bpy.ops.object.search_enum_operator('INVOKE_DEFAULT')
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user