Merge branch 'master' into blender2.8
This commit is contained in:
@@ -76,7 +76,7 @@ class DNACatalogHTML:
|
||||
DNACatalog is a catalog of all information in the DNA1 file-block
|
||||
'''
|
||||
|
||||
def __init__(self, catalog, bpy_module = None):
|
||||
def __init__(self, catalog, bpy_module=None):
|
||||
self.Catalog = catalog
|
||||
self.bpy = bpy_module
|
||||
|
||||
@@ -125,9 +125,9 @@ class DNACatalogHTML:
|
||||
|
||||
# ${endianness}
|
||||
if header.LittleEndianness:
|
||||
endianess= 'Little endianness'
|
||||
endianess = 'Little endianness'
|
||||
else:
|
||||
endianess= 'Big endianness'
|
||||
endianess = 'Big endianness'
|
||||
|
||||
# ${structs_list}
|
||||
log.debug("Creating structs index")
|
||||
@@ -136,7 +136,7 @@ class DNACatalogHTML:
|
||||
structureIndex = 0
|
||||
for structure in self.Catalog.Structs:
|
||||
structs_list += list_item.format(structureIndex, structure.Type.Name)
|
||||
structureIndex+=1
|
||||
structureIndex += 1
|
||||
|
||||
# ${structs_content}
|
||||
log.debug("Creating structs content")
|
||||
@@ -146,12 +146,12 @@ class DNACatalogHTML:
|
||||
structs_content += self.Structure(structure)
|
||||
|
||||
d = dict(
|
||||
version = version,
|
||||
revision = revision,
|
||||
bitness = bitness,
|
||||
endianness = endianess,
|
||||
structs_list = structs_list,
|
||||
structs_content = structs_content
|
||||
version=version,
|
||||
revision=revision,
|
||||
bitness=bitness,
|
||||
endianness=endianess,
|
||||
structs_list=structs_list,
|
||||
structs_content=structs_content
|
||||
)
|
||||
|
||||
dna_html = Template(dna_html_template).substitute(d)
|
||||
@@ -180,9 +180,9 @@ class DNACatalogHTML:
|
||||
<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_name=structure.Type.Name,
|
||||
fields=self.StructureFields(structure, None, 0),
|
||||
size=str(structure.Type.Size)
|
||||
)
|
||||
|
||||
struct_table = Template(struct_table_template).substitute(d)
|
||||
@@ -230,12 +230,12 @@ class DNACatalogHTML:
|
||||
size = field.Size(self.Catalog.Header)
|
||||
|
||||
d = dict(
|
||||
reference = reference,
|
||||
struct = struct,
|
||||
type = type,
|
||||
name = name,
|
||||
offset = offset,
|
||||
size = size
|
||||
reference=reference,
|
||||
struct=struct,
|
||||
type=type,
|
||||
name=name,
|
||||
offset=offset,
|
||||
size=size
|
||||
)
|
||||
|
||||
structure_field = Template(structure_field_template).substitute(d)
|
||||
@@ -246,7 +246,7 @@ class DNACatalogHTML:
|
||||
|
||||
return structure_field
|
||||
|
||||
def indent(self, input, dent, startswith = ''):
|
||||
def indent(self, input, dent, startswith=''):
|
||||
output = ''
|
||||
if dent < 0:
|
||||
for line in input.split('\n'):
|
||||
@@ -257,19 +257,19 @@ class DNACatalogHTML:
|
||||
output += line.lstrip() + '\n' # remove indentation completely
|
||||
elif dent > 0:
|
||||
for line in input.split('\n'):
|
||||
output += ' '* dent + line + '\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>'
|
||||
'\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():
|
||||
@@ -417,7 +417,7 @@ def main():
|
||||
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)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=Path_Blend, copy=True, compress=False)
|
||||
except:
|
||||
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
|
||||
return
|
||||
|
@@ -34,6 +34,7 @@ log = logging.getLogger("BlendFileReader")
|
||||
# module global routines
|
||||
######################################################
|
||||
|
||||
|
||||
def ReadString(handle, length):
|
||||
'''
|
||||
ReadString reads a String of given length or a zero terminating String
|
||||
@@ -45,7 +46,7 @@ def ReadString(handle, length):
|
||||
# length == 0 means we want a zero terminating string
|
||||
result = ""
|
||||
s = ReadString(handle, 1)
|
||||
while s!="\0":
|
||||
while s != "\0":
|
||||
result += s
|
||||
s = ReadString(handle, 1)
|
||||
return result
|
||||
@@ -94,10 +95,10 @@ def openBlendFile(filename):
|
||||
log.debug("decompressing started")
|
||||
fs = gzip.open(filename, "rb")
|
||||
handle = tempfile.TemporaryFile()
|
||||
data = fs.read(1024*1024)
|
||||
data = fs.read(1024 * 1024)
|
||||
while data:
|
||||
handle.write(data)
|
||||
data = fs.read(1024*1024)
|
||||
data = fs.read(1024 * 1024)
|
||||
log.debug("decompressing finished")
|
||||
fs.close()
|
||||
log.debug("resetting decompressed file")
|
||||
@@ -112,7 +113,7 @@ def Align(handle):
|
||||
offset = handle.tell()
|
||||
trim = offset % 4
|
||||
if trim != 0:
|
||||
handle.seek(4-trim, os.SEEK_CUR)
|
||||
handle.seek(4 - trim, os.SEEK_CUR)
|
||||
|
||||
|
||||
######################################################
|
||||
@@ -266,9 +267,9 @@ class DNACatalog:
|
||||
|
||||
def __init__(self, fileheader, handle):
|
||||
log.debug("building DNA catalog")
|
||||
self.Names=[]
|
||||
self.Types=[]
|
||||
self.Structs=[]
|
||||
self.Names = []
|
||||
self.Types = []
|
||||
self.Structs = []
|
||||
self.Header = fileheader
|
||||
|
||||
SDNA = ReadString(handle, 4)
|
||||
@@ -278,7 +279,7 @@ class DNACatalog:
|
||||
numberOfNames = Read('uint', handle, fileheader)
|
||||
log.debug("building #{0} names".format(numberOfNames))
|
||||
for i in range(numberOfNames):
|
||||
name = ReadString(handle,0)
|
||||
name = ReadString(handle, 0)
|
||||
self.Names.append(DNAName(name))
|
||||
Align(handle)
|
||||
|
||||
@@ -287,7 +288,7 @@ class DNACatalog:
|
||||
numberOfTypes = Read('uint', handle, fileheader)
|
||||
log.debug("building #{0} types".format(numberOfTypes))
|
||||
for i in range(numberOfTypes):
|
||||
type = ReadString(handle,0)
|
||||
type = ReadString(handle, 0)
|
||||
self.Types.append(DNAType(type))
|
||||
Align(handle)
|
||||
|
||||
@@ -332,13 +333,13 @@ class DNAName:
|
||||
if parent is None:
|
||||
result = ""
|
||||
else:
|
||||
result = parent+"."
|
||||
result = parent + "."
|
||||
|
||||
result = result + self.ShortName()
|
||||
return result
|
||||
|
||||
def ShortName(self):
|
||||
result = self.Name;
|
||||
result = self.Name
|
||||
result = result.replace("*", "")
|
||||
result = result.replace("(", "")
|
||||
result = result.replace(")", "")
|
||||
@@ -348,10 +349,10 @@ class DNAName:
|
||||
return result
|
||||
|
||||
def IsPointer(self):
|
||||
return self.Name.find("*")>-1
|
||||
return self.Name.find("*") > -1
|
||||
|
||||
def IsMethodPointer(self):
|
||||
return self.Name.find("(*")>-1
|
||||
return self.Name.find("(*") > -1
|
||||
|
||||
def ArraySize(self):
|
||||
result = 1
|
||||
@@ -360,8 +361,8 @@ class DNAName:
|
||||
|
||||
while Index != -1:
|
||||
Index2 = Temp.find("]")
|
||||
result*=int(Temp[Index+1:Index2])
|
||||
Temp = Temp[Index2+1:]
|
||||
result *= int(Temp[Index + 1:Index2])
|
||||
Temp = Temp[Index2 + 1:]
|
||||
Index = Temp.find("[")
|
||||
|
||||
return result
|
||||
@@ -378,7 +379,7 @@ class DNAType:
|
||||
|
||||
def __init__(self, aName):
|
||||
self.Name = aName
|
||||
self.Structure=None
|
||||
self.Structure = None
|
||||
|
||||
|
||||
class DNAStructure:
|
||||
@@ -392,22 +393,22 @@ class DNAStructure:
|
||||
def __init__(self, aType):
|
||||
self.Type = aType
|
||||
self.Type.Structure = self
|
||||
self.Fields=[]
|
||||
self.Fields = []
|
||||
|
||||
def GetField(self, header, handle, path):
|
||||
splitted = path.partition(".")
|
||||
name = splitted[0]
|
||||
rest = splitted[2]
|
||||
offset = 0;
|
||||
offset = 0
|
||||
for field in self.Fields:
|
||||
if field.Name.ShortName() == name:
|
||||
log.debug("found "+name+"@"+str(offset))
|
||||
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)
|
||||
log.debug("error did not find " + path)
|
||||
return None
|
||||
|
||||
|
||||
@@ -425,22 +426,21 @@ class DNAField:
|
||||
|
||||
def Size(self, header):
|
||||
if self.Name.IsPointer() or self.Name.IsMethodPointer():
|
||||
return header.PointerSize*self.Name.ArraySize()
|
||||
return header.PointerSize * self.Name.ArraySize()
|
||||
else:
|
||||
return self.Type.Size*self.Name.ArraySize()
|
||||
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":
|
||||
if self.Type.Name == "int":
|
||||
return Read('int', handle, header)
|
||||
if self.Type.Name=="short":
|
||||
if self.Type.Name == "short":
|
||||
return Read('short', handle, header)
|
||||
if self.Type.Name=="float":
|
||||
if self.Type.Name == "float":
|
||||
return Read('float', handle, header)
|
||||
if self.Type.Name=="char":
|
||||
if self.Type.Name == "char":
|
||||
return ReadString(handle, self.Name.ArraySize())
|
||||
else:
|
||||
return self.Type.Structure.GetField(header, handle, path)
|
||||
|
||||
|
@@ -42,6 +42,7 @@ def man_format(data):
|
||||
data = data.replace("\t", " ")
|
||||
return data
|
||||
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
import getopt
|
||||
raise getopt.GetoptError("Usage: %s <path-to-blender> <output-filename>" % sys.argv[0])
|
||||
|
@@ -73,6 +73,8 @@ def rna_info_BuildRNAInfo_cache():
|
||||
if rna_info_BuildRNAInfo_cache.ret is None:
|
||||
rna_info_BuildRNAInfo_cache.ret = rna_info.BuildRNAInfo()
|
||||
return rna_info_BuildRNAInfo_cache.ret
|
||||
|
||||
|
||||
rna_info_BuildRNAInfo_cache.ret = None
|
||||
# --- end rna_info cache
|
||||
|
||||
@@ -516,6 +518,8 @@ def escape_rst(text):
|
||||
""" Escape plain text which may contain characters used by RST.
|
||||
"""
|
||||
return text.translate(escape_rst.trans)
|
||||
|
||||
|
||||
escape_rst.trans = str.maketrans({
|
||||
"`": "\\`",
|
||||
"|": "\\|",
|
||||
@@ -1018,6 +1022,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
|
||||
file.close()
|
||||
|
||||
|
||||
# Changes in Blender will force errors here
|
||||
context_type_map = {
|
||||
"active_base": ("ObjectBase", False),
|
||||
|
@@ -209,6 +209,8 @@ def modules(module_cache=addons_fake_modules, *, refresh=True):
|
||||
)
|
||||
)
|
||||
return mod_list
|
||||
|
||||
|
||||
modules._is_first = True
|
||||
|
||||
|
||||
|
@@ -172,6 +172,7 @@ def ui_draw_filter_register(
|
||||
|
||||
class Wrapper(cls_real):
|
||||
__slots__ = ()
|
||||
|
||||
def __getattribute__(self, attr):
|
||||
if attr == "layout":
|
||||
return UILayout_Fake(self_real.layout)
|
||||
|
@@ -43,14 +43,17 @@ else:
|
||||
# XXX This is a quick hack to make it work with new I18n... objects! To be reworked!
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description=
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Merge one or more .po files into the first dest one.\n"
|
||||
"If a msgkey (msgctxt, msgid) is present in more than one merged po, the one in the first file "
|
||||
"wins, unless it’s marked as fuzzy and one later is not.\n"
|
||||
"The fuzzy flag is removed if necessary.\n"
|
||||
"All other comments are never modified.\n"
|
||||
"Commented messages in dst will always remain commented, and commented messages are never merged "
|
||||
"from sources.")
|
||||
"from sources."
|
||||
),
|
||||
)
|
||||
parser.add_argument('-s', '--stats', action="store_true", help="Show statistics info.")
|
||||
parser.add_argument('-r', '--replace', action="store_true",
|
||||
help="Replace existing messages of same \"level\" already in dest po.")
|
||||
|
@@ -98,5 +98,6 @@ def main():
|
||||
for value in read_blend_rend_chunk(arg):
|
||||
print("%d %d %s" % value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@@ -228,4 +228,5 @@ class BPyOpsSubModOp:
|
||||
return ("<function bpy.ops.%s.%s at 0x%x'>" %
|
||||
(self._module, self._func, id(self)))
|
||||
|
||||
|
||||
ops_fake_module = BPyOps()
|
||||
|
@@ -183,6 +183,8 @@ def clean_name(name, replace="_"):
|
||||
|
||||
trans = maketrans_init()
|
||||
return name.translate(trans)
|
||||
|
||||
|
||||
clean_name._trans_cache = {}
|
||||
|
||||
|
||||
@@ -223,6 +225,7 @@ def display_name(name):
|
||||
name = _clean_utf8(name)
|
||||
return name
|
||||
|
||||
|
||||
def display_name_to_filepath(name):
|
||||
"""
|
||||
Performs the reverse of display_name using literal versions of characters
|
||||
|
@@ -31,4 +31,4 @@ __all__ = (
|
||||
"mesh_utils",
|
||||
"node_utils",
|
||||
"view3d_utils",
|
||||
)
|
||||
)
|
||||
|
@@ -174,7 +174,7 @@ def bake_action_iter(
|
||||
|
||||
# Bendy Bones
|
||||
if pbone.bone.bbone_segments > 1:
|
||||
bbones[name] = {bb_prop : getattr(pbone, bb_prop) for bb_prop in BBONE_PROPS}
|
||||
bbones[name] = {bb_prop: getattr(pbone, bb_prop) for bb_prop in BBONE_PROPS}
|
||||
return matrix, bbones
|
||||
|
||||
if do_parents_clear:
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
__all__ = (
|
||||
"load_image",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# limited replacement for BPyImage.comprehensiveImageLoad
|
||||
|
@@ -32,7 +32,7 @@ __all__ = (
|
||||
"path_reference_copy",
|
||||
"path_reference_mode",
|
||||
"unique_name"
|
||||
)
|
||||
)
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
@@ -142,7 +142,8 @@ def orientation_helper_factory(name, axis_forward='Y', axis_up='Z'):
|
||||
|
||||
members['axis_forward'] = EnumProperty(
|
||||
name="Forward",
|
||||
items=(('X', "X Forward", ""),
|
||||
items=(
|
||||
('X', "X Forward", ""),
|
||||
('Y', "Y Forward", ""),
|
||||
('Z', "Z Forward", ""),
|
||||
('-X', "-X Forward", ""),
|
||||
@@ -160,7 +161,8 @@ def orientation_helper_factory(name, axis_forward='Y', axis_up='Z'):
|
||||
|
||||
members['axis_up'] = EnumProperty(
|
||||
name="Up",
|
||||
items=(('X', "X Up", ""),
|
||||
items=(
|
||||
('X', "X Up", ""),
|
||||
('Y', "Y Up", ""),
|
||||
('Z', "Z Up", ""),
|
||||
('-X', "-X Up", ""),
|
||||
@@ -205,7 +207,7 @@ _axis_convert_matrix = (
|
||||
((1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, -1.0)),
|
||||
((1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, -1.0, 0.0)),
|
||||
((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)),
|
||||
)
|
||||
)
|
||||
|
||||
# store args as a single int
|
||||
# (X Y Z -X -Y -Z) --> (0, 1, 2, 3, 4, 5)
|
||||
@@ -282,7 +284,7 @@ _axis_convert_lut = (
|
||||
{0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
|
||||
0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
|
||||
0x045, 0x44D, 0x65D, 0xA65},
|
||||
)
|
||||
)
|
||||
|
||||
_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
|
||||
|
||||
@@ -394,7 +396,8 @@ def unpack_face_list(list_of_tuples):
|
||||
path_reference_mode = EnumProperty(
|
||||
name="Path Mode",
|
||||
description="Method used to reference paths",
|
||||
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
|
||||
items=(
|
||||
('AUTO', "Auto", "Use Relative paths with subdirectories only"),
|
||||
('ABSOLUTE', "Absolute", "Always write absolute paths"),
|
||||
('RELATIVE', "Relative", "Always write relative paths "
|
||||
"(where possible)"),
|
||||
@@ -405,7 +408,7 @@ path_reference_mode = EnumProperty(
|
||||
"(or subdirectory)"),
|
||||
),
|
||||
default='AUTO',
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def path_reference(filepath,
|
||||
|
@@ -27,7 +27,7 @@ __all__ = (
|
||||
"edge_loops_from_edges",
|
||||
"ngon_tessellate",
|
||||
"face_random_points",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def mesh_linked_uv_islands(mesh):
|
||||
@@ -286,7 +286,7 @@ def edge_loops_from_edges(mesh, edges=None):
|
||||
ok = True
|
||||
while ok:
|
||||
ok = False
|
||||
#for i, ed in enumerate(edges):
|
||||
# for i, ed in enumerate(edges):
|
||||
i = len(edges)
|
||||
while i:
|
||||
i -= 1
|
||||
@@ -303,7 +303,7 @@ def edge_loops_from_edges(mesh, edges=None):
|
||||
vert_end = line_poly[-1]
|
||||
ok = 1
|
||||
del edges[i]
|
||||
#break
|
||||
# break
|
||||
elif v1 == vert_start:
|
||||
line_poly.insert(0, v2)
|
||||
vert_start = line_poly[0]
|
||||
@@ -315,7 +315,7 @@ def edge_loops_from_edges(mesh, edges=None):
|
||||
vert_start = line_poly[0]
|
||||
ok = 1
|
||||
del edges[i]
|
||||
#break
|
||||
# break
|
||||
line_polys.append(line_poly)
|
||||
|
||||
return line_polys
|
||||
@@ -481,7 +481,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
|
||||
ii += len(verts)
|
||||
|
||||
fill = tessellate_polygon([[v[0] for v in loop] for loop in loop_list])
|
||||
#draw_loops(loop_list)
|
||||
# draw_loops(loop_list)
|
||||
#raise Exception("done loop")
|
||||
# map to original indices
|
||||
fill = [[vert_map[i] for i in reversed(f)] for f in fill]
|
||||
|
@@ -26,7 +26,7 @@ __all__ = (
|
||||
"object_add_grid_scale_apply_operator",
|
||||
"object_image_guess",
|
||||
"world_to_camera_view",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
import bpy
|
||||
|
@@ -153,6 +153,7 @@ def topretty_py(py_data, indent=" "):
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# testing code.
|
||||
|
||||
|
@@ -19,12 +19,12 @@
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# Original copyright (see docstring):
|
||||
#*****************************************************************************
|
||||
# ****************************************************************************
|
||||
# Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
# ****************************************************************************
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
|
@@ -224,6 +224,7 @@ def execute(context, is_interactive):
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
execute.hooks = []
|
||||
|
||||
|
||||
|
@@ -40,6 +40,7 @@ def shell_run(text):
|
||||
|
||||
add_scrollback(output, style)
|
||||
|
||||
|
||||
PROMPT = "$ "
|
||||
|
||||
|
||||
@@ -64,7 +65,7 @@ def execute(context, is_interactive):
|
||||
|
||||
|
||||
def autocomplete(context):
|
||||
#~ sc = context.space_data
|
||||
# sc = context.space_data
|
||||
# TODO
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
@@ -140,7 +140,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
|
||||
return None
|
||||
|
||||
#rna_path_bone = rna_path[:rna_path.index("]") + 1]
|
||||
#return obj.path_resolve(rna_path_bone)
|
||||
# return obj.path_resolve(rna_path_bone)
|
||||
bone_name = rna_path.split("[")[1].split("]")[0]
|
||||
return obj.pose.bones[bone_name[1:-1]]
|
||||
|
||||
@@ -179,6 +179,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
|
||||
print("\nSaved:", filepath)
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
tmppath = "/tmp/test.dot"
|
||||
|
@@ -36,7 +36,7 @@ __all__ = (
|
||||
"RKS_GEN_rotation",
|
||||
"RKS_GEN_scaling",
|
||||
"RKS_GEN_bendy_bones",
|
||||
)
|
||||
)
|
||||
|
||||
import bpy
|
||||
|
||||
@@ -221,6 +221,7 @@ def RKS_GEN_scaling(ksi, context, ks, data):
|
||||
|
||||
# ------
|
||||
|
||||
|
||||
# Property identifiers for Bendy Bones
|
||||
bbone_property_ids = (
|
||||
"bbone_curveinx",
|
||||
|
@@ -25,7 +25,7 @@ __all__ = (
|
||||
"draw_filtered",
|
||||
"draw_hierarchy",
|
||||
"draw_keymaps",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
import bpy
|
||||
@@ -174,7 +174,7 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
|
||||
sub.prop(kmi, "propvalue", text="")
|
||||
else:
|
||||
# One day...
|
||||
#~ sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="")
|
||||
# sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="")
|
||||
sub.prop(kmi, "idname", text="")
|
||||
|
||||
if map_type not in {'TEXTINPUT', 'TIMER'}:
|
||||
@@ -207,6 +207,7 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
|
||||
draw_km(display_keymaps, kc, kmm, None, layout, level + 1)
|
||||
layout.context_pointer_set("keymap", km)
|
||||
|
||||
|
||||
_EVENT_TYPES = set()
|
||||
_EVENT_TYPE_MAP = {}
|
||||
_EVENT_TYPE_MAP_EXTRA = {}
|
||||
@@ -260,8 +261,8 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
|
||||
kmi_test_type = []
|
||||
|
||||
# initialize? - so if a if a kmi has a MOD assigned it wont show up.
|
||||
#~ for kv in key_mod.values():
|
||||
#~ kmi_test_dict[kv] = {False}
|
||||
# for kv in key_mod.values():
|
||||
# kmi_test_dict[kv] = {False}
|
||||
|
||||
# altname: attr
|
||||
for kk, kv in key_mod.items():
|
||||
@@ -374,7 +375,7 @@ def draw_keymaps(context, layout):
|
||||
|
||||
row = subcol.row(align=True)
|
||||
|
||||
#~ row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config")
|
||||
# row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config")
|
||||
text = bpy.path.display_name(wm.keyconfigs.active.name)
|
||||
if not text:
|
||||
text = "Blender (default)"
|
||||
@@ -382,8 +383,8 @@ def draw_keymaps(context, layout):
|
||||
row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMIN')
|
||||
row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMOUT').remove_active = True
|
||||
|
||||
#~ layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
|
||||
#~ row.operator("wm.keyconfig_remove", text="", icon='X')
|
||||
# layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
|
||||
# row.operator("wm.keyconfig_remove", text="", icon='X')
|
||||
row.separator()
|
||||
rowsub = row.split(align=True, percentage=0.33)
|
||||
# postpone drawing into rowsub, so we can set alert!
|
||||
|
@@ -26,7 +26,7 @@ import bmesh
|
||||
__all__ = (
|
||||
"select_prev",
|
||||
"select_next",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def other_edges_over_face(e):
|
||||
@@ -304,7 +304,8 @@ def select_next(bm, report):
|
||||
uuid_cmp_test = fn(uuid_cmp)
|
||||
ele_pair_next_uuid_test = [
|
||||
(ele, uuid) for (ele, uuid) in ele_pair_next_uuid
|
||||
if uuid_cmp_test == fn(uuid)]
|
||||
if uuid_cmp_test == fn(uuid)
|
||||
]
|
||||
if len(ele_pair_next_uuid_test) > 1:
|
||||
ele_pair_next_uuid = ele_pair_next_uuid_test
|
||||
elif len(ele_pair_next_uuid_test) == 1:
|
||||
|
@@ -527,6 +527,8 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
|
||||
ksi.addProp(ks, bone, prop)
|
||||
|
||||
# All properties that are likely to get animated in a character rig, only selected bones.
|
||||
|
||||
|
||||
class BUILTIN_KSI_WholeCharacterSelected(KeyingSetInfo):
|
||||
"""Insert a keyframe for all properties that are likely to get animated in a character rig """
|
||||
"""(only selected bones)"""
|
||||
@@ -557,6 +559,8 @@ class BUILTIN_KSI_WholeCharacterSelected(KeyingSetInfo):
|
||||
###############################
|
||||
|
||||
# Delta Location
|
||||
|
||||
|
||||
class BUILTIN_KSI_DeltaLocation(KeyingSetInfo):
|
||||
"""Insert keyframes for additional location offset"""
|
||||
bl_label = "Delta Location"
|
||||
@@ -643,6 +647,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
|
||||
|
||||
###############################
|
||||
|
||||
|
||||
# Note that this controls order of options in 'insert keyframe' menu.
|
||||
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
||||
# See also T51867.
|
||||
|
@@ -61,12 +61,13 @@ def group_tools_draw(self, layout, context):
|
||||
layout.operator("node.group_ungroup")
|
||||
layout.separator()
|
||||
|
||||
|
||||
# maps node tree type to group node type
|
||||
node_tree_group_type = {
|
||||
'CompositorNodeTree': 'CompositorNodeGroup',
|
||||
'ShaderNodeTree': 'ShaderNodeGroup',
|
||||
'TextureNodeTree': 'TextureNodeGroup',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# generic node group items generator for shader, compositor and texture node groups
|
||||
@@ -273,7 +274,7 @@ shader_node_categories = [
|
||||
NodeItem("NodeFrame"),
|
||||
NodeItem("NodeReroute"),
|
||||
]),
|
||||
]
|
||||
]
|
||||
|
||||
compositor_node_categories = [
|
||||
# Compositor Nodes
|
||||
@@ -386,7 +387,7 @@ compositor_node_categories = [
|
||||
NodeItem("NodeReroute"),
|
||||
NodeItem("CompositorNodeSwitch"),
|
||||
]),
|
||||
]
|
||||
]
|
||||
|
||||
texture_node_categories = [
|
||||
# Texture Nodes
|
||||
@@ -444,7 +445,7 @@ texture_node_categories = [
|
||||
NodeItem("NodeFrame"),
|
||||
NodeItem("NodeReroute"),
|
||||
]),
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
def register():
|
||||
|
@@ -68,7 +68,7 @@ def image_from_file(filepath):
|
||||
|
||||
if bpy is not None:
|
||||
pixels, pixel_w, pixel_h = image_from_file__bpy(filepath)
|
||||
#else:
|
||||
# else:
|
||||
# pixels, pixel_w, pixel_h = image_from_file__py(filepath)
|
||||
|
||||
return pixels, pixel_w, pixel_h
|
||||
@@ -95,7 +95,9 @@ def write_subimage(sub_x, sub_y, sub_w, sub_h,
|
||||
|
||||
with open(filepath, 'wb') as f:
|
||||
|
||||
f.write(struct.pack('<6I',
|
||||
f.write(
|
||||
struct.pack(
|
||||
'<6I',
|
||||
sub_w, sub_h,
|
||||
sub_x, sub_y,
|
||||
# redundant but including to maintain consistency
|
||||
@@ -113,7 +115,8 @@ def write_subimage(sub_x, sub_y, sub_w, sub_h,
|
||||
_dice_icon_name_cache = {}
|
||||
|
||||
|
||||
def dice_icon_name(x, y, parts_x, parts_y,
|
||||
def dice_icon_name(
|
||||
x, y, parts_x, parts_y,
|
||||
name_style=None, prefix=""):
|
||||
"""
|
||||
How to name icons, this is mainly for what name we get in git,
|
||||
@@ -143,7 +146,7 @@ def dice_icon_name(x, y, parts_x, parts_y,
|
||||
icon_name = _dice_icon_name_cache[index]
|
||||
|
||||
# for debugging its handy to sort by number
|
||||
#~ id_str = "%03d_%s%s.dat" % (index, prefix, icon_name)
|
||||
# ~ id_str = "%03d_%s%s.dat" % (index, prefix, icon_name)
|
||||
|
||||
id_str = "%s%s.dat" % (prefix, icon_name)
|
||||
|
||||
@@ -158,14 +161,16 @@ def dice_icon_name(x, y, parts_x, parts_y,
|
||||
return id_str
|
||||
|
||||
|
||||
def dice(filepath, output, output_prefix, name_style,
|
||||
def dice(
|
||||
filepath, output, output_prefix, name_style,
|
||||
parts_x, parts_y,
|
||||
minx, miny, maxx, maxy,
|
||||
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
||||
spacex_icon, spacey_icon,
|
||||
):
|
||||
):
|
||||
|
||||
is_simple = (max(minx, miny, maxx, maxy,
|
||||
is_simple = (max(
|
||||
minx, miny, maxx, maxy,
|
||||
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
||||
spacex_icon, spacey_icon) == 0)
|
||||
|
||||
@@ -199,9 +204,11 @@ def dice(filepath, output, output_prefix, name_style,
|
||||
|
||||
for x in range(parts_x):
|
||||
for y in range(parts_y):
|
||||
id_str = dice_icon_name(x, y,
|
||||
id_str = dice_icon_name(
|
||||
x, y,
|
||||
parts_x, parts_y,
|
||||
name_style=name_style, prefix=output_prefix)
|
||||
name_style=name_style, prefix=output_prefix
|
||||
)
|
||||
filepath = os.path.join(output, id_str)
|
||||
if VERBOSE:
|
||||
print(" writing:", filepath)
|
||||
@@ -235,25 +242,35 @@ def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__, epilog=epilog)
|
||||
|
||||
# File path options
|
||||
parser.add_argument("--image", dest="image", metavar='FILE',
|
||||
help="Image file")
|
||||
|
||||
parser.add_argument("--output", dest="output", metavar='DIR',
|
||||
help="Output directory")
|
||||
|
||||
parser.add_argument("--output_prefix", dest="output_prefix", metavar='STRING',
|
||||
help="Output prefix")
|
||||
parser.add_argument(
|
||||
"--image", dest="image", metavar='FILE',
|
||||
help="Image file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output", dest="output", metavar='DIR',
|
||||
help="Output directory",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output_prefix", dest="output_prefix", metavar='STRING',
|
||||
help="Output prefix",
|
||||
)
|
||||
|
||||
# Icon naming option
|
||||
parser.add_argument("--name_style", dest="name_style", metavar='ENUM', type=str,
|
||||
parser.add_argument(
|
||||
"--name_style", dest="name_style", metavar='ENUM', type=str,
|
||||
choices=('', 'UI_ICONS'),
|
||||
help="The metod used for naming output data")
|
||||
help="The metod used for naming output data",
|
||||
)
|
||||
|
||||
# Options for dicing up the image
|
||||
parser.add_argument("--parts_x", dest="parts_x", metavar='INT', type=int,
|
||||
help="Grid X parts")
|
||||
parser.add_argument("--parts_y", dest="parts_y", metavar='INT', type=int,
|
||||
help="Grid Y parts")
|
||||
parser.add_argument(
|
||||
"--parts_x", dest="parts_x", metavar='INT', type=int,
|
||||
help="Grid X parts",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--parts_y", dest="parts_y", metavar='INT', type=int,
|
||||
help="Grid Y parts",
|
||||
)
|
||||
|
||||
_help = "Inset from the outer edge (in pixels)"
|
||||
parser.add_argument("--minx", dest="minx", metavar='INT', type=int, help=_help)
|
||||
@@ -287,5 +304,6 @@ def main():
|
||||
args.spacex_icon, args.spacey_icon,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -67,5 +67,6 @@ def main():
|
||||
|
||||
icondata_to_png(file_src, file_dst)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -56,19 +56,19 @@ def check_commandline():
|
||||
"""
|
||||
import sys
|
||||
# Usage
|
||||
if len(sys.argv)==1 or len(sys.argv)>3:
|
||||
if len(sys.argv) == 1 or len(sys.argv) > 3:
|
||||
usage()
|
||||
if sys.argv[1] == '-h':
|
||||
help()
|
||||
elif not sys.argv[1].endswith((".txt", ".py")):
|
||||
print ('\nBad input file extension... exiting.')
|
||||
print('\nBad input file extension... exiting.')
|
||||
usage()
|
||||
else:
|
||||
inputfile = sys.argv[1]
|
||||
if len(sys.argv) == 2:
|
||||
sort_priority = default_sort_choice
|
||||
print ('\nSecond parameter missing: choosing to order by %s.' % font_bold(sort_priority))
|
||||
elif len(sys.argv)==3:
|
||||
print('\nSecond parameter missing: choosing to order by %s.' % font_bold(sort_priority))
|
||||
elif len(sys.argv) == 3:
|
||||
sort_priority = sys.argv[2]
|
||||
if sort_priority not in sort_choices:
|
||||
print('\nWrong sort_priority... exiting.')
|
||||
@@ -93,9 +93,11 @@ def check_prefix(prop, btype):
|
||||
return ""
|
||||
|
||||
|
||||
def check_if_changed(a,b):
|
||||
if a != b: return 'changed'
|
||||
else: return 'same'
|
||||
def check_if_changed(a, b):
|
||||
if a != b:
|
||||
return 'changed'
|
||||
else:
|
||||
return 'same'
|
||||
|
||||
|
||||
def get_props_from_txt(input_filename):
|
||||
@@ -103,12 +105,12 @@ def get_props_from_txt(input_filename):
|
||||
If the file is *.txt, the script assumes it is formatted as outlined in this script docstring
|
||||
"""
|
||||
|
||||
file=open(input_filename,'r')
|
||||
file_lines=file.readlines()
|
||||
file = open(input_filename, 'r')
|
||||
file_lines = file.readlines()
|
||||
file.close()
|
||||
|
||||
props_list=[]
|
||||
props_length_max=[0,0,0,0,0,0,0,0]
|
||||
props_list = []
|
||||
props_length_max = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
done_text = "+"
|
||||
done = 0
|
||||
@@ -117,7 +119,7 @@ def get_props_from_txt(input_filename):
|
||||
for iii, line in enumerate(file_lines):
|
||||
|
||||
# debug
|
||||
#print(line)
|
||||
# print(line)
|
||||
line_strip = line.strip()
|
||||
# empty line or comment
|
||||
if not line_strip:
|
||||
@@ -136,7 +138,7 @@ def get_props_from_txt(input_filename):
|
||||
if '*' in bclass:
|
||||
comment, bclass = [x.strip() for x in bclass.split('*', 1)]
|
||||
else:
|
||||
comment= ''
|
||||
comment = ''
|
||||
|
||||
# skipping the header if we have one.
|
||||
# the header is assumed to be "NOTE * CLASS.FROM -> TO: TYPE DESCRIPTION"
|
||||
@@ -155,7 +157,7 @@ def get_props_from_txt(input_filename):
|
||||
# make life easy and strip quotes
|
||||
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
||||
except ValueError:
|
||||
btype, description = [tail,'NO DESCRIPTION']
|
||||
btype, description = [tail, 'NO DESCRIPTION']
|
||||
|
||||
# keyword-check
|
||||
kwcheck = check_prefix(bto, btype)
|
||||
@@ -164,17 +166,17 @@ def get_props_from_txt(input_filename):
|
||||
changed = check_if_changed(bfrom, bto)
|
||||
|
||||
# lists formatting
|
||||
props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
||||
props = [comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
||||
props_list.append(props)
|
||||
props_length_max=list(map(max,zip(props_length_max,list(map(len,props)))))
|
||||
props_length_max = list(map(max, zip(props_length_max, list(map(len, props)))))
|
||||
|
||||
if done_text in comment:
|
||||
done += 1
|
||||
tot += 1
|
||||
|
||||
print("Total done %.2f" % (done / tot * 100.0) )
|
||||
print("Total done %.2f" % (done / tot * 100.0))
|
||||
|
||||
return (props_list,props_length_max)
|
||||
return (props_list, props_length_max)
|
||||
|
||||
|
||||
def get_props_from_py(input_filename):
|
||||
@@ -186,24 +188,24 @@ def get_props_from_py(input_filename):
|
||||
rna_api = __import__(input_filename[:-3]).rna_api
|
||||
|
||||
props_length_max = [0 for i in rna_api[0]] # this way if the vector will take more elements we are safe
|
||||
for index,props in enumerate(rna_api):
|
||||
for index, props in enumerate(rna_api):
|
||||
comment, changed, bclass, bfrom, bto, kwcheck, btype, description = props
|
||||
kwcheck = check_prefix(bto, btype) # keyword-check
|
||||
changed = check_if_changed(bfrom, bto) # changed?
|
||||
description = repr(description)
|
||||
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
||||
rna_api[index] = [comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
||||
props_length = list(map(len,props)) # lengths
|
||||
props_length_max = list(map(max,zip(props_length_max,props_length))) # max lengths
|
||||
return (rna_api,props_length_max)
|
||||
props_length = list(map(len, props)) # lengths
|
||||
props_length_max = list(map(max, zip(props_length_max, props_length))) # max lengths
|
||||
return (rna_api, props_length_max)
|
||||
|
||||
|
||||
def get_props(input_filename):
|
||||
if input_filename.endswith(".txt"):
|
||||
props_list,props_length_max = get_props_from_txt(input_filename)
|
||||
props_list, props_length_max = get_props_from_txt(input_filename)
|
||||
elif input_filename.endswith(".py"):
|
||||
props_list,props_length_max = get_props_from_py(input_filename)
|
||||
return (props_list,props_length_max)
|
||||
props_list, props_length_max = get_props_from_py(input_filename)
|
||||
return (props_list, props_length_max)
|
||||
|
||||
|
||||
def sort(props_list, sort_priority):
|
||||
@@ -222,7 +224,7 @@ def sort(props_list, sort_priority):
|
||||
else:
|
||||
props_list = sorted(props_list, key=lambda p: p[i])
|
||||
|
||||
print ('\nSorted by %s.' % font_bold(sort_priority))
|
||||
print('\nSorted by %s.' % font_bold(sort_priority))
|
||||
return props_list
|
||||
|
||||
|
||||
@@ -250,30 +252,35 @@ def write_files(basename, props_list, props_length_max):
|
||||
* rna_api.py: unformatted, just as final output
|
||||
"""
|
||||
|
||||
f_rna = open("rna_api.py",'w')
|
||||
f_txt = open(basename + '_work.txt','w')
|
||||
f_py = open(basename + '_work.py','w')
|
||||
f_rna = open("rna_api.py", 'w')
|
||||
f_txt = open(basename + '_work.txt', 'w')
|
||||
f_py = open(basename + '_work.py', 'w')
|
||||
|
||||
# reminder: props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
||||
# [comment *] ToolSettings.snap_align_rotation -> use_snap_align_rotation: boolean [Align rotation with the snapping target]
|
||||
rna = py = txt = ''
|
||||
props_list = [['NOTE', 'CHANGED', 'CLASS', 'FROM', 'TO', 'KEYWORD-CHECK', 'TYPE', 'DESCRIPTION']] + props_list
|
||||
for props in props_list:
|
||||
#txt
|
||||
# txt
|
||||
|
||||
# quick way we can tell if it changed
|
||||
if props[3] == props[4]: txt += "#"
|
||||
else: txt += " "
|
||||
if props[3] == props[4]:
|
||||
txt += "#"
|
||||
else:
|
||||
txt += " "
|
||||
|
||||
if props[0] != '': txt += '%s * ' % props[0] # comment
|
||||
if props[0] != '':
|
||||
txt += '%s * ' % props[0] # comment
|
||||
txt += '%s.%s -> %s: %s "%s"\n' % tuple(props[2:5] + props[6:]) # skipping keyword-check
|
||||
# rna_api
|
||||
if props[0] == 'NOTE': indent = '# '
|
||||
else: indent = ' '
|
||||
if props[0] == 'NOTE':
|
||||
indent = '# '
|
||||
else:
|
||||
indent = ' '
|
||||
rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:]) # description is already string formatted
|
||||
# py
|
||||
blanks = [' '* (x[0]-x[1]) for x in zip(props_length_max,list(map(len,props)))]
|
||||
props = [('"%s"%s' if props[-1] != x[0] else "%s%s") % (x[0],x[1]) for x in zip(props,blanks)]
|
||||
blanks = [' ' * (x[0] - x[1]) for x in zip(props_length_max, list(map(len, props)))]
|
||||
props = [('"%s"%s' if props[-1] != x[0] else "%s%s") % (x[0], x[1]) for x in zip(props, blanks)]
|
||||
py += indent + '(%s, %s, %s, %s, %s, %s, %s, "%s"),\n' % tuple(props)
|
||||
|
||||
f_txt.write(txt)
|
||||
@@ -290,7 +297,7 @@ def write_files(basename, props_list, props_length_max):
|
||||
f_py.close()
|
||||
f_rna.close()
|
||||
|
||||
print ('\nSaved %s, %s and %s.\n' % (font_bold(f_txt.name), font_bold(f_py.name), font_bold(f_rna.name) ) )
|
||||
print('\nSaved %s, %s and %s.\n' % (font_bold(f_txt.name), font_bold(f_py.name), font_bold(f_rna.name)))
|
||||
|
||||
|
||||
def main():
|
||||
@@ -298,21 +305,21 @@ def main():
|
||||
global sort_choices, default_sort_choice
|
||||
global kw_prefixes, kw
|
||||
|
||||
sort_choices = ['note','changed','class','from','to','kw', 'class.to']
|
||||
sort_choices = ['note', 'changed', 'class', 'from', 'to', 'kw', 'class.to']
|
||||
default_sort_choice = sort_choices[-1]
|
||||
kw_prefixes = [ 'active','apply','bl','exclude','has','invert','is','lock', \
|
||||
'pressed','show','show_only','use','use_only','layers','states', 'select']
|
||||
kw = ['active','hide','invert','select','layers','mute','states','use','lock']
|
||||
kw_prefixes = ['active', 'apply', 'bl', 'exclude', 'has', 'invert', 'is', 'lock',
|
||||
'pressed', 'show', 'show_only', 'use', 'use_only', 'layers', 'states', 'select']
|
||||
kw = ['active', 'hide', 'invert', 'select', 'layers', 'mute', 'states', 'use', 'lock']
|
||||
|
||||
input_filename, sort_priority = check_commandline()
|
||||
props_list,props_length_max = get_props(input_filename)
|
||||
props_list = sort(props_list,sort_priority)
|
||||
props_list, props_length_max = get_props(input_filename)
|
||||
props_list = sort(props_list, sort_priority)
|
||||
|
||||
output_basename = file_basename(input_filename)
|
||||
write_files(output_basename, props_list,props_length_max)
|
||||
write_files(output_basename, props_list, props_length_max)
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if not sys.version.startswith("3"):
|
||||
print("Incorrect python version, use python 3!")
|
||||
|
@@ -6,12 +6,13 @@ import sys
|
||||
Example usage:
|
||||
python3 rna_cleaner_merge.py out_work.py rna_booleans_work.py
|
||||
'''
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
def work_line_id(line):
|
||||
return line[2].split("|")[-1], line[3] # class/from
|
||||
|
||||
|
||||
if not (sys.argv[-1].endswith(".py") and sys.argv[-2].endswith(".py")):
|
||||
print("Only accepts 2 py files as arguments.")
|
||||
|
||||
@@ -57,5 +58,6 @@ def main():
|
||||
write_work_file(file_path, list(mod_from_dict.values()))
|
||||
print("Warning '%s' contains lost %d items from module %s.py" % (file_path, len(mod_from_dict), mod_from.__name__))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -129,6 +129,7 @@ def seek(r, txt, recurs):
|
||||
newtxt = txt + '[' + str(i) + ']'
|
||||
seek(r[i], newtxt, recurs + 1)
|
||||
|
||||
|
||||
seek(bpy.data, 'bpy.data', 0)
|
||||
# seek(bpy.types, 'bpy.types', 0)
|
||||
'''
|
||||
@@ -140,8 +141,8 @@ for d in dir(bpy.types):
|
||||
seek(r, 'bpy.types.' + d + '.bl_rna', 0)
|
||||
'''
|
||||
|
||||
#print dir(bpy)
|
||||
# print dir(bpy)
|
||||
#import sys
|
||||
#sys.exit()
|
||||
# sys.exit()
|
||||
|
||||
print("iter over ", seek_count, "rna items")
|
||||
|
@@ -50,8 +50,10 @@ for d in defs.split('\n'):
|
||||
if not w:
|
||||
continue
|
||||
|
||||
try: w.remove("#define")
|
||||
except: pass
|
||||
try:
|
||||
w.remove("#define")
|
||||
except:
|
||||
pass
|
||||
|
||||
# print w
|
||||
|
||||
|
@@ -142,5 +142,6 @@ def main():
|
||||
else:
|
||||
print("\nnone found!")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@@ -33,7 +33,6 @@ from modules.test_utils import (with_tempdir,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class AbcPropError(Exception):
|
||||
"""Raised when AbstractAlembicTest.abcprop() finds an error."""
|
||||
|
||||
|
@@ -109,7 +109,6 @@ class SimpleImportTest(AbstractAlembicTest):
|
||||
self.assertAlmostEqual(0, y)
|
||||
self.assertAlmostEqual(2, z)
|
||||
|
||||
|
||||
def test_select_after_import(self):
|
||||
# Add a sphere, so that there is something in the scene, selected, and active,
|
||||
# before we do the Alembic import.
|
||||
|
@@ -33,7 +33,7 @@ import imp
|
||||
|
||||
BLACKLIST_DIRS = (
|
||||
os.path.join(bpy.utils.resource_path('USER'), "scripts"),
|
||||
) + tuple(addon_utils.paths()[1:])
|
||||
) + tuple(addon_utils.paths()[1:])
|
||||
BLACKLIST_ADDONS = set()
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ def addon_modules_sorted():
|
||||
modules[:] = [
|
||||
mod for mod in modules
|
||||
if not (mod.__file__.startswith(BLACKLIST_DIRS))
|
||||
if not (mod.__name__ in BLACKLIST_ADDONS)]
|
||||
if not (mod.__name__ in BLACKLIST_ADDONS)
|
||||
]
|
||||
modules.sort(key=lambda mod: mod.__name__)
|
||||
return modules
|
||||
|
||||
|
@@ -39,20 +39,20 @@ BLACKLIST = {
|
||||
|
||||
# The unpacked wheel is only loaded when actually used, not directly on import:
|
||||
os.path.join("io_blend_utils", "blender_bam-unpacked.whl"),
|
||||
}
|
||||
}
|
||||
|
||||
# Some modules need to add to the `sys.path`.
|
||||
MODULE_SYS_PATHS = {
|
||||
# Runs in a Python subprocess, so its expected its basedir can be imported.
|
||||
"io_blend_utils.blendfile_pack": ".",
|
||||
}
|
||||
}
|
||||
|
||||
if not bpy.app.build_options.freestyle:
|
||||
BLACKLIST.add("render_freestyle_svg")
|
||||
|
||||
BLACKLIST_DIRS = (
|
||||
os.path.join(bpy.utils.resource_path('USER'), "scripts"),
|
||||
) + tuple(addon_utils.paths()[1:])
|
||||
) + tuple(addon_utils.paths()[1:])
|
||||
|
||||
|
||||
def module_names_recursive(mod_dir, *, parent=None):
|
||||
@@ -248,6 +248,7 @@ def main():
|
||||
load_addons()
|
||||
load_modules()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# So a python error exits(1)
|
||||
try:
|
||||
|
@@ -61,11 +61,11 @@ def render_gl(context, filepath, shade):
|
||||
|
||||
ctx_shading_type(context, shade)
|
||||
|
||||
#~ # stop to inspect!
|
||||
#~ if filepath == "test_cube_shell_solidify_subsurf_wp_wire":
|
||||
#~ assert(0)
|
||||
#~ else:
|
||||
#~ return
|
||||
# stop to inspect!
|
||||
# if filepath == "test_cube_shell_solidify_subsurf_wp_wire":
|
||||
# assert(0)
|
||||
# else:
|
||||
# return
|
||||
|
||||
bpy.ops.render.opengl(write_still=True,
|
||||
view_context=True)
|
||||
@@ -219,6 +219,7 @@ def mesh_bmesh_poly_elems(poly, elems):
|
||||
vert_total = poly.loop_total
|
||||
return elems[vert_start:vert_start + vert_total]
|
||||
|
||||
|
||||
def mesh_bmesh_poly_vertices(poly):
|
||||
return [loop.vertex_index
|
||||
for loop in mesh_bmesh_poly_elems(poly, poly.id_data.loops)]
|
||||
@@ -505,7 +506,7 @@ cube_like_vertices = (
|
||||
(-1, 1, 3),
|
||||
(0, 1, 3),
|
||||
(0, 0, 3),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
cube_like_faces = (
|
||||
@@ -547,7 +548,7 @@ cube_like_faces = (
|
||||
(31, 30, 36, 33),
|
||||
(32, 31, 33, 34),
|
||||
(35, 34, 33, 36),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# useful since its a shell for solidify and it can be mirrored
|
||||
@@ -564,7 +565,7 @@ cube_shell_vertices = (
|
||||
(0, -1, 0),
|
||||
(0, 0, -1),
|
||||
(0, 1, -1),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
cube_shell_face = (
|
||||
@@ -577,7 +578,7 @@ cube_shell_face = (
|
||||
(6, 5, 11),
|
||||
(7, 4, 9, 8),
|
||||
(10, 7, 6, 11),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def make_cube(scene):
|
||||
@@ -678,59 +679,77 @@ def make_monkey_extra(scene):
|
||||
|
||||
global_tests = []
|
||||
|
||||
global_tests.append(("none",
|
||||
global_tests.append(
|
||||
("none",
|
||||
(),
|
||||
))
|
||||
|
||||
)
|
||||
)
|
||||
# single
|
||||
global_tests.append(("subsurf_single",
|
||||
global_tests.append(
|
||||
("subsurf_single",
|
||||
((modifier_subsurf_add, dict(levels=2)), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
global_tests.append(("armature_single",
|
||||
global_tests.append(
|
||||
("armature_single",
|
||||
((modifier_armature_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
global_tests.append(("mirror_single",
|
||||
global_tests.append(
|
||||
("mirror_single",
|
||||
((modifier_mirror_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
global_tests.append(("hook_single",
|
||||
global_tests.append(
|
||||
("hook_single",
|
||||
((modifier_hook_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
global_tests.append(("decimate_single",
|
||||
global_tests.append(
|
||||
("decimate_single",
|
||||
((modifier_decimate_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
global_tests.append(("build_single",
|
||||
global_tests.append(
|
||||
("build_single",
|
||||
((modifier_build_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
global_tests.append(("mask_single",
|
||||
global_tests.append(
|
||||
("mask_single",
|
||||
((modifier_mask_add, dict()), ),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# combinations
|
||||
global_tests.append(("mirror_subsurf",
|
||||
global_tests.append(
|
||||
("mirror_subsurf",
|
||||
((modifier_mirror_add, dict()),
|
||||
(modifier_subsurf_add, dict(levels=2))),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
global_tests.append(("solidify_subsurf",
|
||||
global_tests.append(
|
||||
("solidify_subsurf",
|
||||
((modifier_solidify_add, dict()),
|
||||
(modifier_subsurf_add, dict(levels=2))),
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def apply_test(test, scene, obj,
|
||||
def apply_test(
|
||||
test, scene, obj,
|
||||
render_func=None,
|
||||
render_args=None,
|
||||
render_kwargs=None,
|
||||
):
|
||||
):
|
||||
|
||||
test_name, test_funcs = test
|
||||
|
||||
@@ -756,10 +775,12 @@ def test_cube(context, test):
|
||||
obj = make_cube_extra(scene)
|
||||
ctx_camera_setup(context, location=(3, 3, 3))
|
||||
|
||||
apply_test(test, scene, obj,
|
||||
apply_test(
|
||||
test, scene, obj,
|
||||
render_func=render_gl_all_modes,
|
||||
render_args=(context, obj),
|
||||
render_kwargs=dict(filepath=whoami()))
|
||||
render_kwargs=dict(filepath=whoami())
|
||||
)
|
||||
|
||||
|
||||
def test_cube_like(context, test):
|
||||
@@ -767,10 +788,12 @@ def test_cube_like(context, test):
|
||||
obj = make_cube_like_extra(scene)
|
||||
ctx_camera_setup(context, location=(5, 5, 5))
|
||||
|
||||
apply_test(test, scene, obj,
|
||||
apply_test(
|
||||
test, scene, obj,
|
||||
render_func=render_gl_all_modes,
|
||||
render_args=(context, obj),
|
||||
render_kwargs=dict(filepath=whoami()))
|
||||
render_kwargs=dict(filepath=whoami())
|
||||
)
|
||||
|
||||
|
||||
def test_cube_shell(context, test):
|
||||
@@ -778,10 +801,12 @@ def test_cube_shell(context, test):
|
||||
obj = make_cube_shell_extra(scene)
|
||||
ctx_camera_setup(context, location=(4, 4, 4))
|
||||
|
||||
apply_test(test, scene, obj,
|
||||
apply_test(
|
||||
test, scene, obj,
|
||||
render_func=render_gl_all_modes,
|
||||
render_args=(context, obj),
|
||||
render_kwargs=dict(filepath=whoami()))
|
||||
render_kwargs=dict(filepath=whoami())
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@@ -76,7 +76,7 @@ BUILTINS = (
|
||||
"primitive_grid_add",
|
||||
"primitive_monkey_add",
|
||||
"primitive_torus_add",
|
||||
)
|
||||
)
|
||||
BUILTINS_NBR = 4
|
||||
BUILTINS_NBRCHANGES = 5
|
||||
|
||||
|
@@ -5,11 +5,12 @@ import unittest
|
||||
|
||||
from bpy.utils import units
|
||||
|
||||
|
||||
class UnitsTesting(unittest.TestCase):
|
||||
# From user typing to 'internal' Blender value.
|
||||
INPUT_TESTS = (
|
||||
# system, type, ref, input, value
|
||||
##### LENGTH
|
||||
# LENGTH
|
||||
('IMPERIAL', 'LENGTH', "", "1ft", 0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "(1+1)ft", 0.3048 * 2),
|
||||
('IMPERIAL', 'LENGTH', "", "1mi4\"", 1609.344 + 0.0254 * 4),
|
||||
@@ -31,7 +32,7 @@ class UnitsTesting(unittest.TestCase):
|
||||
# From 'internal' Blender value to user-friendly printing
|
||||
OUTPUT_TESTS = (
|
||||
# system, type, prec, sep, compat, value, output
|
||||
##### LENGTH
|
||||
# LENGTH
|
||||
# Note: precision handling is a bit complicated when using multi-units...
|
||||
('IMPERIAL', 'LENGTH', 3, False, False, 0.3048, "1'"),
|
||||
('IMPERIAL', 'LENGTH', 3, False, True, 0.3048, "1ft"),
|
||||
@@ -63,9 +64,13 @@ class UnitsTesting(unittest.TestCase):
|
||||
def test_units_outputs(self):
|
||||
for usys, utype, prec, sep, compat, val, output in self.OUTPUT_TESTS:
|
||||
opt_str = units.to_string(usys, utype, val, prec, sep, compat)
|
||||
self.assertEqual(opt_str, output,
|
||||
msg="%s, %s: %f (precision: %d, separate units: %d, compat units: %d) => "
|
||||
"\"%s\", expected \"%s\"" % (usys, utype, val, prec, sep, compat, opt_str, output))
|
||||
self.assertEqual(
|
||||
opt_str, output,
|
||||
msg=(
|
||||
"%s, %s: %f (precision: %d, separate units: %d, compat units: %d) => "
|
||||
"\"%s\", expected \"%s\""
|
||||
) % (usys, utype, val, prec, sep, compat, opt_str, output)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@@ -198,6 +198,7 @@ class TestBufferProtocol(TestHelper, unittest.TestCase):
|
||||
self.assertEqual(list(view1), list(view2))
|
||||
self.assertEqual(view1.tobytes(), view2.tobytes())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
||||
|
@@ -61,8 +61,10 @@ class TestClass(bpy.types.PropertyGroup):
|
||||
def get_scene(lib_name, sce_name):
|
||||
for s in bpy.data.scenes:
|
||||
if s.name == sce_name:
|
||||
if (s.library and s.library.name == lib_name) or \
|
||||
(lib_name == None and s.library == None):
|
||||
if (
|
||||
(s.library and s.library.name == lib_name) or
|
||||
(lib_name is None and s.library is None)
|
||||
):
|
||||
return s
|
||||
|
||||
|
||||
@@ -309,6 +311,7 @@ def test_restrictions2():
|
||||
|
||||
class TestUIList(UIList):
|
||||
test = bpy.props.PointerProperty(type=bpy.types.Object)
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
|
||||
|
||||
|
@@ -21,8 +21,8 @@ vector_data = (
|
||||
(-0.854645, 0.518036, 0.033936),
|
||||
(0.42514, -0.437866, -0.792114),
|
||||
(-0.358948, 0.597046, 0.717377),
|
||||
(-0.985413,0.144714, 0.089294),
|
||||
)
|
||||
(-0.985413, 0.144714, 0.089294),
|
||||
)
|
||||
|
||||
# get data at different scales
|
||||
vector_data = sum(
|
||||
@@ -33,10 +33,10 @@ vector_data = sum(
|
||||
|
||||
class MatrixTesting(unittest.TestCase):
|
||||
def test_matrix_column_access(self):
|
||||
#mat =
|
||||
#[ 1 2 3 4 ]
|
||||
#[ 1 2 3 4 ]
|
||||
#[ 1 2 3 4 ]
|
||||
# mat =
|
||||
# [ 1 2 3 4 ]
|
||||
# [ 1 2 3 4 ]
|
||||
# [ 1 2 3 4 ]
|
||||
mat = Matrix(((1, 11, 111),
|
||||
(2, 22, 222),
|
||||
(3, 33, 333),
|
||||
@@ -81,11 +81,11 @@ class MatrixTesting(unittest.TestCase):
|
||||
self.assertIn(item, indices)
|
||||
|
||||
def test_matrix_to_3x3(self):
|
||||
#mat =
|
||||
#[ 1 2 3 4 ]
|
||||
#[ 2 4 6 8 ]
|
||||
#[ 3 6 9 12 ]
|
||||
#[ 4 8 12 16 ]
|
||||
# mat =
|
||||
# [ 1 2 3 4 ]
|
||||
# [ 2 4 6 8 ]
|
||||
# [ 3 6 9 12 ]
|
||||
# [ 4 8 12 16 ]
|
||||
mat = Matrix(tuple((i, 2 * i, 3 * i, 4 * i) for i in range(1, 5)))
|
||||
mat_correct = Matrix(((1, 2, 3), (2, 4, 6), (3, 6, 9)))
|
||||
self.assertEqual(mat.to_3x3(), mat_correct)
|
||||
@@ -372,7 +372,6 @@ class KDTreeTesting(unittest.TestCase):
|
||||
ret_filter = k_all.find(co, lambda i: (i % 2) == 0)
|
||||
self.assertAlmostEqualVector(ret_regular, ret_filter)
|
||||
|
||||
|
||||
# filter out all values (search odd tree for even values and the reverse)
|
||||
co = (0,) * 3
|
||||
ret_filter = k_odd.find(co, lambda i: (i % 2) == 0)
|
||||
|
@@ -8,7 +8,7 @@ DUMMY_NAME = "Untitled"
|
||||
DUMMY_PATH = __file__
|
||||
GLOBALS = {
|
||||
"error_num": 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def as_float_32(f):
|
||||
@@ -142,5 +142,6 @@ def main():
|
||||
|
||||
print("Error (total): %d" % GLOBALS["error_num"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -155,5 +155,6 @@ def main():
|
||||
test_language_coverage()
|
||||
test_urls()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -36,7 +36,7 @@ RANDOM_MULTIPLY = 10
|
||||
|
||||
STATE = {
|
||||
"counter": 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
op_blacklist = (
|
||||
@@ -91,7 +91,7 @@ op_blacklist = (
|
||||
"wm.keymap_restore", # another annoying one
|
||||
"wm.addon_*", # harmless, but dont change state
|
||||
"console.*", # just annoying - but harmless
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def blend_list(mainpath):
|
||||
@@ -114,6 +114,7 @@ def blend_list(mainpath):
|
||||
|
||||
return list(sorted(file_list(mainpath, is_blend)))
|
||||
|
||||
|
||||
if USE_FILES:
|
||||
USE_FILES_LS = blend_list(USE_FILES)
|
||||
# print(USE_FILES_LS)
|
||||
@@ -480,8 +481,9 @@ def main():
|
||||
|
||||
print("Finished %r" % __file__)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#~ for i in range(200):
|
||||
#~ RANDOM_SEED[0] += 1
|
||||
# ~ for i in range(200):
|
||||
# ~ RANDOM_SEED[0] += 1
|
||||
#~ main()
|
||||
main()
|
||||
|
@@ -31,6 +31,7 @@ import difflib
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def with_tempdir(wrapped):
|
||||
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
||||
|
||||
@@ -56,8 +57,10 @@ def with_tempdir(wrapped):
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
LINE = "+----------------------------------------------------------------"
|
||||
|
||||
|
||||
class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
@@ -71,33 +74,33 @@ class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
ref = open(reference)
|
||||
exp = open(export)
|
||||
diff=difflib.unified_diff(ref.readlines(), exp.readlines(), lineterm='', n=0)
|
||||
diff = difflib.unified_diff(ref.readlines(), exp.readlines(), lineterm='', n=0)
|
||||
ref.close()
|
||||
exp.close()
|
||||
|
||||
diff_count = 0;
|
||||
diff_count = 0
|
||||
for line in diff:
|
||||
error = True
|
||||
for prefix in ('---', '+++', '@@'):
|
||||
# Ignore diff metadata
|
||||
if line.startswith(prefix):
|
||||
error=False
|
||||
error = False
|
||||
break
|
||||
else:
|
||||
# Ignore time stamps
|
||||
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
||||
if line[1:].strip().startswith(ignore):
|
||||
error=False
|
||||
error = False
|
||||
break
|
||||
if error:
|
||||
diff_count +=1
|
||||
diff_count += 1
|
||||
pline = line.strip()
|
||||
if diff_count == 1:
|
||||
print("\n%s" % LINE)
|
||||
print("|Test has errors:")
|
||||
print(LINE)
|
||||
pre = "reference" if pline[0] == "-" else "generated"
|
||||
print ("| %s:%s"% (pre, pline[1:]))
|
||||
print("| %s:%s" % (pre, pline[1:]))
|
||||
|
||||
if diff_count > 0:
|
||||
print(LINE)
|
||||
@@ -107,6 +110,7 @@ class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
return diff_count == 0
|
||||
|
||||
|
||||
class MeshExportTest4(AbstractColladaTest):
|
||||
@with_tempdir
|
||||
def test_export_animation_suzannes_sample_matrix(self, tempdir: pathlib.Path):
|
||||
@@ -114,7 +118,8 @@ class MeshExportTest4(AbstractColladaTest):
|
||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
@@ -142,12 +147,14 @@ class MeshExportTest4(AbstractColladaTest):
|
||||
export_texture_type_selection='mat',
|
||||
open_sim=False,
|
||||
limit_precision=True,
|
||||
keep_bind_info=False)
|
||||
keep_bind_info=False,
|
||||
)
|
||||
|
||||
# Now check the resulting Collada file.
|
||||
if not self.checkdae(reference_dae, outfile):
|
||||
self.fail()
|
||||
|
||||
|
||||
class MeshExportTest3(AbstractColladaTest):
|
||||
@with_tempdir
|
||||
def test_export_animation_suzannes_sample_locrotscale(self, tempdir: pathlib.Path):
|
||||
@@ -155,7 +162,8 @@ class MeshExportTest3(AbstractColladaTest):
|
||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
@@ -183,12 +191,14 @@ class MeshExportTest3(AbstractColladaTest):
|
||||
export_texture_type_selection='mat',
|
||||
open_sim=False,
|
||||
limit_precision=True,
|
||||
keep_bind_info=False)
|
||||
keep_bind_info=False,
|
||||
)
|
||||
|
||||
# Now check the resulting Collada file.
|
||||
if not self.checkdae(reference_dae, outfile):
|
||||
self.fail()
|
||||
|
||||
|
||||
class MeshExportTest2(AbstractColladaTest):
|
||||
@with_tempdir
|
||||
def test_export_animation_suzannes_keyframe_matrix(self, tempdir: pathlib.Path):
|
||||
@@ -196,7 +206,8 @@ class MeshExportTest2(AbstractColladaTest):
|
||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
@@ -224,12 +235,14 @@ class MeshExportTest2(AbstractColladaTest):
|
||||
export_texture_type_selection='mat',
|
||||
open_sim=False,
|
||||
limit_precision=True,
|
||||
keep_bind_info=False)
|
||||
keep_bind_info=False,
|
||||
)
|
||||
|
||||
# Now check the resulting Collada file.
|
||||
if not self.checkdae(reference_dae, outfile):
|
||||
self.fail()
|
||||
|
||||
|
||||
class MeshExportTest1(AbstractColladaTest):
|
||||
@with_tempdir
|
||||
def test_export_animation_suzannes_keyframe_locrotscale(self, tempdir: pathlib.Path):
|
||||
@@ -237,7 +250,8 @@ class MeshExportTest1(AbstractColladaTest):
|
||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type='DEFAULT',
|
||||
@@ -265,7 +279,8 @@ class MeshExportTest1(AbstractColladaTest):
|
||||
export_texture_type_selection='mat',
|
||||
open_sim=False,
|
||||
limit_precision=True,
|
||||
keep_bind_info=False)
|
||||
keep_bind_info=False,
|
||||
)
|
||||
|
||||
# Now check the resulting Collada file.
|
||||
if not self.checkdae(reference_dae, outfile):
|
||||
@@ -277,4 +292,4 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--testdir', required=True)
|
||||
args, remaining = parser.parse_known_args()
|
||||
unittest.main(argv=sys.argv[0:1]+remaining)
|
||||
unittest.main(argv=sys.argv[0:1] + remaining)
|
||||
|
@@ -31,6 +31,7 @@ import difflib
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def with_tempdir(wrapped):
|
||||
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
||||
|
||||
@@ -56,8 +57,10 @@ def with_tempdir(wrapped):
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
LINE = "+----------------------------------------------------------------"
|
||||
|
||||
|
||||
class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
@@ -71,33 +74,33 @@ class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
ref = open(reference)
|
||||
exp = open(export)
|
||||
diff=difflib.unified_diff(ref.readlines(), exp.readlines(), lineterm='', n=0)
|
||||
diff = difflib.unified_diff(ref.readlines(), exp.readlines(), lineterm='', n=0)
|
||||
ref.close()
|
||||
exp.close()
|
||||
|
||||
diff_count = 0;
|
||||
diff_count = 0
|
||||
for line in diff:
|
||||
error = True
|
||||
for prefix in ('---', '+++', '@@'):
|
||||
# Ignore diff metadata
|
||||
if line.startswith(prefix):
|
||||
error=False
|
||||
error = False
|
||||
break
|
||||
else:
|
||||
# Ignore time stamps
|
||||
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
||||
if line[1:].strip().startswith(ignore):
|
||||
error=False
|
||||
error = False
|
||||
break
|
||||
if error:
|
||||
diff_count +=1
|
||||
diff_count += 1
|
||||
pline = line.strip()
|
||||
if diff_count == 1:
|
||||
print("\n%s" % LINE)
|
||||
print("|Test has errors:")
|
||||
print(LINE)
|
||||
pre = "reference" if pline[0] == "-" else "generated"
|
||||
print ("| %s:%s"% (pre, pline[1:]))
|
||||
print("| %s:%s" % (pre, pline[1:]))
|
||||
|
||||
if diff_count > 0:
|
||||
print(LINE)
|
||||
@@ -107,6 +110,7 @@ class AbstractColladaTest(unittest.TestCase):
|
||||
|
||||
return diff_count == 0
|
||||
|
||||
|
||||
class MeshExportTest(AbstractColladaTest):
|
||||
@with_tempdir
|
||||
def test_export_single_mesh(self, tempdir: pathlib.Path):
|
||||
@@ -114,7 +118,8 @@ class MeshExportTest(AbstractColladaTest):
|
||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||
outfile = tempdir / Path("%s_out.dae" % test)
|
||||
|
||||
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
|
||||
bpy.ops.wm.collada_export(
|
||||
filepath="%s" % str(outfile),
|
||||
check_existing=True,
|
||||
filemode=8,
|
||||
display_type="DEFAULT",
|
||||
@@ -140,15 +145,17 @@ class MeshExportTest(AbstractColladaTest):
|
||||
export_texture_type_selection="mat",
|
||||
open_sim=False,
|
||||
limit_precision=False,
|
||||
keep_bind_info=False)
|
||||
keep_bind_info=False,
|
||||
)
|
||||
|
||||
# Now check the resulting Collada file.
|
||||
if not self.checkdae(reference_dae, outfile):
|
||||
self.fail()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--testdir', required=True)
|
||||
args, remaining = parser.parse_known_args()
|
||||
unittest.main(argv=sys.argv[0:1]+remaining)
|
||||
unittest.main(argv=sys.argv[0:1] + remaining)
|
||||
|
@@ -23,6 +23,7 @@ class COLORS_DUMMY:
|
||||
GREEN = ''
|
||||
ENDC = ''
|
||||
|
||||
|
||||
COLORS = COLORS_DUMMY
|
||||
|
||||
|
||||
@@ -55,10 +56,12 @@ def blend_list(dirpath):
|
||||
filepath = os.path.join(dirpath, filename)
|
||||
yield filepath
|
||||
|
||||
|
||||
def test_get_name(filepath):
|
||||
filename = os.path.basename(filepath)
|
||||
return os.path.splitext(filename)[0]
|
||||
|
||||
|
||||
def test_get_images(output_dir, filepath, reference_dir):
|
||||
testname = test_get_name(filepath)
|
||||
dirpath = os.path.dirname(filepath)
|
||||
@@ -158,7 +161,7 @@ class Report:
|
||||
filepath = os.path.join(outdir, "compare.data")
|
||||
pathlib.Path(filepath).write_text(self.compare_tests)
|
||||
|
||||
def _write_html(self, comparison = False):
|
||||
def _write_html(self, comparison=False):
|
||||
# Gather intermediate data for all tests.
|
||||
if comparison:
|
||||
failed_data = []
|
||||
@@ -307,7 +310,6 @@ class Report:
|
||||
|
||||
self.compare_tests += test_html
|
||||
|
||||
|
||||
def _diff_output(self, filepath, tmp_filepath):
|
||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath, self.reference_dir)
|
||||
|
||||
@@ -367,7 +369,6 @@ class Report:
|
||||
|
||||
return not failed
|
||||
|
||||
|
||||
def _run_test(self, filepath, render_cb):
|
||||
testname = test_get_name(filepath)
|
||||
print_message(testname, 'SUCCESS', 'RUN')
|
||||
@@ -404,7 +405,6 @@ class Report:
|
||||
'FAILURE', 'FAILED')
|
||||
return error
|
||||
|
||||
|
||||
def _run_all_tests(self, dirname, dirpath, render_cb):
|
||||
passed_tests = []
|
||||
failed_tests = []
|
||||
|
@@ -62,7 +62,6 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
|
||||
blender: pathlib.Path = None
|
||||
testdir: pathlib.Path = None
|
||||
|
||||
|
||||
def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str:
|
||||
"""Runs Blender by opening a blendfile and executing a script.
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def screenshot():
|
||||
import bpy
|
||||
|
||||
@@ -19,6 +20,7 @@ def screenshot():
|
||||
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
|
||||
# When run from inside Blender, take screenshot and exit.
|
||||
try:
|
||||
import bpy
|
||||
@@ -93,5 +95,6 @@ def main():
|
||||
|
||||
sys.exit(not ok)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -204,6 +204,5 @@ def main():
|
||||
print("Skipping pylint checks (command not found)")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -3,7 +3,7 @@
|
||||
import unittest
|
||||
import random
|
||||
|
||||
test= bpy.data.test
|
||||
test = bpy.data.test
|
||||
|
||||
# farr - 1-dimensional array of float
|
||||
# fdarr - dynamic 1-dimensional array of float
|
||||
@@ -12,6 +12,7 @@ test= bpy.data.test
|
||||
|
||||
# same as above for other types except that the first letter is "i" for int and "b" for bool
|
||||
|
||||
|
||||
class TestArray(unittest.TestCase):
|
||||
# test that assignment works by: assign -> test value
|
||||
# - rvalue = list of float
|
||||
@@ -20,14 +21,14 @@ class TestArray(unittest.TestCase):
|
||||
# bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr
|
||||
|
||||
def setUp(self):
|
||||
test.farr= (1.0, 2.0, 3.0)
|
||||
test.iarr= (7, 8, 9)
|
||||
test.barr= (False, True, False)
|
||||
test.farr = (1.0, 2.0, 3.0)
|
||||
test.iarr = (7, 8, 9)
|
||||
test.barr = (False, True, False)
|
||||
|
||||
# test access
|
||||
# test slice access, negative indices
|
||||
def test_access(self):
|
||||
rvals= ([1.0, 2.0, 3.0], [7, 8, 9], [False, True, False])
|
||||
rvals = ([1.0, 2.0, 3.0], [7, 8, 9], [False, True, False])
|
||||
for arr, rval in zip((test.farr, test.iarr, test.barr), rvals):
|
||||
self.assertEqual(prop_to_list(arr), rval)
|
||||
self.assertEqual(arr[0:3], rval)
|
||||
@@ -39,12 +40,12 @@ class TestArray(unittest.TestCase):
|
||||
# fail when index out of bounds
|
||||
def test_access_fail(self):
|
||||
for arr in (test.farr, test.iarr, test.barr):
|
||||
self.assertRaises(IndexError, lambda : arr[4])
|
||||
self.assertRaises(IndexError, lambda: arr[4])
|
||||
|
||||
# test assignment of a whole array
|
||||
def test_assign_array(self):
|
||||
# should accept int as float
|
||||
test.farr= (1, 2, 3)
|
||||
test.farr = (1, 2, 3)
|
||||
|
||||
# fail when: unexpected no. of items, invalid item type
|
||||
def test_assign_array_fail(self):
|
||||
@@ -55,20 +56,20 @@ class TestArray(unittest.TestCase):
|
||||
self.assertRaises(ValueError, assign_empty_list, arr)
|
||||
|
||||
def assign_invalid_float():
|
||||
test.farr= (1.0, 2.0, "3.0")
|
||||
test.farr = (1.0, 2.0, "3.0")
|
||||
|
||||
def assign_invalid_int():
|
||||
test.iarr= ("1", 2, 3)
|
||||
test.iarr = ("1", 2, 3)
|
||||
|
||||
def assign_invalid_bool():
|
||||
test.barr= (True, 0.123, False)
|
||||
test.barr = (True, 0.123, False)
|
||||
|
||||
for func in [assign_invalid_float, assign_invalid_int, assign_invalid_bool]:
|
||||
self.assertRaises(TypeError, func)
|
||||
|
||||
# shouldn't accept float as int
|
||||
def assign_float_as_int():
|
||||
test.iarr= (1, 2, 3.0)
|
||||
test.iarr = (1, 2, 3.0)
|
||||
self.assertRaises(TypeError, assign_float_as_int)
|
||||
|
||||
# non-dynamic arrays cannot change size
|
||||
@@ -81,14 +82,14 @@ class TestArray(unittest.TestCase):
|
||||
def test_assign_item(self):
|
||||
for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)):
|
||||
for i in range(len(arr)):
|
||||
val= rand_func()
|
||||
val = rand_func()
|
||||
arr[i] = val
|
||||
|
||||
self.assertEqual(arr[i], val)
|
||||
|
||||
# float prop should accept also int
|
||||
for i in range(len(test.farr)):
|
||||
val= rand_int()
|
||||
val = rand_int()
|
||||
test.farr[i] = val
|
||||
self.assertEqual(test.farr[i], float(val))
|
||||
|
||||
@@ -112,7 +113,7 @@ class TestArray(unittest.TestCase):
|
||||
# test various lengths here
|
||||
for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)):
|
||||
for length in range(1, 64):
|
||||
rval= make_random_array(length, rand_func)
|
||||
rval = make_random_array(length, rand_func)
|
||||
setattr(test, arr, rval)
|
||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||
|
||||
@@ -136,7 +137,7 @@ class TestMArray(unittest.TestCase):
|
||||
def test_assign_array(self):
|
||||
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
||||
# assignment of [3][4][5]
|
||||
rval= make_random_3d_array((3, 4, 5), func)
|
||||
rval = make_random_3d_array((3, 4, 5), func)
|
||||
setattr(test, arr, rval)
|
||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||
|
||||
@@ -144,7 +145,7 @@ class TestMArray(unittest.TestCase):
|
||||
|
||||
def test_assign_array_fail(self):
|
||||
def assign_empty_array():
|
||||
test.fmarr= ()
|
||||
test.fmarr = ()
|
||||
self.assertRaises(ValueError, assign_empty_array)
|
||||
|
||||
def assign_invalid_size(arr, rval):
|
||||
@@ -152,19 +153,19 @@ class TestMArray(unittest.TestCase):
|
||||
|
||||
# assignment of 3,4,4 or 3,3,5 should raise ex
|
||||
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
||||
rval= make_random_3d_array((3, 4, 4), func)
|
||||
rval = make_random_3d_array((3, 4, 4), func)
|
||||
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
|
||||
|
||||
rval= make_random_3d_array((3, 3, 5), func)
|
||||
rval = make_random_3d_array((3, 3, 5), func)
|
||||
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
|
||||
|
||||
rval= make_random_3d_array((3, 3, 3), func)
|
||||
rval = make_random_3d_array((3, 3, 3), func)
|
||||
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
|
||||
|
||||
def test_assign_item(self):
|
||||
# arr[i] = x
|
||||
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
|
||||
rval= make_random_2d_array((4, 5), func)
|
||||
rval = make_random_2d_array((4, 5), func)
|
||||
|
||||
for i in range(3):
|
||||
getattr(test, arr)[i] = rval
|
||||
@@ -173,23 +174,22 @@ class TestMArray(unittest.TestCase):
|
||||
# arr[i][j] = x
|
||||
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
|
||||
|
||||
arr= getattr(test, arr)
|
||||
rval= make_random_array(5, func)
|
||||
arr = getattr(test, arr)
|
||||
rval = make_random_array(5, func)
|
||||
|
||||
for i in range(3):
|
||||
for j in range(4):
|
||||
arr[i][j] = rval
|
||||
self.assertEqual(prop_to_list(arr[i][j]), rval)
|
||||
|
||||
|
||||
def test_assign_item_fail(self):
|
||||
def assign_wrong_size(arr, i, rval):
|
||||
getattr(test, arr)[i] = rval
|
||||
|
||||
# assign wrong size at level 2
|
||||
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
||||
rval1= make_random_2d_array((3, 5), func)
|
||||
rval2= make_random_2d_array((4, 3), func)
|
||||
rval1 = make_random_2d_array((3, 5), func)
|
||||
rval2 = make_random_2d_array((4, 3), func)
|
||||
|
||||
for i in range(3):
|
||||
self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1)
|
||||
@@ -198,22 +198,22 @@ class TestMArray(unittest.TestCase):
|
||||
def test_dynamic_assign_array(self):
|
||||
for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
|
||||
# assignment of [3][4][5]
|
||||
rval= make_random_3d_array((3, 4, 5), func)
|
||||
rval = make_random_3d_array((3, 4, 5), func)
|
||||
setattr(test, arr, rval)
|
||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||
|
||||
# [2][4][5]
|
||||
rval= make_random_3d_array((2, 4, 5), func)
|
||||
rval = make_random_3d_array((2, 4, 5), func)
|
||||
setattr(test, arr, rval)
|
||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||
|
||||
# [1][4][5]
|
||||
rval= make_random_3d_array((1, 4, 5), func)
|
||||
rval = make_random_3d_array((1, 4, 5), func)
|
||||
setattr(test, arr, rval)
|
||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||
|
||||
|
||||
# test access
|
||||
|
||||
def test_access(self):
|
||||
pass
|
||||
|
||||
@@ -221,26 +221,32 @@ class TestMArray(unittest.TestCase):
|
||||
def test_access_fail(self):
|
||||
pass
|
||||
|
||||
|
||||
random.seed()
|
||||
|
||||
|
||||
def rand_int():
|
||||
return random.randint(-1000, 1000)
|
||||
|
||||
|
||||
def rand_float():
|
||||
return float(rand_int())
|
||||
|
||||
|
||||
def rand_bool():
|
||||
return bool(random.randint(0, 1))
|
||||
|
||||
|
||||
def make_random_array(len, rand_func):
|
||||
arr= []
|
||||
arr = []
|
||||
for i in range(len):
|
||||
arr.append(rand_func())
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
def make_random_2d_array(dimsize, rand_func):
|
||||
marr= []
|
||||
marr = []
|
||||
for i in range(dimsize[0]):
|
||||
marr.append([])
|
||||
|
||||
@@ -249,8 +255,9 @@ def make_random_2d_array(dimsize, rand_func):
|
||||
|
||||
return marr
|
||||
|
||||
|
||||
def make_random_3d_array(dimsize, rand_func):
|
||||
marr= []
|
||||
marr = []
|
||||
for i in range(dimsize[0]):
|
||||
marr.append([])
|
||||
|
||||
@@ -262,8 +269,9 @@ def make_random_3d_array(dimsize, rand_func):
|
||||
|
||||
return marr
|
||||
|
||||
|
||||
def prop_to_list(prop):
|
||||
ret= []
|
||||
ret = []
|
||||
|
||||
for x in prop:
|
||||
if type(x) not in {bool, int, float}:
|
||||
@@ -273,8 +281,10 @@ def prop_to_list(prop):
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
||||
|
Reference in New Issue
Block a user