Cleanup: pep8
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
@@ -22,21 +22,21 @@
|
|||||||
#
|
#
|
||||||
# Name:
|
# Name:
|
||||||
# dna.py
|
# dna.py
|
||||||
#
|
#
|
||||||
# Description:
|
# Description:
|
||||||
# Creates a browsable DNA output to HTML.
|
# Creates a browsable DNA output to HTML.
|
||||||
#
|
#
|
||||||
# Author:
|
# Author:
|
||||||
# Jeroen Bakker
|
# Jeroen Bakker
|
||||||
#
|
#
|
||||||
# Version:
|
# Version:
|
||||||
# v0.1 (12-05-2009) - migration of original source code to python.
|
# v0.1 (12-05-2009) - migration of original source code to python.
|
||||||
# Added code to support blender 2.5 branch
|
# Added code to support blender 2.5 branch
|
||||||
# v0.2 (25-05-2009) - integrated with BlendFileReader.py
|
# v0.2 (25-05-2009) - integrated with BlendFileReader.py
|
||||||
#
|
#
|
||||||
# Input:
|
# Input:
|
||||||
# blender build executable
|
# blender build executable
|
||||||
#
|
#
|
||||||
# Output:
|
# Output:
|
||||||
# dna.html
|
# dna.html
|
||||||
# dna.css (will only be created when not existing)
|
# dna.css (will only be created when not existing)
|
||||||
@@ -76,12 +76,12 @@ class DNACatalogHTML:
|
|||||||
DNACatalog is a catalog of all information in the DNA1 file-block
|
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.Catalog = catalog
|
||||||
self.bpy = bpy_module
|
self.bpy = bpy_module
|
||||||
|
|
||||||
def WriteToHTML(self, handle):
|
def WriteToHTML(self, handle):
|
||||||
|
|
||||||
dna_html_template = """
|
dna_html_template = """
|
||||||
<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>
|
<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>
|
||||||
<html>
|
<html>
|
||||||
@@ -105,10 +105,10 @@ class DNACatalogHTML:
|
|||||||
${structs_content}
|
${structs_content}
|
||||||
</body>
|
</body>
|
||||||
</html>"""
|
</html>"""
|
||||||
|
|
||||||
header = self.Catalog.Header
|
header = self.Catalog.Header
|
||||||
bpy = self.bpy
|
bpy = self.bpy
|
||||||
|
|
||||||
# ${version} and ${revision}
|
# ${version} and ${revision}
|
||||||
if bpy:
|
if bpy:
|
||||||
version = '.'.join(map(str, bpy.app.version))
|
version = '.'.join(map(str, bpy.app.version))
|
||||||
@@ -116,7 +116,7 @@ class DNACatalogHTML:
|
|||||||
else:
|
else:
|
||||||
version = str(header.Version)
|
version = str(header.Version)
|
||||||
revision = 'Unknown'
|
revision = 'Unknown'
|
||||||
|
|
||||||
# ${bitness}
|
# ${bitness}
|
||||||
if header.PointerSize == 8:
|
if header.PointerSize == 8:
|
||||||
bitness = '64 bit'
|
bitness = '64 bit'
|
||||||
@@ -125,10 +125,10 @@ class DNACatalogHTML:
|
|||||||
|
|
||||||
# ${endianness}
|
# ${endianness}
|
||||||
if header.LittleEndianness:
|
if header.LittleEndianness:
|
||||||
endianess= 'Little endianness'
|
endianess = 'Little endianness'
|
||||||
else:
|
else:
|
||||||
endianess= 'Big endianness'
|
endianess = 'Big endianness'
|
||||||
|
|
||||||
# ${structs_list}
|
# ${structs_list}
|
||||||
log.debug("Creating structs index")
|
log.debug("Creating structs index")
|
||||||
structs_list = ''
|
structs_list = ''
|
||||||
@@ -136,7 +136,7 @@ class DNACatalogHTML:
|
|||||||
structureIndex = 0
|
structureIndex = 0
|
||||||
for structure in self.Catalog.Structs:
|
for structure in self.Catalog.Structs:
|
||||||
structs_list += list_item.format(structureIndex, structure.Type.Name)
|
structs_list += list_item.format(structureIndex, structure.Type.Name)
|
||||||
structureIndex+=1
|
structureIndex += 1
|
||||||
|
|
||||||
# ${structs_content}
|
# ${structs_content}
|
||||||
log.debug("Creating structs content")
|
log.debug("Creating structs content")
|
||||||
@@ -144,20 +144,20 @@ class DNACatalogHTML:
|
|||||||
for structure in self.Catalog.Structs:
|
for structure in self.Catalog.Structs:
|
||||||
log.debug(structure.Type.Name)
|
log.debug(structure.Type.Name)
|
||||||
structs_content += self.Structure(structure)
|
structs_content += self.Structure(structure)
|
||||||
|
|
||||||
d = dict(
|
d = dict(
|
||||||
version = version,
|
version=version,
|
||||||
revision = revision,
|
revision=revision,
|
||||||
bitness = bitness,
|
bitness=bitness,
|
||||||
endianness = endianess,
|
endianness=endianess,
|
||||||
structs_list = structs_list,
|
structs_list=structs_list,
|
||||||
structs_content = structs_content
|
structs_content=structs_content
|
||||||
)
|
)
|
||||||
|
|
||||||
dna_html = Template(dna_html_template).substitute(d)
|
dna_html = Template(dna_html_template).substitute(d)
|
||||||
dna_html = self.format(dna_html)
|
dna_html = self.format(dna_html)
|
||||||
handle.write(dna_html)
|
handle.write(dna_html)
|
||||||
|
|
||||||
def Structure(self, structure):
|
def Structure(self, structure):
|
||||||
struct_table_template = """
|
struct_table_template = """
|
||||||
<table><a name="${struct_name}"></a>
|
<table><a name="${struct_name}"></a>
|
||||||
@@ -178,23 +178,23 @@ class DNACatalogHTML:
|
|||||||
</table>
|
</table>
|
||||||
<label>Total size: ${size} bytes</label><br/>
|
<label>Total size: ${size} bytes</label><br/>
|
||||||
<label>(<a href="#top">top</a>)</label><br/>"""
|
<label>(<a href="#top">top</a>)</label><br/>"""
|
||||||
|
|
||||||
d = dict(
|
d = dict(
|
||||||
struct_name = structure.Type.Name,
|
struct_name=structure.Type.Name,
|
||||||
fields = self.StructureFields(structure, None, 0),
|
fields=self.StructureFields(structure, None, 0),
|
||||||
size = str(structure.Type.Size)
|
size=str(structure.Type.Size)
|
||||||
)
|
)
|
||||||
|
|
||||||
struct_table = Template(struct_table_template).substitute(d)
|
struct_table = Template(struct_table_template).substitute(d)
|
||||||
return struct_table
|
return struct_table
|
||||||
|
|
||||||
def StructureFields(self, structure, parentReference, offset):
|
def StructureFields(self, structure, parentReference, offset):
|
||||||
fields = ''
|
fields = ''
|
||||||
for field in structure.Fields:
|
for field in structure.Fields:
|
||||||
fields += self.StructureField(field, structure, parentReference, offset)
|
fields += self.StructureField(field, structure, parentReference, offset)
|
||||||
offset += field.Size(self.Catalog.Header)
|
offset += field.Size(self.Catalog.Header)
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def StructureField(self, field, structure, parentReference, offset):
|
def StructureField(self, field, structure, parentReference, offset):
|
||||||
structure_field_template = """
|
structure_field_template = """
|
||||||
<tr>
|
<tr>
|
||||||
@@ -205,7 +205,7 @@ class DNACatalogHTML:
|
|||||||
<td>${offset}</td>
|
<td>${offset}</td>
|
||||||
<td>${size}</td>
|
<td>${size}</td>
|
||||||
</tr>"""
|
</tr>"""
|
||||||
|
|
||||||
if field.Type.Structure is None or field.Name.IsPointer():
|
if field.Type.Structure is None or field.Name.IsPointer():
|
||||||
|
|
||||||
# ${reference}
|
# ${reference}
|
||||||
@@ -216,37 +216,37 @@ class DNACatalogHTML:
|
|||||||
struct = '<a href="#{0}">{0}</a>'.format(structure.Type.Name)
|
struct = '<a href="#{0}">{0}</a>'.format(structure.Type.Name)
|
||||||
else:
|
else:
|
||||||
struct = structure.Type.Name
|
struct = structure.Type.Name
|
||||||
|
|
||||||
# ${type}
|
# ${type}
|
||||||
type = field.Type.Name
|
type = field.Type.Name
|
||||||
|
|
||||||
# ${name}
|
# ${name}
|
||||||
name = field.Name.Name
|
name = field.Name.Name
|
||||||
|
|
||||||
# ${offset}
|
# ${offset}
|
||||||
# offset already set
|
# offset already set
|
||||||
|
|
||||||
# ${size}
|
# ${size}
|
||||||
size = field.Size(self.Catalog.Header)
|
size = field.Size(self.Catalog.Header)
|
||||||
|
|
||||||
d = dict(
|
d = dict(
|
||||||
reference = reference,
|
reference=reference,
|
||||||
struct = struct,
|
struct=struct,
|
||||||
type = type,
|
type=type,
|
||||||
name = name,
|
name=name,
|
||||||
offset = offset,
|
offset=offset,
|
||||||
size = size
|
size=size
|
||||||
)
|
)
|
||||||
|
|
||||||
structure_field = Template(structure_field_template).substitute(d)
|
structure_field = Template(structure_field_template).substitute(d)
|
||||||
|
|
||||||
elif field.Type.Structure is not None:
|
elif field.Type.Structure is not None:
|
||||||
reference = field.Name.AsReference(parentReference)
|
reference = field.Name.AsReference(parentReference)
|
||||||
structure_field = self.StructureFields(field.Type.Structure, reference, offset)
|
structure_field = self.StructureFields(field.Type.Structure, reference, offset)
|
||||||
|
|
||||||
return structure_field
|
return structure_field
|
||||||
|
|
||||||
def indent(self, input, dent, startswith = ''):
|
def indent(self, input, dent, startswith=''):
|
||||||
output = ''
|
output = ''
|
||||||
if dent < 0:
|
if dent < 0:
|
||||||
for line in input.split('\n'):
|
for line in input.split('\n'):
|
||||||
@@ -257,19 +257,19 @@ class DNACatalogHTML:
|
|||||||
output += line.lstrip() + '\n' # remove indentation completely
|
output += line.lstrip() + '\n' # remove indentation completely
|
||||||
elif dent > 0:
|
elif dent > 0:
|
||||||
for line in input.split('\n'):
|
for line in input.split('\n'):
|
||||||
output += ' '* dent + line + '\n'
|
output += ' ' * dent + line + '\n'
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def format(self, input):
|
def format(self, input):
|
||||||
diff = {
|
diff = {
|
||||||
'\n<!DOCTYPE':'<!DOCTYPE',
|
'\n<!DOCTYPE': '<!DOCTYPE',
|
||||||
'\n</ul>' :'</ul>',
|
'\n</ul>': '</ul>',
|
||||||
'<a name' :'\n<a name',
|
'<a name': '\n<a name',
|
||||||
'<tr>\n' :'<tr>',
|
'<tr>\n': '<tr>',
|
||||||
'<tr>' :' <tr>',
|
'<tr>': ' <tr>',
|
||||||
'</th>\n' :'</th>',
|
'</th>\n': '</th>',
|
||||||
'</td>\n' :'</td>',
|
'</td>\n': '</td>',
|
||||||
'<tbody>\n' :'<tbody>'
|
'<tbody>\n': '<tbody>'
|
||||||
}
|
}
|
||||||
output = self.indent(input, 0)
|
output = self.indent(input, 0)
|
||||||
for key, value in diff.items():
|
for key, value in diff.items():
|
||||||
@@ -283,17 +283,17 @@ class DNACatalogHTML:
|
|||||||
'''
|
'''
|
||||||
css = """
|
css = """
|
||||||
@CHARSET "ISO-8859-1";
|
@CHARSET "ISO-8859-1";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: verdana;
|
font-family: verdana;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.title {
|
div.title {
|
||||||
font-size: large;
|
font-size: large;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
page-break-before: always;
|
page-break-before: always;
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ class DNACatalogHTML:
|
|||||||
margin-right: 3%;
|
margin-right: 3%;
|
||||||
padding-left: 40px;
|
padding-left: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1:hover{
|
h1:hover{
|
||||||
background-color: #EBEBEB;
|
background-color: #EBEBEB;
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ class DNACatalogHTML:
|
|||||||
h3 {
|
h3 {
|
||||||
padding-left: 40px;
|
padding-left: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
@@ -321,21 +321,21 @@ class DNACatalogHTML:
|
|||||||
width: 94%;
|
width: 94%;
|
||||||
margin: 20px 3% 10px;
|
margin: 20px 3% 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
caption {
|
caption {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background-color: #000000;
|
background-color: #000000;
|
||||||
color:#ffffff;
|
color:#ffffff;
|
||||||
padding-left:5px;
|
padding-left:5px;
|
||||||
padding-right:5px;
|
padding-right:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
@@ -343,12 +343,12 @@ class DNACatalogHTML:
|
|||||||
padding-left:5px;
|
padding-left:5px;
|
||||||
padding-right:5px;
|
padding-right:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
float:right;
|
float:right;
|
||||||
margin-right: 3%;
|
margin-right: 3%;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.multicolumn {
|
ul.multicolumn {
|
||||||
list-style:none;
|
list-style:none;
|
||||||
float:left;
|
float:left;
|
||||||
@@ -361,18 +361,18 @@ class DNACatalogHTML:
|
|||||||
width:200px;
|
width:200px;
|
||||||
margin-right:0px;
|
margin-right:0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color:#a000a0;
|
color:#a000a0;
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color:#a000a0;
|
color:#a000a0;
|
||||||
text-decoration:underline;
|
text-decoration:underline;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
css = self.indent(css, 0)
|
css = self.indent(css, 0)
|
||||||
|
|
||||||
handle.write(css)
|
handle.write(css)
|
||||||
@@ -389,13 +389,13 @@ def usage():
|
|||||||
print("\tdefault: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py")
|
print("\tdefault: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py")
|
||||||
print("\twith options: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
|
print("\twith options: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
# Main
|
# Main
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
import os, os.path
|
import os, os.path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -408,37 +408,37 @@ def main():
|
|||||||
else:
|
else:
|
||||||
filename = 'dna'
|
filename = 'dna'
|
||||||
dir = os.path.dirname(__file__)
|
dir = os.path.dirname(__file__)
|
||||||
Path_Blend = os.path.join(dir, filename + '.blend') # temporary blend file
|
Path_Blend = os.path.join(dir, filename + '.blend') # temporary blend file
|
||||||
Path_HTML = os.path.join(dir, filename + '.html') # output html file
|
Path_HTML = os.path.join(dir, filename + '.html') # output html file
|
||||||
Path_CSS = os.path.join(dir, 'dna.css') # output css file
|
Path_CSS = os.path.join(dir, 'dna.css') # output css file
|
||||||
|
|
||||||
# create a blend file for dna parsing
|
# create a blend file for dna parsing
|
||||||
if not os.path.exists(Path_Blend):
|
if not os.path.exists(Path_Blend):
|
||||||
log.info("1: write temp blend file with SDNA info")
|
log.info("1: write temp blend file with SDNA info")
|
||||||
log.info(" saving to: " + Path_Blend)
|
log.info(" saving to: " + Path_Blend)
|
||||||
try:
|
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:
|
except:
|
||||||
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
|
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
log.info("1: found blend file with SDNA info")
|
log.info("1: found blend file with SDNA info")
|
||||||
log.info(" " + Path_Blend)
|
log.info(" " + Path_Blend)
|
||||||
|
|
||||||
# read blend header from blend file
|
# read blend header from blend file
|
||||||
log.info("2: read file:")
|
log.info("2: read file:")
|
||||||
|
|
||||||
if not dir in sys.path:
|
if not dir in sys.path:
|
||||||
sys.path.append(dir)
|
sys.path.append(dir)
|
||||||
import BlendFileReader
|
import BlendFileReader
|
||||||
|
|
||||||
handle = BlendFileReader.openBlendFile(Path_Blend)
|
handle = BlendFileReader.openBlendFile(Path_Blend)
|
||||||
blendfile = BlendFileReader.BlendFile(handle)
|
blendfile = BlendFileReader.BlendFile(handle)
|
||||||
catalog = DNACatalogHTML(blendfile.Catalog, bpy)
|
catalog = DNACatalogHTML(blendfile.Catalog, bpy)
|
||||||
|
|
||||||
# close temp file
|
# close temp file
|
||||||
handle.close()
|
handle.close()
|
||||||
|
|
||||||
# deleting or not?
|
# deleting or not?
|
||||||
if '--dna-keep-blend' in sys.argv:
|
if '--dna-keep-blend' in sys.argv:
|
||||||
# keep the blend, useful for studying hexdumps
|
# keep the blend, useful for studying hexdumps
|
||||||
@@ -449,7 +449,7 @@ def main():
|
|||||||
log.info("5: close and delete temp blend:")
|
log.info("5: close and delete temp blend:")
|
||||||
log.info(" {0}".format(Path_Blend))
|
log.info(" {0}".format(Path_Blend))
|
||||||
os.remove(Path_Blend)
|
os.remove(Path_Blend)
|
||||||
|
|
||||||
# export dna to xhtml
|
# export dna to xhtml
|
||||||
log.info("6: export sdna to xhtml file: %r" % Path_HTML)
|
log.info("6: export sdna to xhtml file: %r" % Path_HTML)
|
||||||
handleHTML = open(Path_HTML, "w")
|
handleHTML = open(Path_HTML, "w")
|
||||||
@@ -466,12 +466,12 @@ def main():
|
|||||||
if not bpy.app.background:
|
if not bpy.app.background:
|
||||||
log.info("7: quit blender")
|
log.info("7: quit blender")
|
||||||
bpy.ops.wm.exit_blender()
|
bpy.ops.wm.exit_blender()
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
log.warning(" skipping, not running in Blender")
|
log.warning(" skipping, not running in Blender")
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
@@ -34,6 +34,7 @@ log = logging.getLogger("BlendFileReader")
|
|||||||
# module global routines
|
# module global routines
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
|
||||||
def ReadString(handle, length):
|
def ReadString(handle, length):
|
||||||
'''
|
'''
|
||||||
ReadString reads a String of given length or a zero terminating String
|
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
|
# length == 0 means we want a zero terminating string
|
||||||
result = ""
|
result = ""
|
||||||
s = ReadString(handle, 1)
|
s = ReadString(handle, 1)
|
||||||
while s!="\0":
|
while s != "\0":
|
||||||
result += s
|
result += s
|
||||||
s = ReadString(handle, 1)
|
s = ReadString(handle, 1)
|
||||||
return result
|
return result
|
||||||
@@ -57,7 +58,7 @@ def Read(type, handle, fileheader):
|
|||||||
'''
|
'''
|
||||||
def unpacked_bytes(type_char, size):
|
def unpacked_bytes(type_char, size):
|
||||||
return struct.unpack(fileheader.StructPre + type_char, handle.read(size))[0]
|
return struct.unpack(fileheader.StructPre + type_char, handle.read(size))[0]
|
||||||
|
|
||||||
if type == 'ushort':
|
if type == 'ushort':
|
||||||
return unpacked_bytes("H", 2) # unsigned short
|
return unpacked_bytes("H", 2) # unsigned short
|
||||||
elif type == 'short':
|
elif type == 'short':
|
||||||
@@ -94,10 +95,10 @@ def openBlendFile(filename):
|
|||||||
log.debug("decompressing started")
|
log.debug("decompressing started")
|
||||||
fs = gzip.open(filename, "rb")
|
fs = gzip.open(filename, "rb")
|
||||||
handle = tempfile.TemporaryFile()
|
handle = tempfile.TemporaryFile()
|
||||||
data = fs.read(1024*1024)
|
data = fs.read(1024 * 1024)
|
||||||
while data:
|
while data:
|
||||||
handle.write(data)
|
handle.write(data)
|
||||||
data = fs.read(1024*1024)
|
data = fs.read(1024 * 1024)
|
||||||
log.debug("decompressing finished")
|
log.debug("decompressing finished")
|
||||||
fs.close()
|
fs.close()
|
||||||
log.debug("resetting decompressed file")
|
log.debug("resetting decompressed file")
|
||||||
@@ -112,7 +113,7 @@ def Align(handle):
|
|||||||
offset = handle.tell()
|
offset = handle.tell()
|
||||||
trim = offset % 4
|
trim = offset % 4
|
||||||
if trim != 0:
|
if trim != 0:
|
||||||
handle.seek(4-trim, os.SEEK_CUR)
|
handle.seek(4 - trim, os.SEEK_CUR)
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
@@ -121,14 +122,14 @@ def Align(handle):
|
|||||||
|
|
||||||
class BlendFile:
|
class BlendFile:
|
||||||
'''
|
'''
|
||||||
Reads a blendfile and store the header, all the fileblocks, and catalogue
|
Reads a blendfile and store the header, all the fileblocks, and catalogue
|
||||||
structs foound in the DNA fileblock
|
structs foound in the DNA fileblock
|
||||||
|
|
||||||
- BlendFile.Header (BlendFileHeader instance)
|
- BlendFile.Header (BlendFileHeader instance)
|
||||||
- BlendFile.Blocks (list of BlendFileBlock instances)
|
- BlendFile.Blocks (list of BlendFileBlock instances)
|
||||||
- BlendFile.Catalog (DNACatalog instance)
|
- BlendFile.Catalog (DNACatalog instance)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, handle):
|
def __init__(self, handle):
|
||||||
log.debug("initializing reading blend-file")
|
log.debug("initializing reading blend-file")
|
||||||
self.Header = BlendFileHeader(handle)
|
self.Header = BlendFileHeader(handle)
|
||||||
@@ -141,13 +142,13 @@ class BlendFile:
|
|||||||
found_dna_block = True
|
found_dna_block = True
|
||||||
else:
|
else:
|
||||||
fileblock.Header.skip(handle)
|
fileblock.Header.skip(handle)
|
||||||
|
|
||||||
self.Blocks.append(fileblock)
|
self.Blocks.append(fileblock)
|
||||||
fileblock = BlendFileBlock(handle, self)
|
fileblock = BlendFileBlock(handle, self)
|
||||||
|
|
||||||
# appending last fileblock, "ENDB"
|
# appending last fileblock, "ENDB"
|
||||||
self.Blocks.append(fileblock)
|
self.Blocks.append(fileblock)
|
||||||
|
|
||||||
# seems unused?
|
# seems unused?
|
||||||
"""
|
"""
|
||||||
def FindBlendFileBlocksWithCode(self, code):
|
def FindBlendFileBlocksWithCode(self, code):
|
||||||
@@ -164,27 +165,27 @@ class BlendFileHeader:
|
|||||||
BlendFileHeader allocates the first 12 bytes of a blend file.
|
BlendFileHeader allocates the first 12 bytes of a blend file.
|
||||||
It contains information about the hardware architecture.
|
It contains information about the hardware architecture.
|
||||||
Header example: BLENDER_v254
|
Header example: BLENDER_v254
|
||||||
|
|
||||||
BlendFileHeader.Magic (str)
|
BlendFileHeader.Magic (str)
|
||||||
BlendFileHeader.PointerSize (int)
|
BlendFileHeader.PointerSize (int)
|
||||||
BlendFileHeader.LittleEndianness (bool)
|
BlendFileHeader.LittleEndianness (bool)
|
||||||
BlendFileHeader.StructPre (str) see http://docs.python.org/py3k/library/struct.html#byte-order-size-and-alignment
|
BlendFileHeader.StructPre (str) see http://docs.python.org/py3k/library/struct.html#byte-order-size-and-alignment
|
||||||
BlendFileHeader.Version (int)
|
BlendFileHeader.Version (int)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, handle):
|
def __init__(self, handle):
|
||||||
log.debug("reading blend-file-header")
|
log.debug("reading blend-file-header")
|
||||||
|
|
||||||
self.Magic = ReadString(handle, 7)
|
self.Magic = ReadString(handle, 7)
|
||||||
log.debug(self.Magic)
|
log.debug(self.Magic)
|
||||||
|
|
||||||
pointersize = ReadString(handle, 1)
|
pointersize = ReadString(handle, 1)
|
||||||
log.debug(pointersize)
|
log.debug(pointersize)
|
||||||
if pointersize == "-":
|
if pointersize == "-":
|
||||||
self.PointerSize = 8
|
self.PointerSize = 8
|
||||||
if pointersize == "_":
|
if pointersize == "_":
|
||||||
self.PointerSize = 4
|
self.PointerSize = 4
|
||||||
|
|
||||||
endianness = ReadString(handle, 1)
|
endianness = ReadString(handle, 1)
|
||||||
log.debug(endianness)
|
log.debug(endianness)
|
||||||
if endianness == "v":
|
if endianness == "v":
|
||||||
@@ -193,11 +194,11 @@ class BlendFileHeader:
|
|||||||
if endianness == "V":
|
if endianness == "V":
|
||||||
self.LittleEndianness = False
|
self.LittleEndianness = False
|
||||||
self.StructPre = ">"
|
self.StructPre = ">"
|
||||||
|
|
||||||
version = ReadString(handle, 3)
|
version = ReadString(handle, 3)
|
||||||
log.debug(version)
|
log.debug(version)
|
||||||
self.Version = int(version)
|
self.Version = int(version)
|
||||||
|
|
||||||
log.debug("{0} {1} {2} {3}".format(self.Magic, self.PointerSize, self.LittleEndianness, version))
|
log.debug("{0} {1} {2} {3}".format(self.Magic, self.PointerSize, self.LittleEndianness, version))
|
||||||
|
|
||||||
|
|
||||||
@@ -206,11 +207,11 @@ class BlendFileBlock:
|
|||||||
BlendFileBlock.File (BlendFile)
|
BlendFileBlock.File (BlendFile)
|
||||||
BlendFileBlock.Header (FileBlockHeader)
|
BlendFileBlock.Header (FileBlockHeader)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, handle, blendfile):
|
def __init__(self, handle, blendfile):
|
||||||
self.File = blendfile
|
self.File = blendfile
|
||||||
self.Header = FileBlockHeader(handle, blendfile.Header)
|
self.Header = FileBlockHeader(handle, blendfile.Header)
|
||||||
|
|
||||||
def Get(self, handle, path):
|
def Get(self, handle, path):
|
||||||
log.debug("find dna structure")
|
log.debug("find dna structure")
|
||||||
dnaIndex = self.Header.SDNAIndex
|
dnaIndex = self.Header.SDNAIndex
|
||||||
@@ -232,7 +233,7 @@ class FileBlockHeader:
|
|||||||
Count (int)
|
Count (int)
|
||||||
FileOffset (= file pointer of datablock)
|
FileOffset (= file pointer of datablock)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, handle, fileheader):
|
def __init__(self, handle, fileheader):
|
||||||
self.Code = ReadString(handle, 4).strip()
|
self.Code = ReadString(handle, 4).strip()
|
||||||
if self.Code != "ENDB":
|
if self.Code != "ENDB":
|
||||||
@@ -257,28 +258,28 @@ class FileBlockHeader:
|
|||||||
class DNACatalog:
|
class DNACatalog:
|
||||||
'''
|
'''
|
||||||
DNACatalog is a catalog of all information in the DNA1 file-block
|
DNACatalog is a catalog of all information in the DNA1 file-block
|
||||||
|
|
||||||
Header = None
|
Header = None
|
||||||
Names = None
|
Names = None
|
||||||
Types = None
|
Types = None
|
||||||
Structs = None
|
Structs = None
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, fileheader, handle):
|
def __init__(self, fileheader, handle):
|
||||||
log.debug("building DNA catalog")
|
log.debug("building DNA catalog")
|
||||||
self.Names=[]
|
self.Names = []
|
||||||
self.Types=[]
|
self.Types = []
|
||||||
self.Structs=[]
|
self.Structs = []
|
||||||
self.Header = fileheader
|
self.Header = fileheader
|
||||||
|
|
||||||
SDNA = ReadString(handle, 4)
|
SDNA = ReadString(handle, 4)
|
||||||
|
|
||||||
# names
|
# names
|
||||||
NAME = ReadString(handle, 4)
|
NAME = ReadString(handle, 4)
|
||||||
numberOfNames = Read('uint', handle, fileheader)
|
numberOfNames = Read('uint', handle, fileheader)
|
||||||
log.debug("building #{0} names".format(numberOfNames))
|
log.debug("building #{0} names".format(numberOfNames))
|
||||||
for i in range(numberOfNames):
|
for i in range(numberOfNames):
|
||||||
name = ReadString(handle,0)
|
name = ReadString(handle, 0)
|
||||||
self.Names.append(DNAName(name))
|
self.Names.append(DNAName(name))
|
||||||
Align(handle)
|
Align(handle)
|
||||||
|
|
||||||
@@ -287,7 +288,7 @@ class DNACatalog:
|
|||||||
numberOfTypes = Read('uint', handle, fileheader)
|
numberOfTypes = Read('uint', handle, fileheader)
|
||||||
log.debug("building #{0} types".format(numberOfTypes))
|
log.debug("building #{0} types".format(numberOfTypes))
|
||||||
for i in range(numberOfTypes):
|
for i in range(numberOfTypes):
|
||||||
type = ReadString(handle,0)
|
type = ReadString(handle, 0)
|
||||||
self.Types.append(DNAType(type))
|
self.Types.append(DNAType(type))
|
||||||
Align(handle)
|
Align(handle)
|
||||||
|
|
||||||
@@ -321,24 +322,24 @@ class DNACatalog:
|
|||||||
class DNAName:
|
class DNAName:
|
||||||
'''
|
'''
|
||||||
DNAName is a C-type name stored in the DNA.
|
DNAName is a C-type name stored in the DNA.
|
||||||
|
|
||||||
Name = str
|
Name = str
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.Name = name
|
self.Name = name
|
||||||
|
|
||||||
def AsReference(self, parent):
|
def AsReference(self, parent):
|
||||||
if parent is None:
|
if parent is None:
|
||||||
result = ""
|
result = ""
|
||||||
else:
|
else:
|
||||||
result = parent+"."
|
result = parent + "."
|
||||||
|
|
||||||
result = result + self.ShortName()
|
result = result + self.ShortName()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def ShortName(self):
|
def ShortName(self):
|
||||||
result = self.Name;
|
result = self.Name
|
||||||
result = result.replace("*", "")
|
result = result.replace("*", "")
|
||||||
result = result.replace("(", "")
|
result = result.replace("(", "")
|
||||||
result = result.replace(")", "")
|
result = result.replace(")", "")
|
||||||
@@ -346,12 +347,12 @@ class DNAName:
|
|||||||
if Index != -1:
|
if Index != -1:
|
||||||
result = result[0:Index]
|
result = result[0:Index]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def IsPointer(self):
|
def IsPointer(self):
|
||||||
return self.Name.find("*")>-1
|
return self.Name.find("*") > -1
|
||||||
|
|
||||||
def IsMethodPointer(self):
|
def IsMethodPointer(self):
|
||||||
return self.Name.find("(*")>-1
|
return self.Name.find("(*") > -1
|
||||||
|
|
||||||
def ArraySize(self):
|
def ArraySize(self):
|
||||||
result = 1
|
result = 1
|
||||||
@@ -360,10 +361,10 @@ class DNAName:
|
|||||||
|
|
||||||
while Index != -1:
|
while Index != -1:
|
||||||
Index2 = Temp.find("]")
|
Index2 = Temp.find("]")
|
||||||
result*=int(Temp[Index+1:Index2])
|
result *= int(Temp[Index + 1:Index2])
|
||||||
Temp = Temp[Index2+1:]
|
Temp = Temp[Index2 + 1:]
|
||||||
Index = Temp.find("[")
|
Index = Temp.find("[")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@@ -375,46 +376,46 @@ class DNAType:
|
|||||||
Size = int
|
Size = int
|
||||||
Structure = DNAStructure
|
Structure = DNAStructure
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, aName):
|
def __init__(self, aName):
|
||||||
self.Name = aName
|
self.Name = aName
|
||||||
self.Structure=None
|
self.Structure = None
|
||||||
|
|
||||||
|
|
||||||
class DNAStructure:
|
class DNAStructure:
|
||||||
'''
|
'''
|
||||||
DNAType is a C-type structure stored in the DNA
|
DNAType is a C-type structure stored in the DNA
|
||||||
|
|
||||||
Type = DNAType
|
Type = DNAType
|
||||||
Fields = [DNAField]
|
Fields = [DNAField]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, aType):
|
def __init__(self, aType):
|
||||||
self.Type = aType
|
self.Type = aType
|
||||||
self.Type.Structure = self
|
self.Type.Structure = self
|
||||||
self.Fields=[]
|
self.Fields = []
|
||||||
|
|
||||||
def GetField(self, header, handle, path):
|
def GetField(self, header, handle, path):
|
||||||
splitted = path.partition(".")
|
splitted = path.partition(".")
|
||||||
name = splitted[0]
|
name = splitted[0]
|
||||||
rest = splitted[2]
|
rest = splitted[2]
|
||||||
offset = 0;
|
offset = 0
|
||||||
for field in self.Fields:
|
for field in self.Fields:
|
||||||
if field.Name.ShortName() == name:
|
if field.Name.ShortName() == name:
|
||||||
log.debug("found "+name+"@"+str(offset))
|
log.debug("found " + name + "@" + str(offset))
|
||||||
handle.seek(offset, os.SEEK_CUR)
|
handle.seek(offset, os.SEEK_CUR)
|
||||||
return field.DecodeField(header, handle, rest)
|
return field.DecodeField(header, handle, rest)
|
||||||
else:
|
else:
|
||||||
offset += field.Size(header)
|
offset += field.Size(header)
|
||||||
|
|
||||||
log.debug("error did not find "+path)
|
log.debug("error did not find " + path)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class DNAField:
|
class DNAField:
|
||||||
'''
|
'''
|
||||||
DNAField is a coupled DNAType and DNAName.
|
DNAField is a coupled DNAType and DNAName.
|
||||||
|
|
||||||
Type = DNAType
|
Type = DNAType
|
||||||
Name = DNAName
|
Name = DNAName
|
||||||
'''
|
'''
|
||||||
@@ -422,25 +423,24 @@ class DNAField:
|
|||||||
def __init__(self, aType, aName):
|
def __init__(self, aType, aName):
|
||||||
self.Type = aType
|
self.Type = aType
|
||||||
self.Name = aName
|
self.Name = aName
|
||||||
|
|
||||||
def Size(self, header):
|
def Size(self, header):
|
||||||
if self.Name.IsPointer() or self.Name.IsMethodPointer():
|
if self.Name.IsPointer() or self.Name.IsMethodPointer():
|
||||||
return header.PointerSize*self.Name.ArraySize()
|
return header.PointerSize * self.Name.ArraySize()
|
||||||
else:
|
else:
|
||||||
return self.Type.Size*self.Name.ArraySize()
|
return self.Type.Size * self.Name.ArraySize()
|
||||||
|
|
||||||
def DecodeField(self, header, handle, path):
|
def DecodeField(self, header, handle, path):
|
||||||
if path == "":
|
if path == "":
|
||||||
if self.Name.IsPointer():
|
if self.Name.IsPointer():
|
||||||
return Read('pointer', handle, header)
|
return Read('pointer', handle, header)
|
||||||
if self.Type.Name=="int":
|
if self.Type.Name == "int":
|
||||||
return Read('int', handle, header)
|
return Read('int', handle, header)
|
||||||
if self.Type.Name=="short":
|
if self.Type.Name == "short":
|
||||||
return Read('short', handle, header)
|
return Read('short', handle, header)
|
||||||
if self.Type.Name=="float":
|
if self.Type.Name == "float":
|
||||||
return Read('float', handle, header)
|
return Read('float', handle, header)
|
||||||
if self.Type.Name=="char":
|
if self.Type.Name == "char":
|
||||||
return ReadString(handle, self.Name.ArraySize())
|
return ReadString(handle, self.Name.ArraySize())
|
||||||
else:
|
else:
|
||||||
return self.Type.Structure.GetField(header, handle, path)
|
return self.Type.Structure.GetField(header, handle, path)
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ def man_format(data):
|
|||||||
data = data.replace("\t", " ")
|
data = data.replace("\t", " ")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
if len(sys.argv) != 3:
|
if len(sys.argv) != 3:
|
||||||
import getopt
|
import getopt
|
||||||
raise getopt.GetoptError("Usage: %s <path-to-blender> <output-filename>" % sys.argv[0])
|
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:
|
if rna_info_BuildRNAInfo_cache.ret is None:
|
||||||
rna_info_BuildRNAInfo_cache.ret = rna_info.BuildRNAInfo()
|
rna_info_BuildRNAInfo_cache.ret = rna_info.BuildRNAInfo()
|
||||||
return rna_info_BuildRNAInfo_cache.ret
|
return rna_info_BuildRNAInfo_cache.ret
|
||||||
|
|
||||||
|
|
||||||
rna_info_BuildRNAInfo_cache.ret = None
|
rna_info_BuildRNAInfo_cache.ret = None
|
||||||
# --- end rna_info cache
|
# --- end rna_info cache
|
||||||
|
|
||||||
@@ -431,7 +433,7 @@ else:
|
|||||||
BLENDER_VERSION_DOTS = ".".join(blender_version_strings)
|
BLENDER_VERSION_DOTS = ".".join(blender_version_strings)
|
||||||
if BLENDER_REVISION != "Unknown":
|
if BLENDER_REVISION != "Unknown":
|
||||||
# '2.62a SHA1' (release) or '2.62.1 SHA1' (non-release)
|
# '2.62a SHA1' (release) or '2.62.1 SHA1' (non-release)
|
||||||
BLENDER_VERSION_DOTS += " " + BLENDER_REVISION
|
BLENDER_VERSION_DOTS += " " + BLENDER_REVISION
|
||||||
|
|
||||||
if is_release:
|
if is_release:
|
||||||
# '2_62a_release'
|
# '2_62a_release'
|
||||||
@@ -513,6 +515,8 @@ def escape_rst(text):
|
|||||||
""" Escape plain text which may contain characters used by RST.
|
""" Escape plain text which may contain characters used by RST.
|
||||||
"""
|
"""
|
||||||
return text.translate(escape_rst.trans)
|
return text.translate(escape_rst.trans)
|
||||||
|
|
||||||
|
|
||||||
escape_rst.trans = str.maketrans({
|
escape_rst.trans = str.maketrans({
|
||||||
"`": "\\`",
|
"`": "\\`",
|
||||||
"|": "\\|",
|
"|": "\\|",
|
||||||
@@ -1015,6 +1019,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
|||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
# Changes in Blender will force errors here
|
# Changes in Blender will force errors here
|
||||||
context_type_map = {
|
context_type_map = {
|
||||||
"active_base": ("ObjectBase", False),
|
"active_base": ("ObjectBase", False),
|
||||||
|
@@ -68,7 +68,7 @@ def image_from_file(filepath):
|
|||||||
|
|
||||||
if bpy is not None:
|
if bpy is not None:
|
||||||
pixels, pixel_w, pixel_h = image_from_file__bpy(filepath)
|
pixels, pixel_w, pixel_h = image_from_file__bpy(filepath)
|
||||||
#else:
|
# else:
|
||||||
# pixels, pixel_w, pixel_h = image_from_file__py(filepath)
|
# pixels, pixel_w, pixel_h = image_from_file__py(filepath)
|
||||||
|
|
||||||
return pixels, pixel_w, pixel_h
|
return pixels, pixel_w, pixel_h
|
||||||
@@ -95,12 +95,14 @@ def write_subimage(sub_x, sub_y, sub_w, sub_h,
|
|||||||
|
|
||||||
with open(filepath, 'wb') as f:
|
with open(filepath, 'wb') as f:
|
||||||
|
|
||||||
f.write(struct.pack('<6I',
|
f.write(
|
||||||
|
struct.pack(
|
||||||
|
'<6I',
|
||||||
sub_w, sub_h,
|
sub_w, sub_h,
|
||||||
sub_x, sub_y,
|
sub_x, sub_y,
|
||||||
# redundant but including to maintain consistency
|
# redundant but including to maintain consistency
|
||||||
pixel_w, pixel_h,
|
pixel_w, pixel_h,
|
||||||
))
|
))
|
||||||
|
|
||||||
for y in range(sub_h):
|
for y in range(sub_h):
|
||||||
for x in range(sub_w):
|
for x in range(sub_w):
|
||||||
@@ -113,8 +115,9 @@ def write_subimage(sub_x, sub_y, sub_w, sub_h,
|
|||||||
_dice_icon_name_cache = {}
|
_dice_icon_name_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def dice_icon_name(x, y, parts_x, parts_y,
|
def dice_icon_name(
|
||||||
name_style=None, prefix=""):
|
x, y, parts_x, parts_y,
|
||||||
|
name_style=None, prefix=""):
|
||||||
"""
|
"""
|
||||||
How to name icons, this is mainly for what name we get in git,
|
How to name icons, this is mainly for what name we get in git,
|
||||||
the actual names don't really matter, its just nice to have the
|
the actual names don't really matter, its just nice to have the
|
||||||
@@ -143,7 +146,7 @@ def dice_icon_name(x, y, parts_x, parts_y,
|
|||||||
icon_name = _dice_icon_name_cache[index]
|
icon_name = _dice_icon_name_cache[index]
|
||||||
|
|
||||||
# for debugging its handy to sort by number
|
# 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)
|
id_str = "%s%s.dat" % (prefix, icon_name)
|
||||||
|
|
||||||
@@ -158,16 +161,18 @@ def dice_icon_name(x, y, parts_x, parts_y,
|
|||||||
return id_str
|
return id_str
|
||||||
|
|
||||||
|
|
||||||
def dice(filepath, output, output_prefix, name_style,
|
def dice(
|
||||||
parts_x, parts_y,
|
filepath, output, output_prefix, name_style,
|
||||||
minx, miny, maxx, maxy,
|
parts_x, parts_y,
|
||||||
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
minx, miny, maxx, maxy,
|
||||||
spacex_icon, spacey_icon,
|
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
||||||
):
|
spacex_icon, spacey_icon,
|
||||||
|
):
|
||||||
|
|
||||||
is_simple = (max(minx, miny, maxx, maxy,
|
is_simple = (max(
|
||||||
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
minx, miny, maxx, maxy,
|
||||||
spacex_icon, spacey_icon) == 0)
|
minx_icon, miny_icon, maxx_icon, maxy_icon,
|
||||||
|
spacex_icon, spacey_icon) == 0)
|
||||||
|
|
||||||
pixels, pixel_w, pixel_h = image_from_file(filepath)
|
pixels, pixel_w, pixel_h = image_from_file(filepath)
|
||||||
|
|
||||||
@@ -199,9 +204,11 @@ def dice(filepath, output, output_prefix, name_style,
|
|||||||
|
|
||||||
for x in range(parts_x):
|
for x in range(parts_x):
|
||||||
for y in range(parts_y):
|
for y in range(parts_y):
|
||||||
id_str = dice_icon_name(x, y,
|
id_str = dice_icon_name(
|
||||||
parts_x, parts_y,
|
x, y,
|
||||||
name_style=name_style, prefix=output_prefix)
|
parts_x, parts_y,
|
||||||
|
name_style=name_style, prefix=output_prefix
|
||||||
|
)
|
||||||
filepath = os.path.join(output, id_str)
|
filepath = os.path.join(output, id_str)
|
||||||
if VERBOSE:
|
if VERBOSE:
|
||||||
print(" writing:", filepath)
|
print(" writing:", filepath)
|
||||||
@@ -235,25 +242,35 @@ def main():
|
|||||||
parser = argparse.ArgumentParser(description=__doc__, epilog=epilog)
|
parser = argparse.ArgumentParser(description=__doc__, epilog=epilog)
|
||||||
|
|
||||||
# File path options
|
# File path options
|
||||||
parser.add_argument("--image", dest="image", metavar='FILE',
|
parser.add_argument(
|
||||||
help="Image file")
|
"--image", dest="image", metavar='FILE',
|
||||||
|
help="Image file",
|
||||||
parser.add_argument("--output", dest="output", metavar='DIR',
|
)
|
||||||
help="Output directory")
|
parser.add_argument(
|
||||||
|
"--output", dest="output", metavar='DIR',
|
||||||
parser.add_argument("--output_prefix", dest="output_prefix", metavar='STRING',
|
help="Output directory",
|
||||||
help="Output prefix")
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--output_prefix", dest="output_prefix", metavar='STRING',
|
||||||
|
help="Output prefix",
|
||||||
|
)
|
||||||
|
|
||||||
# Icon naming option
|
# Icon naming option
|
||||||
parser.add_argument("--name_style", dest="name_style", metavar='ENUM', type=str,
|
parser.add_argument(
|
||||||
choices=('', 'UI_ICONS'),
|
"--name_style", dest="name_style", metavar='ENUM', type=str,
|
||||||
help="The metod used for naming output data")
|
choices=('', 'UI_ICONS'),
|
||||||
|
help="The metod used for naming output data",
|
||||||
|
)
|
||||||
|
|
||||||
# Options for dicing up the image
|
# Options for dicing up the image
|
||||||
parser.add_argument("--parts_x", dest="parts_x", metavar='INT', type=int,
|
parser.add_argument(
|
||||||
help="Grid X parts")
|
"--parts_x", dest="parts_x", metavar='INT', type=int,
|
||||||
parser.add_argument("--parts_y", dest="parts_y", metavar='INT', type=int,
|
help="Grid X parts",
|
||||||
help="Grid Y 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)"
|
_help = "Inset from the outer edge (in pixels)"
|
||||||
parser.add_argument("--minx", dest="minx", metavar='INT', type=int, help=_help)
|
parser.add_argument("--minx", dest="minx", metavar='INT', type=int, help=_help)
|
||||||
@@ -287,5 +304,6 @@ def main():
|
|||||||
args.spacex_icon, args.spacey_icon,
|
args.spacex_icon, args.spacey_icon,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -67,5 +67,6 @@ def main():
|
|||||||
|
|
||||||
icondata_to_png(file_src, file_dst)
|
icondata_to_png(file_src, file_dst)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -56,19 +56,19 @@ def check_commandline():
|
|||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
# Usage
|
# Usage
|
||||||
if len(sys.argv)==1 or len(sys.argv)>3:
|
if len(sys.argv) == 1 or len(sys.argv) > 3:
|
||||||
usage()
|
usage()
|
||||||
if sys.argv[1] == '-h':
|
if sys.argv[1] == '-h':
|
||||||
help()
|
help()
|
||||||
elif not sys.argv[1].endswith((".txt", ".py")):
|
elif not sys.argv[1].endswith((".txt", ".py")):
|
||||||
print ('\nBad input file extension... exiting.')
|
print('\nBad input file extension... exiting.')
|
||||||
usage()
|
usage()
|
||||||
else:
|
else:
|
||||||
inputfile = sys.argv[1]
|
inputfile = sys.argv[1]
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
sort_priority = default_sort_choice
|
sort_priority = default_sort_choice
|
||||||
print ('\nSecond parameter missing: choosing to order by %s.' % font_bold(sort_priority))
|
print('\nSecond parameter missing: choosing to order by %s.' % font_bold(sort_priority))
|
||||||
elif len(sys.argv)==3:
|
elif len(sys.argv) == 3:
|
||||||
sort_priority = sys.argv[2]
|
sort_priority = sys.argv[2]
|
||||||
if sort_priority not in sort_choices:
|
if sort_priority not in sort_choices:
|
||||||
print('\nWrong sort_priority... exiting.')
|
print('\nWrong sort_priority... exiting.')
|
||||||
@@ -93,9 +93,11 @@ def check_prefix(prop, btype):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def check_if_changed(a,b):
|
def check_if_changed(a, b):
|
||||||
if a != b: return 'changed'
|
if a != b:
|
||||||
else: return 'same'
|
return 'changed'
|
||||||
|
else:
|
||||||
|
return 'same'
|
||||||
|
|
||||||
|
|
||||||
def get_props_from_txt(input_filename):
|
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
|
If the file is *.txt, the script assumes it is formatted as outlined in this script docstring
|
||||||
"""
|
"""
|
||||||
|
|
||||||
file=open(input_filename,'r')
|
file = open(input_filename, 'r')
|
||||||
file_lines=file.readlines()
|
file_lines = file.readlines()
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
props_list=[]
|
props_list = []
|
||||||
props_length_max=[0,0,0,0,0,0,0,0]
|
props_length_max = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
done_text = "+"
|
done_text = "+"
|
||||||
done = 0
|
done = 0
|
||||||
@@ -117,7 +119,7 @@ def get_props_from_txt(input_filename):
|
|||||||
for iii, line in enumerate(file_lines):
|
for iii, line in enumerate(file_lines):
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
#print(line)
|
# print(line)
|
||||||
line_strip = line.strip()
|
line_strip = line.strip()
|
||||||
# empty line or comment
|
# empty line or comment
|
||||||
if not line_strip:
|
if not line_strip:
|
||||||
@@ -136,7 +138,7 @@ def get_props_from_txt(input_filename):
|
|||||||
if '*' in bclass:
|
if '*' in bclass:
|
||||||
comment, bclass = [x.strip() for x in bclass.split('*', 1)]
|
comment, bclass = [x.strip() for x in bclass.split('*', 1)]
|
||||||
else:
|
else:
|
||||||
comment= ''
|
comment = ''
|
||||||
|
|
||||||
# skipping the header if we have one.
|
# skipping the header if we have one.
|
||||||
# the header is assumed to be "NOTE * CLASS.FROM -> TO: TYPE DESCRIPTION"
|
# 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
|
# make life easy and strip quotes
|
||||||
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
btype, description = [tail,'NO DESCRIPTION']
|
btype, description = [tail, 'NO DESCRIPTION']
|
||||||
|
|
||||||
# keyword-check
|
# keyword-check
|
||||||
kwcheck = check_prefix(bto, btype)
|
kwcheck = check_prefix(bto, btype)
|
||||||
@@ -164,17 +166,17 @@ def get_props_from_txt(input_filename):
|
|||||||
changed = check_if_changed(bfrom, bto)
|
changed = check_if_changed(bfrom, bto)
|
||||||
|
|
||||||
# lists formatting
|
# 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_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:
|
if done_text in comment:
|
||||||
done += 1
|
done += 1
|
||||||
tot += 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):
|
def get_props_from_py(input_filename):
|
||||||
@@ -185,25 +187,25 @@ def get_props_from_py(input_filename):
|
|||||||
# adds the list "rna_api" to this function's scope
|
# adds the list "rna_api" to this function's scope
|
||||||
rna_api = __import__(input_filename[:-3]).rna_api
|
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
|
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
|
comment, changed, bclass, bfrom, bto, kwcheck, btype, description = props
|
||||||
kwcheck = check_prefix(bto, btype) # keyword-check
|
kwcheck = check_prefix(bto, btype) # keyword-check
|
||||||
changed = check_if_changed(bfrom, bto) # changed?
|
changed = check_if_changed(bfrom, bto) # changed?
|
||||||
description = repr(description)
|
description = repr(description)
|
||||||
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
description = description.replace("'", "").replace('"', "").replace("\\", "").strip()
|
||||||
rna_api[index] = [comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
rna_api[index] = [comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
||||||
props_length = list(map(len,props)) # lengths
|
props_length = list(map(len, props)) # lengths
|
||||||
props_length_max = list(map(max,zip(props_length_max,props_length))) # max lengths
|
props_length_max = list(map(max, zip(props_length_max, props_length))) # max lengths
|
||||||
return (rna_api,props_length_max)
|
return (rna_api, props_length_max)
|
||||||
|
|
||||||
|
|
||||||
def get_props(input_filename):
|
def get_props(input_filename):
|
||||||
if input_filename.endswith(".txt"):
|
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"):
|
elif input_filename.endswith(".py"):
|
||||||
props_list,props_length_max = get_props_from_py(input_filename)
|
props_list, props_length_max = get_props_from_py(input_filename)
|
||||||
return (props_list,props_length_max)
|
return (props_list, props_length_max)
|
||||||
|
|
||||||
|
|
||||||
def sort(props_list, sort_priority):
|
def sort(props_list, sort_priority):
|
||||||
@@ -222,7 +224,7 @@ def sort(props_list, sort_priority):
|
|||||||
else:
|
else:
|
||||||
props_list = sorted(props_list, key=lambda p: p[i])
|
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
|
return props_list
|
||||||
|
|
||||||
|
|
||||||
@@ -250,30 +252,35 @@ def write_files(basename, props_list, props_length_max):
|
|||||||
* rna_api.py: unformatted, just as final output
|
* rna_api.py: unformatted, just as final output
|
||||||
"""
|
"""
|
||||||
|
|
||||||
f_rna = open("rna_api.py",'w')
|
f_rna = open("rna_api.py", 'w')
|
||||||
f_txt = open(basename + '_work.txt','w')
|
f_txt = open(basename + '_work.txt', 'w')
|
||||||
f_py = open(basename + '_work.py','w')
|
f_py = open(basename + '_work.py', 'w')
|
||||||
|
|
||||||
# reminder: props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
|
# 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]
|
# [comment *] ToolSettings.snap_align_rotation -> use_snap_align_rotation: boolean [Align rotation with the snapping target]
|
||||||
rna = py = txt = ''
|
rna = py = txt = ''
|
||||||
props_list = [['NOTE', 'CHANGED', 'CLASS', 'FROM', 'TO', 'KEYWORD-CHECK', 'TYPE', 'DESCRIPTION']] + props_list
|
props_list = [['NOTE', 'CHANGED', 'CLASS', 'FROM', 'TO', 'KEYWORD-CHECK', 'TYPE', 'DESCRIPTION']] + props_list
|
||||||
for props in props_list:
|
for props in props_list:
|
||||||
#txt
|
# txt
|
||||||
|
|
||||||
# quick way we can tell if it changed
|
# quick way we can tell if it changed
|
||||||
if props[3] == props[4]: txt += "#"
|
if props[3] == props[4]:
|
||||||
else: txt += " "
|
txt += "#"
|
||||||
|
else:
|
||||||
|
txt += " "
|
||||||
|
|
||||||
if props[0] != '': txt += '%s * ' % props[0] # comment
|
if props[0] != '':
|
||||||
txt += '%s.%s -> %s: %s "%s"\n' % tuple(props[2:5] + props[6:]) # skipping keyword-check
|
txt += '%s * ' % props[0] # comment
|
||||||
|
txt += '%s.%s -> %s: %s "%s"\n' % tuple(props[2:5] + props[6:]) # skipping keyword-check
|
||||||
# rna_api
|
# rna_api
|
||||||
if props[0] == 'NOTE': indent = '# '
|
if props[0] == 'NOTE':
|
||||||
else: indent = ' '
|
indent = '# '
|
||||||
rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:]) # description is already string formatted
|
else:
|
||||||
|
indent = ' '
|
||||||
|
rna += indent + '("%s", "%s", "%s", "%s", "%s"),\n' % tuple(props[2:5] + props[6:]) # description is already string formatted
|
||||||
# py
|
# py
|
||||||
blanks = [' '* (x[0]-x[1]) for x in zip(props_length_max,list(map(len,props)))]
|
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)]
|
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)
|
py += indent + '(%s, %s, %s, %s, %s, %s, %s, "%s"),\n' % tuple(props)
|
||||||
|
|
||||||
f_txt.write(txt)
|
f_txt.write(txt)
|
||||||
@@ -290,7 +297,7 @@ def write_files(basename, props_list, props_length_max):
|
|||||||
f_py.close()
|
f_py.close()
|
||||||
f_rna.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():
|
def main():
|
||||||
@@ -298,21 +305,21 @@ def main():
|
|||||||
global sort_choices, default_sort_choice
|
global sort_choices, default_sort_choice
|
||||||
global kw_prefixes, kw
|
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]
|
default_sort_choice = sort_choices[-1]
|
||||||
kw_prefixes = [ 'active','apply','bl','exclude','has','invert','is','lock', \
|
kw_prefixes = ['active', 'apply', 'bl', 'exclude', 'has', 'invert', 'is', 'lock',
|
||||||
'pressed','show','show_only','use','use_only','layers','states', 'select']
|
'pressed', 'show', 'show_only', 'use', 'use_only', 'layers', 'states', 'select']
|
||||||
kw = ['active','hide','invert','select','layers','mute','states','use','lock']
|
kw = ['active', 'hide', 'invert', 'select', 'layers', 'mute', 'states', 'use', 'lock']
|
||||||
|
|
||||||
input_filename, sort_priority = check_commandline()
|
input_filename, sort_priority = check_commandline()
|
||||||
props_list,props_length_max = get_props(input_filename)
|
props_list, props_length_max = get_props(input_filename)
|
||||||
props_list = sort(props_list,sort_priority)
|
props_list = sort(props_list, sort_priority)
|
||||||
|
|
||||||
output_basename = file_basename(input_filename)
|
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
|
import sys
|
||||||
if not sys.version.startswith("3"):
|
if not sys.version.startswith("3"):
|
||||||
print("Incorrect python version, use python 3!")
|
print("Incorrect python version, use python 3!")
|
||||||
|
@@ -6,56 +6,58 @@ import sys
|
|||||||
Example usage:
|
Example usage:
|
||||||
python3 rna_cleaner_merge.py out_work.py rna_booleans_work.py
|
python3 rna_cleaner_merge.py out_work.py rna_booleans_work.py
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
def work_line_id(line):
|
def work_line_id(line):
|
||||||
return line[2].split("|")[-1], line[3] # class/from
|
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.")
|
||||||
|
|
||||||
if not (sys.argv[-1].endswith(".py") and sys.argv[-2].endswith(".py")):
|
sys.path.insert(0, ".")
|
||||||
print("Only accepts 2 py files as arguments.")
|
|
||||||
|
|
||||||
sys.path.insert(0, ".")
|
mod_from = __import__(sys.argv[-1][:-3])
|
||||||
|
mod_to = __import__(sys.argv[-2][:-3])
|
||||||
|
|
||||||
mod_from = __import__(sys.argv[-1][:-3])
|
mod_to_dict = dict([(work_line_id(line), line) for line in mod_to.rna_api])
|
||||||
mod_to = __import__(sys.argv[-2][:-3])
|
mod_from_dict = dict([(work_line_id(line), line) for line in mod_from.rna_api])
|
||||||
|
|
||||||
mod_to_dict = dict([(work_line_id(line), line) for line in mod_to.rna_api])
|
rna_api_new = []
|
||||||
mod_from_dict = dict([(work_line_id(line), line) for line in mod_from.rna_api])
|
|
||||||
|
|
||||||
rna_api_new = []
|
for key, val_orig in mod_to_dict.items():
|
||||||
|
try:
|
||||||
|
val_new = mod_from_dict.pop(key)
|
||||||
|
except:
|
||||||
|
# print("not found", key)
|
||||||
|
val_new = val_orig
|
||||||
|
|
||||||
for key, val_orig in mod_to_dict.items():
|
# always take the class from the base
|
||||||
try:
|
val = list(val_orig)
|
||||||
val_new = mod_from_dict.pop(key)
|
val[0] = val_new[0] # comment
|
||||||
except:
|
val[4] = val_new[4] # -> to
|
||||||
# print("not found", key)
|
val = tuple(val)
|
||||||
val_new = val_orig
|
rna_api_new.append(val)
|
||||||
|
|
||||||
# always take the class from the base
|
def write_work_file(file_path, rna_api):
|
||||||
val = list(val_orig)
|
rna_api = list(rna_api)
|
||||||
val[0] = val_new[0] # comment
|
rna_api.sort(key=work_line_id)
|
||||||
val[4] = val_new[4] # -> to
|
file_out = open(file_path, "w")
|
||||||
val = tuple(val)
|
file_out.write("rna_api = [\n")
|
||||||
rna_api_new.append(val)
|
for line in rna_api:
|
||||||
|
file_out.write(" %s,\n" % (repr(line)))
|
||||||
|
file_out.write("]\n")
|
||||||
|
file_out.close()
|
||||||
|
|
||||||
def write_work_file(file_path, rna_api):
|
file_path = sys.argv[-2][:-3] + "_merged.py"
|
||||||
rna_api = list(rna_api)
|
write_work_file(file_path, rna_api_new)
|
||||||
rna_api.sort(key=work_line_id)
|
|
||||||
file_out = open(file_path, "w")
|
|
||||||
file_out.write("rna_api = [\n")
|
|
||||||
for line in rna_api:
|
|
||||||
file_out.write(" %s,\n" % (repr(line)))
|
|
||||||
file_out.write("]\n")
|
|
||||||
file_out.close()
|
|
||||||
|
|
||||||
file_path = sys.argv[-2][:-3] + "_merged.py"
|
if mod_from_dict:
|
||||||
write_work_file(file_path, rna_api_new)
|
file_path = sys.argv[-2][:-3] + "_lost.py"
|
||||||
|
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 mod_from_dict:
|
|
||||||
file_path = sys.argv[-2][:-3] + "_lost.py"
|
|
||||||
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -129,6 +129,7 @@ def seek(r, txt, recurs):
|
|||||||
newtxt = txt + '[' + str(i) + ']'
|
newtxt = txt + '[' + str(i) + ']'
|
||||||
seek(r[i], newtxt, recurs + 1)
|
seek(r[i], newtxt, recurs + 1)
|
||||||
|
|
||||||
|
|
||||||
seek(bpy.data, 'bpy.data', 0)
|
seek(bpy.data, 'bpy.data', 0)
|
||||||
# seek(bpy.types, 'bpy.types', 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)
|
seek(r, 'bpy.types.' + d + '.bl_rna', 0)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
#print dir(bpy)
|
# print dir(bpy)
|
||||||
#import sys
|
#import sys
|
||||||
#sys.exit()
|
# sys.exit()
|
||||||
|
|
||||||
print("iter over ", seek_count, "rna items")
|
print("iter over ", seek_count, "rna items")
|
||||||
|
@@ -50,8 +50,10 @@ for d in defs.split('\n'):
|
|||||||
if not w:
|
if not w:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try: w.remove("#define")
|
try:
|
||||||
except: pass
|
w.remove("#define")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# print w
|
# print w
|
||||||
|
|
||||||
|
@@ -142,5 +142,6 @@ def main():
|
|||||||
else:
|
else:
|
||||||
print("\nnone found!")
|
print("\nnone found!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@@ -33,7 +33,6 @@ from modules.test_utils import (with_tempdir,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AbcPropError(Exception):
|
class AbcPropError(Exception):
|
||||||
"""Raised when AbstractAlembicTest.abcprop() finds an error."""
|
"""Raised when AbstractAlembicTest.abcprop() finds an error."""
|
||||||
|
|
||||||
|
@@ -107,7 +107,6 @@ class SimpleImportTest(AbstractAlembicTest):
|
|||||||
self.assertAlmostEqual(0, y)
|
self.assertAlmostEqual(0, y)
|
||||||
self.assertAlmostEqual(2, z)
|
self.assertAlmostEqual(2, z)
|
||||||
|
|
||||||
|
|
||||||
def test_select_after_import(self):
|
def test_select_after_import(self):
|
||||||
# Add a sphere, so that there is something in the scene, selected, and active,
|
# Add a sphere, so that there is something in the scene, selected, and active,
|
||||||
# before we do the Alembic import.
|
# before we do the Alembic import.
|
||||||
|
@@ -33,7 +33,7 @@ import imp
|
|||||||
|
|
||||||
BLACKLIST_DIRS = (
|
BLACKLIST_DIRS = (
|
||||||
os.path.join(bpy.utils.resource_path('USER'), "scripts"),
|
os.path.join(bpy.utils.resource_path('USER'), "scripts"),
|
||||||
) + tuple(addon_utils.paths()[1:])
|
) + tuple(addon_utils.paths()[1:])
|
||||||
BLACKLIST_ADDONS = set()
|
BLACKLIST_ADDONS = set()
|
||||||
|
|
||||||
|
|
||||||
@@ -54,9 +54,10 @@ def _init_addon_blacklist():
|
|||||||
def addon_modules_sorted():
|
def addon_modules_sorted():
|
||||||
modules = addon_utils.modules({})
|
modules = addon_utils.modules({})
|
||||||
modules[:] = [
|
modules[:] = [
|
||||||
mod for mod in modules
|
mod for mod in modules
|
||||||
if not (mod.__file__.startswith(BLACKLIST_DIRS))
|
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__)
|
modules.sort(key=lambda mod: mod.__name__)
|
||||||
return modules
|
return modules
|
||||||
|
|
||||||
|
@@ -39,20 +39,20 @@ BLACKLIST = {
|
|||||||
|
|
||||||
# The unpacked wheel is only loaded when actually used, not directly on import:
|
# The unpacked wheel is only loaded when actually used, not directly on import:
|
||||||
os.path.join("io_blend_utils", "blender_bam-unpacked.whl"),
|
os.path.join("io_blend_utils", "blender_bam-unpacked.whl"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Some modules need to add to the `sys.path`.
|
# Some modules need to add to the `sys.path`.
|
||||||
MODULE_SYS_PATHS = {
|
MODULE_SYS_PATHS = {
|
||||||
# Runs in a Python subprocess, so its expected its basedir can be imported.
|
# Runs in a Python subprocess, so its expected its basedir can be imported.
|
||||||
"io_blend_utils.blendfile_pack": ".",
|
"io_blend_utils.blendfile_pack": ".",
|
||||||
}
|
}
|
||||||
|
|
||||||
if not bpy.app.build_options.freestyle:
|
if not bpy.app.build_options.freestyle:
|
||||||
BLACKLIST.add("render_freestyle_svg")
|
BLACKLIST.add("render_freestyle_svg")
|
||||||
|
|
||||||
BLACKLIST_DIRS = (
|
BLACKLIST_DIRS = (
|
||||||
os.path.join(bpy.utils.resource_path('USER'), "scripts"),
|
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):
|
def module_names_recursive(mod_dir, *, parent=None):
|
||||||
@@ -168,7 +168,7 @@ def load_modules():
|
|||||||
os.sep + "presets" + os.sep,
|
os.sep + "presets" + os.sep,
|
||||||
os.sep + "templates" + os.sep,
|
os.sep + "templates" + os.sep,
|
||||||
] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
|
] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
|
||||||
[(os.sep + f + ".py") for f in BLACKLIST])
|
[(os.sep + f + ".py") for f in BLACKLIST])
|
||||||
|
|
||||||
#
|
#
|
||||||
# now submodules
|
# now submodules
|
||||||
@@ -185,7 +185,7 @@ def load_modules():
|
|||||||
sys.path.extend([
|
sys.path.extend([
|
||||||
os.path.normpath(os.path.join(mod_dir, f))
|
os.path.normpath(os.path.join(mod_dir, f))
|
||||||
for f in MODULE_SYS_PATHS.get(mod_name_full, ())
|
for f in MODULE_SYS_PATHS.get(mod_name_full, ())
|
||||||
])
|
])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
__import__(mod_name_full)
|
__import__(mod_name_full)
|
||||||
@@ -248,6 +248,7 @@ def main():
|
|||||||
load_addons()
|
load_addons()
|
||||||
load_modules()
|
load_modules()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# So a python error exits(1)
|
# So a python error exits(1)
|
||||||
try:
|
try:
|
||||||
|
@@ -61,11 +61,11 @@ def render_gl(context, filepath, shade):
|
|||||||
|
|
||||||
ctx_viewport_shade(context, shade)
|
ctx_viewport_shade(context, shade)
|
||||||
|
|
||||||
#~ # stop to inspect!
|
# stop to inspect!
|
||||||
#~ if filepath == "test_cube_shell_solidify_subsurf_wp_wire":
|
# if filepath == "test_cube_shell_solidify_subsurf_wp_wire":
|
||||||
#~ assert(0)
|
# assert(0)
|
||||||
#~ else:
|
# else:
|
||||||
#~ return
|
# return
|
||||||
|
|
||||||
bpy.ops.render.opengl(write_still=True,
|
bpy.ops.render.opengl(write_still=True,
|
||||||
view_context=True)
|
view_context=True)
|
||||||
@@ -219,6 +219,7 @@ def mesh_bmesh_poly_elems(poly, elems):
|
|||||||
vert_total = poly.loop_total
|
vert_total = poly.loop_total
|
||||||
return elems[vert_start:vert_start + vert_total]
|
return elems[vert_start:vert_start + vert_total]
|
||||||
|
|
||||||
|
|
||||||
def mesh_bmesh_poly_vertices(poly):
|
def mesh_bmesh_poly_vertices(poly):
|
||||||
return [loop.vertex_index
|
return [loop.vertex_index
|
||||||
for loop in mesh_bmesh_poly_elems(poly, poly.id_data.loops)]
|
for loop in mesh_bmesh_poly_elems(poly, poly.id_data.loops)]
|
||||||
@@ -505,7 +506,7 @@ cube_like_vertices = (
|
|||||||
(-1, 1, 3),
|
(-1, 1, 3),
|
||||||
(0, 1, 3),
|
(0, 1, 3),
|
||||||
(0, 0, 3),
|
(0, 0, 3),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cube_like_faces = (
|
cube_like_faces = (
|
||||||
@@ -547,7 +548,7 @@ cube_like_faces = (
|
|||||||
(31, 30, 36, 33),
|
(31, 30, 36, 33),
|
||||||
(32, 31, 33, 34),
|
(32, 31, 33, 34),
|
||||||
(35, 34, 33, 36),
|
(35, 34, 33, 36),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# useful since its a shell for solidify and it can be mirrored
|
# useful since its a shell for solidify and it can be mirrored
|
||||||
@@ -564,7 +565,7 @@ cube_shell_vertices = (
|
|||||||
(0, -1, 0),
|
(0, -1, 0),
|
||||||
(0, 0, -1),
|
(0, 0, -1),
|
||||||
(0, 1, -1),
|
(0, 1, -1),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cube_shell_face = (
|
cube_shell_face = (
|
||||||
@@ -577,7 +578,7 @@ cube_shell_face = (
|
|||||||
(6, 5, 11),
|
(6, 5, 11),
|
||||||
(7, 4, 9, 8),
|
(7, 4, 9, 8),
|
||||||
(10, 7, 6, 11),
|
(10, 7, 6, 11),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_cube(scene):
|
def make_cube(scene):
|
||||||
@@ -678,59 +679,77 @@ def make_monkey_extra(scene):
|
|||||||
|
|
||||||
global_tests = []
|
global_tests = []
|
||||||
|
|
||||||
global_tests.append(("none",
|
global_tests.append(
|
||||||
(),
|
("none",
|
||||||
))
|
(),
|
||||||
|
)
|
||||||
|
)
|
||||||
# single
|
# single
|
||||||
global_tests.append(("subsurf_single",
|
global_tests.append(
|
||||||
((modifier_subsurf_add, dict(levels=2)), ),
|
("subsurf_single",
|
||||||
))
|
((modifier_subsurf_add, dict(levels=2)), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
global_tests.append(
|
||||||
|
("armature_single",
|
||||||
|
((modifier_armature_add, dict()), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
global_tests.append(("armature_single",
|
global_tests.append(
|
||||||
((modifier_armature_add, dict()), ),
|
("mirror_single",
|
||||||
))
|
((modifier_mirror_add, dict()), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
global_tests.append(
|
||||||
|
("hook_single",
|
||||||
|
((modifier_hook_add, dict()), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
global_tests.append(("mirror_single",
|
global_tests.append(
|
||||||
((modifier_mirror_add, dict()), ),
|
("decimate_single",
|
||||||
))
|
((modifier_decimate_add, dict()), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
global_tests.append(("hook_single",
|
global_tests.append(
|
||||||
((modifier_hook_add, dict()), ),
|
("build_single",
|
||||||
))
|
((modifier_build_add, dict()), ),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
global_tests.append(("decimate_single",
|
global_tests.append(
|
||||||
((modifier_decimate_add, dict()), ),
|
("mask_single",
|
||||||
))
|
((modifier_mask_add, dict()), ),
|
||||||
|
)
|
||||||
global_tests.append(("build_single",
|
)
|
||||||
((modifier_build_add, dict()), ),
|
|
||||||
))
|
|
||||||
|
|
||||||
global_tests.append(("mask_single",
|
|
||||||
((modifier_mask_add, dict()), ),
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
# combinations
|
# combinations
|
||||||
global_tests.append(("mirror_subsurf",
|
global_tests.append(
|
||||||
((modifier_mirror_add, dict()),
|
("mirror_subsurf",
|
||||||
(modifier_subsurf_add, dict(levels=2))),
|
((modifier_mirror_add, dict()),
|
||||||
))
|
(modifier_subsurf_add, dict(levels=2))),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
global_tests.append(("solidify_subsurf",
|
global_tests.append(
|
||||||
((modifier_solidify_add, dict()),
|
("solidify_subsurf",
|
||||||
(modifier_subsurf_add, dict(levels=2))),
|
((modifier_solidify_add, dict()),
|
||||||
))
|
(modifier_subsurf_add, dict(levels=2))),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def apply_test(test, scene, obj,
|
def apply_test(
|
||||||
render_func=None,
|
test, scene, obj,
|
||||||
render_args=None,
|
render_func=None,
|
||||||
render_kwargs=None,
|
render_args=None,
|
||||||
):
|
render_kwargs=None,
|
||||||
|
):
|
||||||
|
|
||||||
test_name, test_funcs = test
|
test_name, test_funcs = test
|
||||||
|
|
||||||
@@ -756,10 +775,12 @@ def test_cube(context, test):
|
|||||||
obj = make_cube_extra(scene)
|
obj = make_cube_extra(scene)
|
||||||
ctx_camera_setup(context, location=(3, 3, 3))
|
ctx_camera_setup(context, location=(3, 3, 3))
|
||||||
|
|
||||||
apply_test(test, scene, obj,
|
apply_test(
|
||||||
render_func=render_gl_all_modes,
|
test, scene, obj,
|
||||||
render_args=(context, obj),
|
render_func=render_gl_all_modes,
|
||||||
render_kwargs=dict(filepath=whoami()))
|
render_args=(context, obj),
|
||||||
|
render_kwargs=dict(filepath=whoami())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_cube_like(context, test):
|
def test_cube_like(context, test):
|
||||||
@@ -767,10 +788,12 @@ def test_cube_like(context, test):
|
|||||||
obj = make_cube_like_extra(scene)
|
obj = make_cube_like_extra(scene)
|
||||||
ctx_camera_setup(context, location=(5, 5, 5))
|
ctx_camera_setup(context, location=(5, 5, 5))
|
||||||
|
|
||||||
apply_test(test, scene, obj,
|
apply_test(
|
||||||
render_func=render_gl_all_modes,
|
test, scene, obj,
|
||||||
render_args=(context, obj),
|
render_func=render_gl_all_modes,
|
||||||
render_kwargs=dict(filepath=whoami()))
|
render_args=(context, obj),
|
||||||
|
render_kwargs=dict(filepath=whoami())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_cube_shell(context, test):
|
def test_cube_shell(context, test):
|
||||||
@@ -778,10 +801,12 @@ def test_cube_shell(context, test):
|
|||||||
obj = make_cube_shell_extra(scene)
|
obj = make_cube_shell_extra(scene)
|
||||||
ctx_camera_setup(context, location=(4, 4, 4))
|
ctx_camera_setup(context, location=(4, 4, 4))
|
||||||
|
|
||||||
apply_test(test, scene, obj,
|
apply_test(
|
||||||
render_func=render_gl_all_modes,
|
test, scene, obj,
|
||||||
render_args=(context, obj),
|
render_func=render_gl_all_modes,
|
||||||
render_kwargs=dict(filepath=whoami()))
|
render_args=(context, obj),
|
||||||
|
render_kwargs=dict(filepath=whoami())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@@ -45,20 +45,20 @@ MESHES = {
|
|||||||
( # Edges
|
( # Edges
|
||||||
),
|
),
|
||||||
( # Loops
|
( # Loops
|
||||||
0, 1, 4, 3,
|
0, 1, 4, 3,
|
||||||
3, 4, 6,
|
3, 4, 6,
|
||||||
1, 2, 5, 4,
|
1, 2, 5, 4,
|
||||||
3, 4, 6,
|
3, 4, 6,
|
||||||
4, 7, 6,
|
4, 7, 6,
|
||||||
4, 5, 9, 4, 8, 7,
|
4, 5, 9, 4, 8, 7,
|
||||||
),
|
),
|
||||||
( # Polygons
|
( # Polygons
|
||||||
(0, 4),
|
(0, 4),
|
||||||
(4, 3),
|
(4, 3),
|
||||||
(7, 4),
|
(7, 4),
|
||||||
(11, 3),
|
(11, 3),
|
||||||
(14, 3),
|
(14, 3),
|
||||||
(16, 6),
|
(16, 6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -66,17 +66,17 @@ MESHES = {
|
|||||||
|
|
||||||
|
|
||||||
BUILTINS = (
|
BUILTINS = (
|
||||||
"primitive_plane_add",
|
"primitive_plane_add",
|
||||||
"primitive_cube_add",
|
"primitive_cube_add",
|
||||||
"primitive_circle_add",
|
"primitive_circle_add",
|
||||||
"primitive_uv_sphere_add",
|
"primitive_uv_sphere_add",
|
||||||
"primitive_ico_sphere_add",
|
"primitive_ico_sphere_add",
|
||||||
"primitive_cylinder_add",
|
"primitive_cylinder_add",
|
||||||
"primitive_cone_add",
|
"primitive_cone_add",
|
||||||
"primitive_grid_add",
|
"primitive_grid_add",
|
||||||
"primitive_monkey_add",
|
"primitive_monkey_add",
|
||||||
"primitive_torus_add",
|
"primitive_torus_add",
|
||||||
)
|
)
|
||||||
BUILTINS_NBR = 4
|
BUILTINS_NBR = 4
|
||||||
BUILTINS_NBRCHANGES = 5
|
BUILTINS_NBRCHANGES = 5
|
||||||
|
|
||||||
|
@@ -5,25 +5,26 @@ import unittest
|
|||||||
|
|
||||||
from bpy.utils import units
|
from bpy.utils import units
|
||||||
|
|
||||||
|
|
||||||
class UnitsTesting(unittest.TestCase):
|
class UnitsTesting(unittest.TestCase):
|
||||||
# From user typing to 'internal' Blender value.
|
# From user typing to 'internal' Blender value.
|
||||||
INPUT_TESTS = (
|
INPUT_TESTS = (
|
||||||
# system, type, ref, input, value
|
# system, type, ref, input, value
|
||||||
##### LENGTH
|
# LENGTH
|
||||||
('IMPERIAL', 'LENGTH', "", "1ft", 0.3048),
|
('IMPERIAL', 'LENGTH', "", "1ft", 0.3048),
|
||||||
('IMPERIAL', 'LENGTH', "", "(1+1)ft", 0.3048 * 2),
|
('IMPERIAL', 'LENGTH', "", "(1+1)ft", 0.3048 * 2),
|
||||||
('IMPERIAL', 'LENGTH', "", "1mi4\"", 1609.344 + 0.0254 * 4),
|
('IMPERIAL', 'LENGTH', "", "1mi4\"", 1609.344 + 0.0254 * 4),
|
||||||
('METRIC', 'LENGTH', "", "0.005µm", 0.000001 * 0.005),
|
('METRIC', 'LENGTH', "", "0.005µm", 0.000001 * 0.005),
|
||||||
('METRIC', 'LENGTH', "", "1e6km", 1000.0 * 1e6),
|
('METRIC', 'LENGTH', "", "1e6km", 1000.0 * 1e6),
|
||||||
('IMPERIAL', 'LENGTH', "", "1ft5cm", 0.3048 + 0.01 * 5),
|
('IMPERIAL', 'LENGTH', "", "1ft5cm", 0.3048 + 0.01 * 5),
|
||||||
('METRIC', 'LENGTH', "", "1ft5cm", 0.3048 + 0.01 * 5),
|
('METRIC', 'LENGTH', "", "1ft5cm", 0.3048 + 0.01 * 5),
|
||||||
# Using reference string to find a unit when none is given.
|
# Using reference string to find a unit when none is given.
|
||||||
('IMPERIAL', 'LENGTH', "33.3ft", "1", 0.3048),
|
('IMPERIAL', 'LENGTH', "33.3ft", "1", 0.3048),
|
||||||
('METRIC', 'LENGTH', "33.3dm", "1", 0.1),
|
('METRIC', 'LENGTH', "33.3dm", "1", 0.1),
|
||||||
('IMPERIAL', 'LENGTH', "33.3cm", "1", 0.3048), # ref unit is not in IMPERIAL system, default to feet...
|
('IMPERIAL', 'LENGTH', "33.3cm", "1", 0.3048), # ref unit is not in IMPERIAL system, default to feet...
|
||||||
('IMPERIAL', 'LENGTH', "33.3ft", "1\"", 0.0254), # unused ref unit, since one is given already!
|
('IMPERIAL', 'LENGTH', "33.3ft", "1\"", 0.0254), # unused ref unit, since one is given already!
|
||||||
('IMPERIAL', 'LENGTH', "", "1+1ft", 0.3048 * 2), # default unit taken from current string (feet).
|
('IMPERIAL', 'LENGTH', "", "1+1ft", 0.3048 * 2), # default unit taken from current string (feet).
|
||||||
('METRIC', 'LENGTH', "", "1+1ft", 1.3048), # no metric units, we default to meters.
|
('METRIC', 'LENGTH', "", "1+1ft", 1.3048), # no metric units, we default to meters.
|
||||||
('IMPERIAL', 'LENGTH', "", "3+1in+1ft", 0.3048 * 4 + 0.0254), # bigger unit becomes default one!
|
('IMPERIAL', 'LENGTH', "", "3+1in+1ft", 0.3048 * 4 + 0.0254), # bigger unit becomes default one!
|
||||||
('IMPERIAL', 'LENGTH', "", "(3+1)in+1ft", 0.3048 + 0.0254 * 4),
|
('IMPERIAL', 'LENGTH', "", "(3+1)in+1ft", 0.3048 + 0.0254 * 4),
|
||||||
)
|
)
|
||||||
@@ -31,18 +32,18 @@ class UnitsTesting(unittest.TestCase):
|
|||||||
# From 'internal' Blender value to user-friendly printing
|
# From 'internal' Blender value to user-friendly printing
|
||||||
OUTPUT_TESTS = (
|
OUTPUT_TESTS = (
|
||||||
# system, type, prec, sep, compat, value, output
|
# system, type, prec, sep, compat, value, output
|
||||||
##### LENGTH
|
# LENGTH
|
||||||
# Note: precision handling is a bit complicated when using multi-units...
|
# Note: precision handling is a bit complicated when using multi-units...
|
||||||
('IMPERIAL', 'LENGTH', 3, False, False, 0.3048, "1'"),
|
('IMPERIAL', 'LENGTH', 3, False, False, 0.3048, "1'"),
|
||||||
('IMPERIAL', 'LENGTH', 3, False, True, 0.3048, "1ft"),
|
('IMPERIAL', 'LENGTH', 3, False, True, 0.3048, "1ft"),
|
||||||
('IMPERIAL', 'LENGTH', 4, True, False, 0.3048 * 2 + 0.0254 * 5.5, "2' 5.5\""),
|
('IMPERIAL', 'LENGTH', 4, True, False, 0.3048 * 2 + 0.0254 * 5.5, "2' 5.5\""),
|
||||||
('IMPERIAL', 'LENGTH', 3, False, False, 1609.344 * 1e6, "1000000mi"),
|
('IMPERIAL', 'LENGTH', 3, False, False, 1609.344 * 1e6, "1000000mi"),
|
||||||
('IMPERIAL', 'LENGTH', 6, False, False, 1609.344 * 1e6, "1000000mi"),
|
('IMPERIAL', 'LENGTH', 6, False, False, 1609.344 * 1e6, "1000000mi"),
|
||||||
('METRIC', 'LENGTH', 3, True, False, 1000 * 2 + 0.001 * 15, "2km 2cm"),
|
('METRIC', 'LENGTH', 3, True, False, 1000 * 2 + 0.001 * 15, "2km 2cm"),
|
||||||
('METRIC', 'LENGTH', 5, True, False, 1234.56789, "1km 234.6m"),
|
('METRIC', 'LENGTH', 5, True, False, 1234.56789, "1km 234.6m"),
|
||||||
('METRIC', 'LENGTH', 6, True, False, 1234.56789, "1km 234.57m"),
|
('METRIC', 'LENGTH', 6, True, False, 1234.56789, "1km 234.57m"),
|
||||||
('METRIC', 'LENGTH', 9, False, False, 1234.56789, "1.234568km"),
|
('METRIC', 'LENGTH', 9, False, False, 1234.56789, "1.234568km"),
|
||||||
('METRIC', 'LENGTH', 9, True, False, 1000.000123456789, "1km 0.123mm"),
|
('METRIC', 'LENGTH', 9, True, False, 1000.000123456789, "1km 0.123mm"),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_units_inputs(self):
|
def test_units_inputs(self):
|
||||||
@@ -63,9 +64,13 @@ class UnitsTesting(unittest.TestCase):
|
|||||||
def test_units_outputs(self):
|
def test_units_outputs(self):
|
||||||
for usys, utype, prec, sep, compat, val, output in self.OUTPUT_TESTS:
|
for usys, utype, prec, sep, compat, val, output in self.OUTPUT_TESTS:
|
||||||
opt_str = units.to_string(usys, utype, val, prec, sep, compat)
|
opt_str = units.to_string(usys, utype, val, prec, sep, compat)
|
||||||
self.assertEqual(opt_str, output,
|
self.assertEqual(
|
||||||
msg="%s, %s: %f (precision: %d, separate units: %d, compat units: %d) => "
|
opt_str, output,
|
||||||
"\"%s\", expected \"%s\"" % (usys, utype, val, prec, sep, compat, 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__':
|
if __name__ == '__main__':
|
||||||
|
@@ -198,6 +198,7 @@ class TestBufferProtocol(TestHelper, unittest.TestCase):
|
|||||||
self.assertEqual(list(view1), list(view2))
|
self.assertEqual(list(view1), list(view2))
|
||||||
self.assertEqual(view1.tobytes(), view2.tobytes())
|
self.assertEqual(view1.tobytes(), view2.tobytes())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
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):
|
def get_scene(lib_name, sce_name):
|
||||||
for s in bpy.data.scenes:
|
for s in bpy.data.scenes:
|
||||||
if s.name == sce_name:
|
if s.name == sce_name:
|
||||||
if (s.library and s.library.name == lib_name) or \
|
if (
|
||||||
(lib_name == None and s.library == None):
|
(s.library and s.library.name == lib_name) or
|
||||||
|
(lib_name is None and s.library is None)
|
||||||
|
):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
@@ -309,6 +311,7 @@ def test_restrictions2():
|
|||||||
|
|
||||||
class TestUIList(UIList):
|
class TestUIList(UIList):
|
||||||
test = bpy.props.PointerProperty(type=bpy.types.Object)
|
test = bpy.props.PointerProperty(type=bpy.types.Object)
|
||||||
|
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||||
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
|
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
|
||||||
|
|
||||||
|
@@ -21,22 +21,22 @@ vector_data = (
|
|||||||
(-0.854645, 0.518036, 0.033936),
|
(-0.854645, 0.518036, 0.033936),
|
||||||
(0.42514, -0.437866, -0.792114),
|
(0.42514, -0.437866, -0.792114),
|
||||||
(-0.358948, 0.597046, 0.717377),
|
(-0.358948, 0.597046, 0.717377),
|
||||||
(-0.985413,0.144714, 0.089294),
|
(-0.985413, 0.144714, 0.089294),
|
||||||
)
|
)
|
||||||
|
|
||||||
# get data at different scales
|
# get data at different scales
|
||||||
vector_data = sum(
|
vector_data = sum(
|
||||||
(tuple(tuple(a * scale for a in v) for v in vector_data)
|
(tuple(tuple(a * scale for a in v) for v in vector_data)
|
||||||
for scale in (s * sign for s in (0.0001, 0.1, 1.0, 10.0, 1000.0, 100000.0)
|
for scale in (s * sign for s in (0.0001, 0.1, 1.0, 10.0, 1000.0, 100000.0)
|
||||||
for sign in (1.0, -1.0))), ()) + ((0.0, 0.0, 0.0),)
|
for sign in (1.0, -1.0))), ()) + ((0.0, 0.0, 0.0),)
|
||||||
|
|
||||||
|
|
||||||
class MatrixTesting(unittest.TestCase):
|
class MatrixTesting(unittest.TestCase):
|
||||||
def test_matrix_column_access(self):
|
def test_matrix_column_access(self):
|
||||||
#mat =
|
# mat =
|
||||||
#[ 1 2 3 4 ]
|
# [ 1 2 3 4 ]
|
||||||
#[ 1 2 3 4 ]
|
# [ 1 2 3 4 ]
|
||||||
#[ 1 2 3 4 ]
|
# [ 1 2 3 4 ]
|
||||||
mat = Matrix(((1, 11, 111),
|
mat = Matrix(((1, 11, 111),
|
||||||
(2, 22, 222),
|
(2, 22, 222),
|
||||||
(3, 33, 333),
|
(3, 33, 333),
|
||||||
@@ -81,11 +81,11 @@ class MatrixTesting(unittest.TestCase):
|
|||||||
self.assertIn(item, indices)
|
self.assertIn(item, indices)
|
||||||
|
|
||||||
def test_matrix_to_3x3(self):
|
def test_matrix_to_3x3(self):
|
||||||
#mat =
|
# mat =
|
||||||
#[ 1 2 3 4 ]
|
# [ 1 2 3 4 ]
|
||||||
#[ 2 4 6 8 ]
|
# [ 2 4 6 8 ]
|
||||||
#[ 3 6 9 12 ]
|
# [ 3 6 9 12 ]
|
||||||
#[ 4 8 12 16 ]
|
# [ 4 8 12 16 ]
|
||||||
mat = Matrix(tuple((i, 2 * i, 3 * i, 4 * i) for i in range(1, 5)))
|
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)))
|
mat_correct = Matrix(((1, 2, 3), (2, 4, 6), (3, 6, 9)))
|
||||||
self.assertEqual(mat.to_3x3(), mat_correct)
|
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)
|
ret_filter = k_all.find(co, lambda i: (i % 2) == 0)
|
||||||
self.assertAlmostEqualVector(ret_regular, ret_filter)
|
self.assertAlmostEqualVector(ret_regular, ret_filter)
|
||||||
|
|
||||||
|
|
||||||
# filter out all values (search odd tree for even values and the reverse)
|
# filter out all values (search odd tree for even values and the reverse)
|
||||||
co = (0,) * 3
|
co = (0,) * 3
|
||||||
ret_filter = k_odd.find(co, lambda i: (i % 2) == 0)
|
ret_filter = k_odd.find(co, lambda i: (i % 2) == 0)
|
||||||
|
@@ -8,7 +8,7 @@ DUMMY_NAME = "Untitled"
|
|||||||
DUMMY_PATH = __file__
|
DUMMY_PATH = __file__
|
||||||
GLOBALS = {
|
GLOBALS = {
|
||||||
"error_num": 0,
|
"error_num": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def as_float_32(f):
|
def as_float_32(f):
|
||||||
@@ -142,5 +142,6 @@ def main():
|
|||||||
|
|
||||||
print("Error (total): %d" % GLOBALS["error_num"])
|
print("Error (total): %d" % GLOBALS["error_num"])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -155,5 +155,6 @@ def main():
|
|||||||
test_language_coverage()
|
test_language_coverage()
|
||||||
test_urls()
|
test_urls()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -36,7 +36,7 @@ RANDOM_MULTIPLY = 10
|
|||||||
|
|
||||||
STATE = {
|
STATE = {
|
||||||
"counter": 0,
|
"counter": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
op_blacklist = (
|
op_blacklist = (
|
||||||
@@ -91,7 +91,7 @@ op_blacklist = (
|
|||||||
"wm.keymap_restore", # another annoying one
|
"wm.keymap_restore", # another annoying one
|
||||||
"wm.addon_*", # harmless, but dont change state
|
"wm.addon_*", # harmless, but dont change state
|
||||||
"console.*", # just annoying - but harmless
|
"console.*", # just annoying - but harmless
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def blend_list(mainpath):
|
def blend_list(mainpath):
|
||||||
@@ -114,6 +114,7 @@ def blend_list(mainpath):
|
|||||||
|
|
||||||
return list(sorted(file_list(mainpath, is_blend)))
|
return list(sorted(file_list(mainpath, is_blend)))
|
||||||
|
|
||||||
|
|
||||||
if USE_FILES:
|
if USE_FILES:
|
||||||
USE_FILES_LS = blend_list(USE_FILES)
|
USE_FILES_LS = blend_list(USE_FILES)
|
||||||
# print(USE_FILES_LS)
|
# print(USE_FILES_LS)
|
||||||
@@ -176,7 +177,7 @@ if USE_ATTRSET:
|
|||||||
CLS_BLACKLIST = (
|
CLS_BLACKLIST = (
|
||||||
bpy.types.BrushTextureSlot,
|
bpy.types.BrushTextureSlot,
|
||||||
bpy.types.Brush,
|
bpy.types.Brush,
|
||||||
)
|
)
|
||||||
property_typemap = build_property_typemap(CLS_BLACKLIST)
|
property_typemap = build_property_typemap(CLS_BLACKLIST)
|
||||||
bpy_struct_type = bpy.types.Struct.__base__
|
bpy_struct_type = bpy.types.Struct.__base__
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ if USE_ATTRSET:
|
|||||||
{0: "", 1: "hello", 2: "test"}, {"": 0, "hello": 1, "test": 2},
|
{0: "", 1: "hello", 2: "test"}, {"": 0, "hello": 1, "test": 2},
|
||||||
set(), {"", "test", "."}, {None, ..., type},
|
set(), {"", "test", "."}, {None, ..., type},
|
||||||
range(10), (" " * i for i in range(10)),
|
range(10), (" " * i for i in range(10)),
|
||||||
)
|
)
|
||||||
|
|
||||||
def attrset_data():
|
def attrset_data():
|
||||||
for attr in dir(bpy.data):
|
for attr in dir(bpy.data):
|
||||||
@@ -480,8 +481,9 @@ def main():
|
|||||||
|
|
||||||
print("Finished %r" % __file__)
|
print("Finished %r" % __file__)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
#~ for i in range(200):
|
# ~ for i in range(200):
|
||||||
#~ RANDOM_SEED[0] += 1
|
# ~ RANDOM_SEED[0] += 1
|
||||||
#~ main()
|
#~ main()
|
||||||
main()
|
main()
|
||||||
|
@@ -31,6 +31,7 @@ import difflib
|
|||||||
import pathlib
|
import pathlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def with_tempdir(wrapped):
|
def with_tempdir(wrapped):
|
||||||
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
||||||
|
|
||||||
@@ -56,8 +57,10 @@ def with_tempdir(wrapped):
|
|||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
LINE = "+----------------------------------------------------------------"
|
LINE = "+----------------------------------------------------------------"
|
||||||
|
|
||||||
|
|
||||||
class AbstractColladaTest(unittest.TestCase):
|
class AbstractColladaTest(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -71,33 +74,33 @@ class AbstractColladaTest(unittest.TestCase):
|
|||||||
|
|
||||||
ref = open(reference)
|
ref = open(reference)
|
||||||
exp = open(export)
|
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()
|
ref.close()
|
||||||
exp.close()
|
exp.close()
|
||||||
|
|
||||||
diff_count = 0;
|
diff_count = 0
|
||||||
for line in diff:
|
for line in diff:
|
||||||
error = True
|
error = True
|
||||||
for prefix in ('---', '+++', '@@'):
|
for prefix in ('---', '+++', '@@'):
|
||||||
# Ignore diff metadata
|
# Ignore diff metadata
|
||||||
if line.startswith(prefix):
|
if line.startswith(prefix):
|
||||||
error=False
|
error = False
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# Ignore time stamps
|
# Ignore time stamps
|
||||||
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
||||||
if line[1:].strip().startswith(ignore):
|
if line[1:].strip().startswith(ignore):
|
||||||
error=False
|
error = False
|
||||||
break
|
break
|
||||||
if error:
|
if error:
|
||||||
diff_count +=1
|
diff_count += 1
|
||||||
pline = line.strip()
|
pline = line.strip()
|
||||||
if diff_count == 1:
|
if diff_count == 1:
|
||||||
print("\n%s" % LINE)
|
print("\n%s" % LINE)
|
||||||
print("|Test has errors:")
|
print("|Test has errors:")
|
||||||
print(LINE)
|
print(LINE)
|
||||||
pre = "reference" if pline[0] == "-" else "generated"
|
pre = "reference" if pline[0] == "-" else "generated"
|
||||||
print ("| %s:%s"% (pre, pline[1:]))
|
print("| %s:%s" % (pre, pline[1:]))
|
||||||
|
|
||||||
if diff_count > 0:
|
if diff_count > 0:
|
||||||
print(LINE)
|
print(LINE)
|
||||||
@@ -107,14 +110,16 @@ class AbstractColladaTest(unittest.TestCase):
|
|||||||
|
|
||||||
return diff_count == 0
|
return diff_count == 0
|
||||||
|
|
||||||
|
|
||||||
class MeshExportTest4(AbstractColladaTest):
|
class MeshExportTest4(AbstractColladaTest):
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_export_animation_suzannes_sample_matrix(self, tempdir: pathlib.Path):
|
def test_export_animation_suzannes_sample_matrix(self, tempdir: pathlib.Path):
|
||||||
test = "suzannes_parent_inverse_sample_10_matrix"
|
test = "suzannes_parent_inverse_sample_10_matrix"
|
||||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||||
outfile = tempdir / Path("%s_out.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,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
@@ -142,20 +147,23 @@ class MeshExportTest4(AbstractColladaTest):
|
|||||||
export_texture_type_selection='mat',
|
export_texture_type_selection='mat',
|
||||||
open_sim=False,
|
open_sim=False,
|
||||||
limit_precision=True,
|
limit_precision=True,
|
||||||
keep_bind_info=False)
|
keep_bind_info=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Now check the resulting Collada file.
|
# Now check the resulting Collada file.
|
||||||
if not self.checkdae(reference_dae, outfile):
|
if not self.checkdae(reference_dae, outfile):
|
||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
|
|
||||||
class MeshExportTest3(AbstractColladaTest):
|
class MeshExportTest3(AbstractColladaTest):
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_export_animation_suzannes_sample_locrotscale(self, tempdir: pathlib.Path):
|
def test_export_animation_suzannes_sample_locrotscale(self, tempdir: pathlib.Path):
|
||||||
test = "suzannes_parent_inverse_sample_10_channels"
|
test = "suzannes_parent_inverse_sample_10_channels"
|
||||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||||
outfile = tempdir / Path("%s_out.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,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
@@ -183,20 +191,23 @@ class MeshExportTest3(AbstractColladaTest):
|
|||||||
export_texture_type_selection='mat',
|
export_texture_type_selection='mat',
|
||||||
open_sim=False,
|
open_sim=False,
|
||||||
limit_precision=True,
|
limit_precision=True,
|
||||||
keep_bind_info=False)
|
keep_bind_info=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Now check the resulting Collada file.
|
# Now check the resulting Collada file.
|
||||||
if not self.checkdae(reference_dae, outfile):
|
if not self.checkdae(reference_dae, outfile):
|
||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
|
|
||||||
class MeshExportTest2(AbstractColladaTest):
|
class MeshExportTest2(AbstractColladaTest):
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_export_animation_suzannes_keyframe_matrix(self, tempdir: pathlib.Path):
|
def test_export_animation_suzannes_keyframe_matrix(self, tempdir: pathlib.Path):
|
||||||
test = "suzannes_parent_inverse_keyframes_matrix"
|
test = "suzannes_parent_inverse_keyframes_matrix"
|
||||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||||
outfile = tempdir / Path("%s_out.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,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
@@ -224,20 +235,23 @@ class MeshExportTest2(AbstractColladaTest):
|
|||||||
export_texture_type_selection='mat',
|
export_texture_type_selection='mat',
|
||||||
open_sim=False,
|
open_sim=False,
|
||||||
limit_precision=True,
|
limit_precision=True,
|
||||||
keep_bind_info=False)
|
keep_bind_info=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Now check the resulting Collada file.
|
# Now check the resulting Collada file.
|
||||||
if not self.checkdae(reference_dae, outfile):
|
if not self.checkdae(reference_dae, outfile):
|
||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
|
|
||||||
class MeshExportTest1(AbstractColladaTest):
|
class MeshExportTest1(AbstractColladaTest):
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_export_animation_suzannes_keyframe_locrotscale(self, tempdir: pathlib.Path):
|
def test_export_animation_suzannes_keyframe_locrotscale(self, tempdir: pathlib.Path):
|
||||||
test = "suzannes_parent_inverse_keyframes_channels"
|
test = "suzannes_parent_inverse_keyframes_channels"
|
||||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||||
outfile = tempdir / Path("%s_out.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,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type='DEFAULT',
|
display_type='DEFAULT',
|
||||||
@@ -265,7 +279,8 @@ class MeshExportTest1(AbstractColladaTest):
|
|||||||
export_texture_type_selection='mat',
|
export_texture_type_selection='mat',
|
||||||
open_sim=False,
|
open_sim=False,
|
||||||
limit_precision=True,
|
limit_precision=True,
|
||||||
keep_bind_info=False)
|
keep_bind_info=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Now check the resulting Collada file.
|
# Now check the resulting Collada file.
|
||||||
if not self.checkdae(reference_dae, outfile):
|
if not self.checkdae(reference_dae, outfile):
|
||||||
@@ -277,4 +292,4 @@ if __name__ == '__main__':
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--testdir', required=True)
|
parser.add_argument('--testdir', required=True)
|
||||||
args, remaining = parser.parse_known_args()
|
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
|
import pathlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def with_tempdir(wrapped):
|
def with_tempdir(wrapped):
|
||||||
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
"""Creates a temporary directory for the function, cleaning up after it returns normally.
|
||||||
|
|
||||||
@@ -56,8 +57,10 @@ def with_tempdir(wrapped):
|
|||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
LINE = "+----------------------------------------------------------------"
|
LINE = "+----------------------------------------------------------------"
|
||||||
|
|
||||||
|
|
||||||
class AbstractColladaTest(unittest.TestCase):
|
class AbstractColladaTest(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -71,33 +74,33 @@ class AbstractColladaTest(unittest.TestCase):
|
|||||||
|
|
||||||
ref = open(reference)
|
ref = open(reference)
|
||||||
exp = open(export)
|
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()
|
ref.close()
|
||||||
exp.close()
|
exp.close()
|
||||||
|
|
||||||
diff_count = 0;
|
diff_count = 0
|
||||||
for line in diff:
|
for line in diff:
|
||||||
error = True
|
error = True
|
||||||
for prefix in ('---', '+++', '@@'):
|
for prefix in ('---', '+++', '@@'):
|
||||||
# Ignore diff metadata
|
# Ignore diff metadata
|
||||||
if line.startswith(prefix):
|
if line.startswith(prefix):
|
||||||
error=False
|
error = False
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# Ignore time stamps
|
# Ignore time stamps
|
||||||
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
for ignore in ('<created>', '<modified>', '<authoring_tool>'):
|
||||||
if line[1:].strip().startswith(ignore):
|
if line[1:].strip().startswith(ignore):
|
||||||
error=False
|
error = False
|
||||||
break
|
break
|
||||||
if error:
|
if error:
|
||||||
diff_count +=1
|
diff_count += 1
|
||||||
pline = line.strip()
|
pline = line.strip()
|
||||||
if diff_count == 1:
|
if diff_count == 1:
|
||||||
print("\n%s" % LINE)
|
print("\n%s" % LINE)
|
||||||
print("|Test has errors:")
|
print("|Test has errors:")
|
||||||
print(LINE)
|
print(LINE)
|
||||||
pre = "reference" if pline[0] == "-" else "generated"
|
pre = "reference" if pline[0] == "-" else "generated"
|
||||||
print ("| %s:%s"% (pre, pline[1:]))
|
print("| %s:%s" % (pre, pline[1:]))
|
||||||
|
|
||||||
if diff_count > 0:
|
if diff_count > 0:
|
||||||
print(LINE)
|
print(LINE)
|
||||||
@@ -107,14 +110,16 @@ class AbstractColladaTest(unittest.TestCase):
|
|||||||
|
|
||||||
return diff_count == 0
|
return diff_count == 0
|
||||||
|
|
||||||
|
|
||||||
class MeshExportTest(AbstractColladaTest):
|
class MeshExportTest(AbstractColladaTest):
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_export_single_mesh(self, tempdir: pathlib.Path):
|
def test_export_single_mesh(self, tempdir: pathlib.Path):
|
||||||
test = "mesh_simple_001"
|
test = "mesh_simple_001"
|
||||||
reference_dae = self.testdir / Path("%s.dae" % test)
|
reference_dae = self.testdir / Path("%s.dae" % test)
|
||||||
outfile = tempdir / Path("%s_out.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,
|
check_existing=True,
|
||||||
filemode=8,
|
filemode=8,
|
||||||
display_type="DEFAULT",
|
display_type="DEFAULT",
|
||||||
@@ -140,15 +145,17 @@ class MeshExportTest(AbstractColladaTest):
|
|||||||
export_texture_type_selection="mat",
|
export_texture_type_selection="mat",
|
||||||
open_sim=False,
|
open_sim=False,
|
||||||
limit_precision=False,
|
limit_precision=False,
|
||||||
keep_bind_info=False)
|
keep_bind_info=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Now check the resulting Collada file.
|
# Now check the resulting Collada file.
|
||||||
if not self.checkdae(reference_dae, outfile):
|
if not self.checkdae(reference_dae, outfile):
|
||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--testdir', required=True)
|
parser.add_argument('--testdir', required=True)
|
||||||
args, remaining = parser.parse_known_args()
|
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 = ''
|
GREEN = ''
|
||||||
ENDC = ''
|
ENDC = ''
|
||||||
|
|
||||||
|
|
||||||
COLORS = COLORS_DUMMY
|
COLORS = COLORS_DUMMY
|
||||||
|
|
||||||
|
|
||||||
@@ -55,10 +56,12 @@ def blend_list(dirpath):
|
|||||||
filepath = os.path.join(dirpath, filename)
|
filepath = os.path.join(dirpath, filename)
|
||||||
yield filepath
|
yield filepath
|
||||||
|
|
||||||
|
|
||||||
def test_get_name(filepath):
|
def test_get_name(filepath):
|
||||||
filename = os.path.basename(filepath)
|
filename = os.path.basename(filepath)
|
||||||
return os.path.splitext(filename)[0]
|
return os.path.splitext(filename)[0]
|
||||||
|
|
||||||
|
|
||||||
def test_get_images(output_dir, filepath):
|
def test_get_images(output_dir, filepath):
|
||||||
testname = test_get_name(filepath)
|
testname = test_get_name(filepath)
|
||||||
dirpath = os.path.dirname(filepath)
|
dirpath = os.path.dirname(filepath)
|
||||||
@@ -96,7 +99,7 @@ class Report:
|
|||||||
'update',
|
'update',
|
||||||
'failed_tests',
|
'failed_tests',
|
||||||
'passed_tests'
|
'passed_tests'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, title, output_dir, idiff):
|
def __init__(self, title, output_dir, idiff):
|
||||||
self.title = title
|
self.title = title
|
||||||
@@ -257,7 +260,6 @@ class Report:
|
|||||||
else:
|
else:
|
||||||
self.passed_tests += test_html
|
self.passed_tests += test_html
|
||||||
|
|
||||||
|
|
||||||
def _diff_output(self, filepath, tmp_filepath):
|
def _diff_output(self, filepath, tmp_filepath):
|
||||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath)
|
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath)
|
||||||
|
|
||||||
@@ -280,7 +282,7 @@ class Report:
|
|||||||
"-failpercent", "1",
|
"-failpercent", "1",
|
||||||
ref_img,
|
ref_img,
|
||||||
tmp_filepath,
|
tmp_filepath,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(command)
|
subprocess.check_output(command)
|
||||||
failed = False
|
failed = False
|
||||||
@@ -307,7 +309,7 @@ class Report:
|
|||||||
"-abs", "-scale", "16",
|
"-abs", "-scale", "16",
|
||||||
ref_img,
|
ref_img,
|
||||||
tmp_filepath
|
tmp_filepath
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(command)
|
subprocess.check_output(command)
|
||||||
@@ -317,7 +319,6 @@ class Report:
|
|||||||
|
|
||||||
return not failed
|
return not failed
|
||||||
|
|
||||||
|
|
||||||
def _run_test(self, filepath, render_cb):
|
def _run_test(self, filepath, render_cb):
|
||||||
testname = test_get_name(filepath)
|
testname = test_get_name(filepath)
|
||||||
print_message(testname, 'SUCCESS', 'RUN')
|
print_message(testname, 'SUCCESS', 'RUN')
|
||||||
@@ -344,7 +345,7 @@ class Report:
|
|||||||
return error
|
return error
|
||||||
elif error == "NO_START":
|
elif error == "NO_START":
|
||||||
print_message('Can not perform tests because blender fails to start.',
|
print_message('Can not perform tests because blender fails to start.',
|
||||||
'Make sure INSTALL target was run.')
|
'Make sure INSTALL target was run.')
|
||||||
return error
|
return error
|
||||||
elif error == 'VERIFY':
|
elif error == 'VERIFY':
|
||||||
print_message("Rendered result is different from reference image")
|
print_message("Rendered result is different from reference image")
|
||||||
@@ -354,7 +355,6 @@ class Report:
|
|||||||
'FAILURE', 'FAILED')
|
'FAILURE', 'FAILED')
|
||||||
return error
|
return error
|
||||||
|
|
||||||
|
|
||||||
def _run_all_tests(self, dirname, dirpath, render_cb):
|
def _run_all_tests(self, dirname, dirpath, render_cb):
|
||||||
passed_tests = []
|
passed_tests = []
|
||||||
failed_tests = []
|
failed_tests = []
|
||||||
@@ -387,8 +387,8 @@ class Report:
|
|||||||
'SUCCESS', 'PASSED')
|
'SUCCESS', 'PASSED')
|
||||||
if failed_tests:
|
if failed_tests:
|
||||||
print_message("{} tests, listed below:" .
|
print_message("{} tests, listed below:" .
|
||||||
format(len(failed_tests)),
|
format(len(failed_tests)),
|
||||||
'FAILURE', 'FAILED')
|
'FAILURE', 'FAILED')
|
||||||
failed_tests.sort()
|
failed_tests.sort()
|
||||||
for test in failed_tests:
|
for test in failed_tests:
|
||||||
print_message("{}" . format(test), 'FAILURE', "FAILED")
|
print_message("{}" . format(test), 'FAILURE', "FAILED")
|
||||||
|
@@ -62,7 +62,6 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
|
|||||||
blender: pathlib.Path = None
|
blender: pathlib.Path = None
|
||||||
testdir: pathlib.Path = None
|
testdir: pathlib.Path = None
|
||||||
|
|
||||||
|
|
||||||
def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str:
|
def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str:
|
||||||
"""Runs Blender by opening a blendfile and executing a script.
|
"""Runs Blender by opening a blendfile and executing a script.
|
||||||
|
|
||||||
@@ -92,7 +91,7 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
|
|||||||
'-E', 'CYCLES',
|
'-E', 'CYCLES',
|
||||||
'--python-exit-code', '47',
|
'--python-exit-code', '47',
|
||||||
'--python-expr', python_script,
|
'--python-expr', python_script,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||||
|
@@ -8,6 +8,7 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def screenshot():
|
def screenshot():
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ def screenshot():
|
|||||||
|
|
||||||
bpy.ops.wm.quit_blender()
|
bpy.ops.wm.quit_blender()
|
||||||
|
|
||||||
|
|
||||||
# When run from inside Blender, take screenshot and exit.
|
# When run from inside Blender, take screenshot and exit.
|
||||||
try:
|
try:
|
||||||
import bpy
|
import bpy
|
||||||
@@ -93,5 +95,6 @@ def main():
|
|||||||
|
|
||||||
sys.exit(not ok)
|
sys.exit(not ok)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -93,7 +93,7 @@ def check_files_flake8(files):
|
|||||||
# times types are compared,
|
# times types are compared,
|
||||||
# I rather keep them specific
|
# I rather keep them specific
|
||||||
"E721",
|
"E721",
|
||||||
)
|
)
|
||||||
|
|
||||||
for f, pep8_type in files:
|
for f, pep8_type in files:
|
||||||
|
|
||||||
@@ -129,10 +129,10 @@ def check_files_pylint(files):
|
|||||||
"C0413," # import should be placed at the top
|
"C0413," # import should be placed at the top
|
||||||
"W0613," # unused argument, may add this back
|
"W0613," # unused argument, may add this back
|
||||||
# but happens a lot for 'context' for eg.
|
# but happens a lot for 'context' for eg.
|
||||||
"W0232," # class has no __init__, Operator/Panel/Menu etc
|
"W0232," # class has no __init__, Operator/Panel/Menu etc
|
||||||
"W0142," # Used * or ** magic
|
"W0142," # Used * or ** magic
|
||||||
# even needed in some cases
|
# even needed in some cases
|
||||||
"R0902," # Too many instance attributes
|
"R0902," # Too many instance attributes
|
||||||
"R0903," # Too many statements
|
"R0903," # Too many statements
|
||||||
"R0911," # Too many return statements
|
"R0911," # Too many return statements
|
||||||
"R0912," # Too many branches
|
"R0912," # Too many branches
|
||||||
@@ -204,6 +204,5 @@ def main():
|
|||||||
print("Skipping pylint checks (command not found)")
|
print("Skipping pylint checks (command not found)")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import random
|
import random
|
||||||
|
|
||||||
test= bpy.data.test
|
test = bpy.data.test
|
||||||
|
|
||||||
# farr - 1-dimensional array of float
|
# farr - 1-dimensional array of float
|
||||||
# fdarr - dynamic 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
|
# same as above for other types except that the first letter is "i" for int and "b" for bool
|
||||||
|
|
||||||
|
|
||||||
class TestArray(unittest.TestCase):
|
class TestArray(unittest.TestCase):
|
||||||
# test that assignment works by: assign -> test value
|
# test that assignment works by: assign -> test value
|
||||||
# - rvalue = list of float
|
# - rvalue = list of float
|
||||||
@@ -20,14 +21,14 @@ class TestArray(unittest.TestCase):
|
|||||||
# bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr
|
# bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
test.farr= (1.0, 2.0, 3.0)
|
test.farr = (1.0, 2.0, 3.0)
|
||||||
test.iarr= (7, 8, 9)
|
test.iarr = (7, 8, 9)
|
||||||
test.barr= (False, True, False)
|
test.barr = (False, True, False)
|
||||||
|
|
||||||
# test access
|
# test access
|
||||||
# test slice access, negative indices
|
# test slice access, negative indices
|
||||||
def test_access(self):
|
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):
|
for arr, rval in zip((test.farr, test.iarr, test.barr), rvals):
|
||||||
self.assertEqual(prop_to_list(arr), rval)
|
self.assertEqual(prop_to_list(arr), rval)
|
||||||
self.assertEqual(arr[0:3], rval)
|
self.assertEqual(arr[0:3], rval)
|
||||||
@@ -39,12 +40,12 @@ class TestArray(unittest.TestCase):
|
|||||||
# fail when index out of bounds
|
# fail when index out of bounds
|
||||||
def test_access_fail(self):
|
def test_access_fail(self):
|
||||||
for arr in (test.farr, test.iarr, test.barr):
|
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
|
# test assignment of a whole array
|
||||||
def test_assign_array(self):
|
def test_assign_array(self):
|
||||||
# should accept int as float
|
# should accept int as float
|
||||||
test.farr= (1, 2, 3)
|
test.farr = (1, 2, 3)
|
||||||
|
|
||||||
# fail when: unexpected no. of items, invalid item type
|
# fail when: unexpected no. of items, invalid item type
|
||||||
def test_assign_array_fail(self):
|
def test_assign_array_fail(self):
|
||||||
@@ -55,20 +56,20 @@ class TestArray(unittest.TestCase):
|
|||||||
self.assertRaises(ValueError, assign_empty_list, arr)
|
self.assertRaises(ValueError, assign_empty_list, arr)
|
||||||
|
|
||||||
def assign_invalid_float():
|
def assign_invalid_float():
|
||||||
test.farr= (1.0, 2.0, "3.0")
|
test.farr = (1.0, 2.0, "3.0")
|
||||||
|
|
||||||
def assign_invalid_int():
|
def assign_invalid_int():
|
||||||
test.iarr= ("1", 2, 3)
|
test.iarr = ("1", 2, 3)
|
||||||
|
|
||||||
def assign_invalid_bool():
|
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]:
|
for func in [assign_invalid_float, assign_invalid_int, assign_invalid_bool]:
|
||||||
self.assertRaises(TypeError, func)
|
self.assertRaises(TypeError, func)
|
||||||
|
|
||||||
# shouldn't accept float as int
|
# shouldn't accept float as int
|
||||||
def assign_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)
|
self.assertRaises(TypeError, assign_float_as_int)
|
||||||
|
|
||||||
# non-dynamic arrays cannot change size
|
# non-dynamic arrays cannot change size
|
||||||
@@ -81,14 +82,14 @@ class TestArray(unittest.TestCase):
|
|||||||
def test_assign_item(self):
|
def test_assign_item(self):
|
||||||
for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)):
|
for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)):
|
||||||
for i in range(len(arr)):
|
for i in range(len(arr)):
|
||||||
val= rand_func()
|
val = rand_func()
|
||||||
arr[i] = val
|
arr[i] = val
|
||||||
|
|
||||||
self.assertEqual(arr[i], val)
|
self.assertEqual(arr[i], val)
|
||||||
|
|
||||||
# float prop should accept also int
|
# float prop should accept also int
|
||||||
for i in range(len(test.farr)):
|
for i in range(len(test.farr)):
|
||||||
val= rand_int()
|
val = rand_int()
|
||||||
test.farr[i] = val
|
test.farr[i] = val
|
||||||
self.assertEqual(test.farr[i], float(val))
|
self.assertEqual(test.farr[i], float(val))
|
||||||
|
|
||||||
@@ -112,7 +113,7 @@ class TestArray(unittest.TestCase):
|
|||||||
# test various lengths here
|
# test various lengths here
|
||||||
for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)):
|
for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)):
|
||||||
for length in range(1, 64):
|
for length in range(1, 64):
|
||||||
rval= make_random_array(length, rand_func)
|
rval = make_random_array(length, rand_func)
|
||||||
setattr(test, arr, rval)
|
setattr(test, arr, rval)
|
||||||
self.assertEqual(prop_to_list(getattr(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):
|
def test_assign_array(self):
|
||||||
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
||||||
# assignment of [3][4][5]
|
# 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)
|
setattr(test, arr, rval)
|
||||||
self.assertEqual(prop_to_list(getattr(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 test_assign_array_fail(self):
|
||||||
def assign_empty_array():
|
def assign_empty_array():
|
||||||
test.fmarr= ()
|
test.fmarr = ()
|
||||||
self.assertRaises(ValueError, assign_empty_array)
|
self.assertRaises(ValueError, assign_empty_array)
|
||||||
|
|
||||||
def assign_invalid_size(arr, rval):
|
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
|
# 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)):
|
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)
|
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)
|
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)
|
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
|
||||||
|
|
||||||
def test_assign_item(self):
|
def test_assign_item(self):
|
||||||
# arr[i] = x
|
# arr[i] = x
|
||||||
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
|
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):
|
for i in range(3):
|
||||||
getattr(test, arr)[i] = rval
|
getattr(test, arr)[i] = rval
|
||||||
@@ -173,23 +174,22 @@ class TestMArray(unittest.TestCase):
|
|||||||
# arr[i][j] = x
|
# arr[i][j] = x
|
||||||
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
|
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
|
||||||
|
|
||||||
arr= getattr(test, arr)
|
arr = getattr(test, arr)
|
||||||
rval= make_random_array(5, func)
|
rval = make_random_array(5, func)
|
||||||
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
for j in range(4):
|
for j in range(4):
|
||||||
arr[i][j] = rval
|
arr[i][j] = rval
|
||||||
self.assertEqual(prop_to_list(arr[i][j]), rval)
|
self.assertEqual(prop_to_list(arr[i][j]), rval)
|
||||||
|
|
||||||
|
|
||||||
def test_assign_item_fail(self):
|
def test_assign_item_fail(self):
|
||||||
def assign_wrong_size(arr, i, rval):
|
def assign_wrong_size(arr, i, rval):
|
||||||
getattr(test, arr)[i] = rval
|
getattr(test, arr)[i] = rval
|
||||||
|
|
||||||
# assign wrong size at level 2
|
# assign wrong size at level 2
|
||||||
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
|
||||||
rval1= make_random_2d_array((3, 5), func)
|
rval1 = make_random_2d_array((3, 5), func)
|
||||||
rval2= make_random_2d_array((4, 3), func)
|
rval2 = make_random_2d_array((4, 3), func)
|
||||||
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1)
|
self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1)
|
||||||
@@ -198,22 +198,22 @@ class TestMArray(unittest.TestCase):
|
|||||||
def test_dynamic_assign_array(self):
|
def test_dynamic_assign_array(self):
|
||||||
for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
|
for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
|
||||||
# assignment of [3][4][5]
|
# 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)
|
setattr(test, arr, rval)
|
||||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||||
|
|
||||||
# [2][4][5]
|
# [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)
|
setattr(test, arr, rval)
|
||||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||||
|
|
||||||
# [1][4][5]
|
# [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)
|
setattr(test, arr, rval)
|
||||||
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
|
||||||
|
|
||||||
|
|
||||||
# test access
|
# test access
|
||||||
|
|
||||||
def test_access(self):
|
def test_access(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -221,26 +221,32 @@ class TestMArray(unittest.TestCase):
|
|||||||
def test_access_fail(self):
|
def test_access_fail(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
random.seed()
|
random.seed()
|
||||||
|
|
||||||
|
|
||||||
def rand_int():
|
def rand_int():
|
||||||
return random.randint(-1000, 1000)
|
return random.randint(-1000, 1000)
|
||||||
|
|
||||||
|
|
||||||
def rand_float():
|
def rand_float():
|
||||||
return float(rand_int())
|
return float(rand_int())
|
||||||
|
|
||||||
|
|
||||||
def rand_bool():
|
def rand_bool():
|
||||||
return bool(random.randint(0, 1))
|
return bool(random.randint(0, 1))
|
||||||
|
|
||||||
|
|
||||||
def make_random_array(len, rand_func):
|
def make_random_array(len, rand_func):
|
||||||
arr= []
|
arr = []
|
||||||
for i in range(len):
|
for i in range(len):
|
||||||
arr.append(rand_func())
|
arr.append(rand_func())
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
|
|
||||||
def make_random_2d_array(dimsize, rand_func):
|
def make_random_2d_array(dimsize, rand_func):
|
||||||
marr= []
|
marr = []
|
||||||
for i in range(dimsize[0]):
|
for i in range(dimsize[0]):
|
||||||
marr.append([])
|
marr.append([])
|
||||||
|
|
||||||
@@ -249,8 +255,9 @@ def make_random_2d_array(dimsize, rand_func):
|
|||||||
|
|
||||||
return marr
|
return marr
|
||||||
|
|
||||||
|
|
||||||
def make_random_3d_array(dimsize, rand_func):
|
def make_random_3d_array(dimsize, rand_func):
|
||||||
marr= []
|
marr = []
|
||||||
for i in range(dimsize[0]):
|
for i in range(dimsize[0]):
|
||||||
marr.append([])
|
marr.append([])
|
||||||
|
|
||||||
@@ -262,8 +269,9 @@ def make_random_3d_array(dimsize, rand_func):
|
|||||||
|
|
||||||
return marr
|
return marr
|
||||||
|
|
||||||
|
|
||||||
def prop_to_list(prop):
|
def prop_to_list(prop):
|
||||||
ret= []
|
ret = []
|
||||||
|
|
||||||
for x in prop:
|
for x in prop:
|
||||||
if type(x) not in {bool, int, float}:
|
if type(x) not in {bool, int, float}:
|
||||||
@@ -273,8 +281,10 @@ def prop_to_list(prop):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)])
|
return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
unittest.TextTestRunner(verbosity=2).run(suite())
|
||||||
|
Reference in New Issue
Block a user