Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-06-18 15:44:40 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-06-18 16:03:46 +0400
commit0eb060c7b4fb3a85b14c9efca85a7a361640a95e (patch)
tree87e50d4913eb210f7d8aa6ab2f62136e42aa6c11 /tests/python/bl_mesh_modifiers.py
parent7259ac821ea73bdde3add0390dfc1137f619bc9a (diff)
Move tests into tests/ top-level dir
Diffstat (limited to 'tests/python/bl_mesh_modifiers.py')
-rw-r--r--tests/python/bl_mesh_modifiers.py866
1 files changed, 866 insertions, 0 deletions
diff --git a/tests/python/bl_mesh_modifiers.py b/tests/python/bl_mesh_modifiers.py
new file mode 100644
index 00000000000..b3f77aed96b
--- /dev/null
+++ b/tests/python/bl_mesh_modifiers.py
@@ -0,0 +1,866 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# Currently this script only generates images from different modifier
+# combinations and does not validate they work correctly,
+# this is because we don't get 1:1 match with bmesh.
+#
+# Later, we may have a way to check the results are valid.
+
+
+# ./blender.bin --factory-startup --python tests/python/bl_mesh_modifiers.py
+#
+
+import math
+
+USE_QUICK_RENDER = False
+IS_BMESH = hasattr(__import__("bpy").types, "LoopColors")
+
+# -----------------------------------------------------------------------------
+# utility functions
+
+
+def render_gl(context, filepath, shade):
+
+ def ctx_viewport_shade(context, shade):
+ for area in context.window.screen.areas:
+ if area.type == 'VIEW_3D':
+ space = area.spaces.active
+ # rv3d = space.region_3d
+ space.viewport_shade = shade
+
+ import bpy
+ scene = context.scene
+ render = scene.render
+ render.filepath = filepath
+ render.image_settings.file_format = 'PNG'
+ render.image_settings.color_mode = 'RGB'
+ render.use_file_extension = True
+ render.use_antialiasing = False
+
+ # render size
+ render.resolution_percentage = 100
+ render.resolution_x = 512
+ render.resolution_y = 512
+
+ ctx_viewport_shade(context, shade)
+
+ #~ # stop to inspect!
+ #~ if filepath == "test_cube_shell_solidify_subsurf_wp_wire":
+ #~ assert(0)
+ #~ else:
+ #~ return
+
+ bpy.ops.render.opengl(write_still=True,
+ view_context=True)
+
+
+def render_gl_all_modes(context, obj, filepath=""):
+
+ assert(obj is not None)
+ assert(filepath != "")
+
+ scene = context.scene
+
+ # avoid drawing outline/center dot
+ bpy.ops.object.select_all(action='DESELECT')
+ scene.objects.active = None
+
+ # editmode
+ scene.tool_settings.mesh_select_mode = False, True, False
+
+ # render
+ render_gl(context, filepath + "_ob_solid", shade='SOLID')
+
+ if USE_QUICK_RENDER:
+ return
+
+ render_gl(context, filepath + "_ob_wire", shade='WIREFRAME')
+ render_gl(context, filepath + "_ob_textured", shade='TEXTURED')
+
+ # -------------------------------------------------------------------------
+ # not just draw modes, but object modes!
+ scene.objects.active = obj
+
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ render_gl(context, filepath + "_edit_wire", shade='WIREFRAME')
+ render_gl(context, filepath + "_edit_solid", shade='SOLID')
+ render_gl(context, filepath + "_edit_textured", shade='TEXTURED')
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False)
+
+ render_gl(context, filepath + "_wp_wire", shade='WIREFRAME')
+
+ assert(1)
+
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ scene.objects.active = None
+
+
+def ctx_clear_scene(): # copied from batch_import.py
+ import bpy
+ unique_obs = set()
+ for scene in bpy.data.scenes:
+ for obj in scene.objects[:]:
+ scene.objects.unlink(obj)
+ unique_obs.add(obj)
+
+ # remove obdata, for now only worry about the startup scene
+ for bpy_data_iter in (bpy.data.objects,
+ bpy.data.meshes,
+ bpy.data.lamps,
+ bpy.data.cameras,
+ ):
+
+ for id_data in bpy_data_iter:
+ bpy_data_iter.remove(id_data)
+
+
+def ctx_viewport_camera(context):
+ # because gl render without view_context has no shading option.
+ for area in context.window.screen.areas:
+ if area.type == 'VIEW_3D':
+ space = area.spaces.active
+ space.region_3d.view_perspective = 'CAMERA'
+
+
+def ctx_camera_setup(context,
+ location=(0.0, 0.0, 0.0),
+ lookat=(0.0, 0.0, 0.0),
+ # most likely the following vars can be left as defaults
+ up=(0.0, 0.0, 1.0),
+ lookat_axis='-Z',
+ up_axis='Y',
+ ):
+
+ camera = bpy.data.cameras.new(whoami())
+ obj = bpy.data.objects.new(whoami(), camera)
+
+ scene = context.scene
+ scene.objects.link(obj)
+ scene.camera = obj
+
+ from mathutils import Vector, Matrix
+
+ # setup transform
+ view_vec = Vector(lookat) - Vector(location)
+ rot_mat = view_vec.to_track_quat(lookat_axis, up_axis).to_matrix().to_4x4()
+ tra_mat = Matrix.Translation(location)
+
+ obj.matrix_world = tra_mat * rot_mat
+
+ ctx_viewport_camera(context)
+
+ return obj
+
+
+# -----------------------------------------------------------------------------
+# inspect functions
+
+import inspect
+
+
+# functions
+
+def whoami():
+ return inspect.stack()[1][3]
+
+
+def whosdaddy():
+ return inspect.stack()[2][3]
+
+
+# -----------------------------------------------------------------------------
+# models (defaults)
+
+def defaults_object(obj):
+ obj.show_wire = True
+
+ if obj.type == 'MESH':
+ mesh = obj.data
+ mesh.show_all_edges = True
+
+ mesh.show_normal_vertex = True
+
+ # lame!
+ if IS_BMESH:
+ for poly in mesh.polygons:
+ poly.use_smooth = True
+ else:
+ for face in mesh.faces:
+ face.use_smooth = True
+
+
+def defaults_modifier(mod):
+ mod.show_in_editmode = True
+ mod.show_on_cage = True
+
+
+# -----------------------------------------------------------------------------
+# models (utils)
+
+
+if IS_BMESH:
+ def mesh_bmesh_poly_elems(poly, elems):
+ vert_start = poly.loop_start
+ vert_total = poly.loop_total
+ return elems[vert_start:vert_start + vert_total]
+
+ def mesh_bmesh_poly_vertices(poly):
+ return [loop.vertex_index
+ for loop in mesh_bmesh_poly_elems(poly, poly.id_data.loops)]
+
+
+def mesh_bounds(mesh):
+ xmin = ymin = zmin = +100000000.0
+ xmax = ymax = zmax = -100000000.0
+
+ for v in mesh.vertices:
+ x, y, z = v.co
+ xmax = max(x, xmax)
+ ymax = max(y, ymax)
+ zmax = max(z, zmax)
+
+ xmin = min(x, xmin)
+ ymin = min(y, ymin)
+ zmin = min(z, zmin)
+
+ return (xmin, ymin, zmin), (xmax, ymax, zmax)
+
+
+def mesh_uv_add(obj):
+
+ uvs = ((0.0, 0.0),
+ (0.0, 1.0),
+ (1.0, 1.0),
+ (1.0, 0.0))
+
+ uv_lay = obj.data.uv_textures.new()
+
+ if IS_BMESH:
+ # XXX, odd that we need to do this. until UV's and texface
+ # are separated we will need to keep it
+ uv_loops = obj.data.uv_layers[-1]
+ uv_list = uv_loops.data[:]
+ for poly in obj.data.polygons:
+ poly_uvs = mesh_bmesh_poly_elems(poly, uv_list)
+ for i, c in enumerate(poly_uvs):
+ c.uv = uvs[i % 4]
+ else:
+ for uv in uv_lay.data:
+ uv.uv1 = uvs[0]
+ uv.uv2 = uvs[1]
+ uv.uv3 = uvs[2]
+ uv.uv4 = uvs[3]
+
+ return uv_lay
+
+
+def mesh_vcol_add(obj, mode=0):
+
+ colors = ((0.0, 0.0, 0.0), # black
+ (1.0, 0.0, 0.0), # red
+ (0.0, 1.0, 0.0), # green
+ (0.0, 0.0, 1.0), # blue
+ (1.0, 1.0, 0.0), # yellow
+ (0.0, 1.0, 1.0), # cyan
+ (1.0, 0.0, 1.0), # magenta
+ (1.0, 1.0, 1.0), # white
+ )
+
+ def colors_get(i):
+ return colors[i % len(colors)]
+
+ vcol_lay = obj.data.vertex_colors.new()
+
+ mesh = obj.data
+
+ if IS_BMESH:
+ col_list = vcol_lay.data[:]
+ for poly in mesh.polygons:
+ face_verts = mesh_bmesh_poly_vertices(poly)
+ poly_cols = mesh_bmesh_poly_elems(poly, col_list)
+ for i, c in enumerate(poly_cols):
+ c.color = colors_get(face_verts[i])
+ else:
+ for i, col in enumerate(vcol_lay.data):
+ face_verts = mesh.faces[i].vertices
+ col.color1 = colors_get(face_verts[0])
+ col.color2 = colors_get(face_verts[1])
+ col.color3 = colors_get(face_verts[2])
+ if len(face_verts) == 4:
+ col.color4 = colors_get(face_verts[3])
+
+ return vcol_lay
+
+
+def mesh_vgroup_add(obj, name="Group", axis=0, invert=False, mode=0):
+ mesh = obj.data
+ vgroup = obj.vertex_groups.new(name=name)
+ vgroup.add(list(range(len(mesh.vertices))), 1.0, 'REPLACE')
+ group_index = len(obj.vertex_groups) - 1
+
+ min_bb, max_bb = mesh_bounds(mesh)
+
+ range_axis = max_bb[axis] - min_bb[axis]
+
+ # gradient
+ for v in mesh.vertices:
+ for vg in v.groups:
+ if vg.group == group_index:
+ f = (v.co[axis] - min_bb[axis]) / range_axis
+ vg.weight = 1.0 - f if invert else f
+
+ return vgroup
+
+
+def mesh_shape_add(obj, mode=0):
+ pass
+
+
+def mesh_armature_add(obj, mode=0):
+ pass
+
+
+# -----------------------------------------------------------------------------
+# modifiers
+
+def modifier_subsurf_add(scene, obj, levels=2):
+ mod = obj.modifiers.new(name=whoami(), type='SUBSURF')
+ defaults_modifier(mod)
+
+ mod.levels = levels
+ mod.render_levels = levels
+ return mod
+
+
+def modifier_armature_add(scene, obj):
+ mod = obj.modifiers.new(name=whoami(), type='ARMATURE')
+ defaults_modifier(mod)
+
+ arm_data = bpy.data.armatures.new(whoami())
+ obj_arm = bpy.data.objects.new(whoami(), arm_data)
+
+ scene.objects.link(obj_arm)
+
+ obj_arm.select = True
+ scene.objects.active = obj_arm
+
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+
+ # XXX, annoying, remove bone.
+ while arm_data.edit_bones:
+ obj_arm.edit_bones.remove(arm_data.edit_bones[-1])
+
+ bone_a = arm_data.edit_bones.new("Bone.A")
+ bone_b = arm_data.edit_bones.new("Bone.B")
+ bone_b.parent = bone_a
+
+ bone_a.head = -1, 0, 0
+ bone_a.tail = 0, 0, 0
+ bone_b.head = 0, 0, 0
+ bone_b.tail = 1, 0, 0
+
+ # Get armature animation data
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ # 45d armature
+ obj_arm.pose.bones["Bone.B"].rotation_quaternion = 1, -0.5, 0, 0
+
+ # set back to the original
+ scene.objects.active = obj
+
+ # display options
+ obj_arm.show_x_ray = True
+ arm_data.draw_type = 'STICK'
+
+ # apply to modifier
+ mod.object = obj_arm
+
+ mesh_vgroup_add(obj, name="Bone.A", axis=0, invert=True)
+ mesh_vgroup_add(obj, name="Bone.B", axis=0, invert=False)
+
+ return mod
+
+
+def modifier_mirror_add(scene, obj):
+ mod = obj.modifiers.new(name=whoami(), type='MIRROR')
+ defaults_modifier(mod)
+
+ return mod
+
+
+def modifier_solidify_add(scene, obj, thickness=0.25):
+ mod = obj.modifiers.new(name=whoami(), type='SOLIDIFY')
+ defaults_modifier(mod)
+
+ mod.thickness = thickness
+
+ return mod
+
+
+def modifier_hook_add(scene, obj, use_vgroup=True):
+ scene.objects.active = obj
+
+ # no nice way to add hooks from py api yet
+ # assume object mode, hook first face!
+ mesh = obj.data
+
+ if use_vgroup:
+ for v in mesh.vertices:
+ v.select = True
+ else:
+ for v in mesh.vertices:
+ v.select = False
+
+ if IS_BMESH:
+ face_verts = mesh_bmesh_poly_vertices(mesh.polygons[0])
+ else:
+ face_verts = mesh.faces[0].vertices[:]
+
+ for i in mesh.faces[0].vertices:
+ mesh.vertices[i].select = True
+
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.object.hook_add_newob()
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ # mod = obj.modifiers.new(name=whoami(), type='HOOK')
+ mod = obj.modifiers[-1]
+ defaults_modifier(mod)
+
+ obj_hook = mod.object
+ obj_hook.rotation_euler = 0, math.radians(45), 0
+ obj_hook.show_x_ray = True
+
+ if use_vgroup:
+ mod.vertex_group = obj.vertex_groups[0].name
+
+ return mod
+
+
+def modifier_decimate_add(scene, obj):
+ mod = obj.modifiers.new(name=whoami(), type='DECIMATE')
+ defaults_modifier(mod)
+
+ mod.ratio = 1 / 3
+
+ return mod
+
+
+def modifier_build_add(scene, obj):
+ mod = obj.modifiers.new(name=whoami(), type='BUILD')
+ defaults_modifier(mod)
+
+ # ensure we display some faces
+ if IS_BMESH:
+ totface = len(obj.data.polygons)
+ else:
+ totface = len(obj.data.faces)
+
+ mod.frame_start = totface // 2
+ mod.frame_duration = totface
+
+ return mod
+
+
+def modifier_mask_add(scene, obj):
+ mod = obj.modifiers.new(name=whoami(), type='MASK')
+ defaults_modifier(mod)
+
+ mod.vertex_group = obj.vertex_groups[0].name
+
+ return mod
+
+
+# -----------------------------------------------------------------------------
+# models
+
+# useful since its solid boxy shape but simple enough to debug errors
+cube_like_vertices = (
+ (1, 1, -1),
+ (1, -1, -1),
+ (-1, -1, -1),
+ (-1, 1, -1),
+ (1, 1, 1),
+ (1, -1, 1),
+ (-1, -1, 1),
+ (-1, 1, 1),
+ (0, -1, -1),
+ (1, 0, -1),
+ (0, 1, -1),
+ (-1, 0, -1),
+ (1, 0, 1),
+ (0, -1, 1),
+ (-1, 0, 1),
+ (0, 1, 1),
+ (1, -1, 0),
+ (1, 1, 0),
+ (-1, -1, 0),
+ (-1, 1, 0),
+ (0, 0, -1),
+ (0, 0, 1),
+ (1, 0, 0),
+ (0, -1, 0),
+ (-1, 0, 0),
+ (2, 0, 0),
+ (2, 0, -1),
+ (2, 1, 0),
+ (2, 1, -1),
+ (0, 1, 2),
+ (0, 0, 2),
+ (-1, 0, 2),
+ (-1, 1, 2),
+ (-1, 0, 3),
+ (-1, 1, 3),
+ (0, 1, 3),
+ (0, 0, 3),
+ )
+
+
+cube_like_faces = (
+ (0, 9, 20, 10),
+ (0, 10, 17),
+ (0, 17, 27, 28),
+ (1, 16, 23, 8),
+ (2, 18, 24, 11),
+ (3, 19, 10),
+ (4, 15, 21, 12),
+ (4, 17, 15),
+ (7, 14, 31, 32),
+ (7, 15, 19),
+ (8, 23, 18, 2),
+ (9, 0, 28, 26),
+ (9, 1, 8, 20),
+ (9, 22, 16, 1),
+ (10, 20, 11, 3),
+ (11, 24, 19, 3),
+ (12, 21, 13, 5),
+ (13, 6, 18),
+ (14, 21, 30, 31),
+ (15, 7, 32, 29),
+ (15, 17, 10, 19),
+ (16, 5, 13, 23),
+ (17, 4, 12, 22),
+ (17, 22, 25, 27),
+ (18, 6, 14, 24),
+ (20, 8, 2, 11),
+ (21, 14, 6, 13),
+ (21, 15, 29, 30),
+ (22, 9, 26, 25),
+ (22, 12, 5, 16),
+ (23, 13, 18),
+ (24, 14, 7, 19),
+ (28, 27, 25, 26),
+ (29, 32, 34, 35),
+ (30, 29, 35, 36),
+ (31, 30, 36, 33),
+ (32, 31, 33, 34),
+ (35, 34, 33, 36),
+ )
+
+
+# useful since its a shell for solidify and it can be mirrored
+cube_shell_vertices = (
+ (0, 0, 1),
+ (0, 1, 1),
+ (-1, 1, 1),
+ (-1, 0, 1),
+ (0, 0, 0),
+ (0, 1, 0),
+ (-1, 1, 0),
+ (-1, 0, 0),
+ (-1, -1, 0),
+ (0, -1, 0),
+ (0, 0, -1),
+ (0, 1, -1),
+ )
+
+
+cube_shell_face = (
+ (0, 1, 2, 3),
+ (0, 3, 8, 9),
+ (1, 5, 6, 2),
+ (2, 6, 7, 3),
+ (3, 7, 8),
+ (4, 7, 10),
+ (6, 5, 11),
+ (7, 4, 9, 8),
+ (10, 7, 6, 11),
+ )
+
+
+def make_cube(scene):
+ bpy.ops.mesh.primitive_cube_add(view_align=False,
+ enter_editmode=False,
+ location=(0, 0, 0),
+ rotation=(0, 0, 0),
+ )
+
+ obj = scene.objects.active
+
+ defaults_object(obj)
+ return obj
+
+
+def make_cube_extra(scene):
+ obj = make_cube(scene)
+
+ # extra data layers
+ mesh_uv_add(obj)
+ mesh_vcol_add(obj)
+ mesh_vgroup_add(obj)
+
+ return obj
+
+
+def make_cube_like(scene):
+ mesh = bpy.data.meshes.new(whoami())
+
+ mesh.from_pydata(cube_like_vertices, (), cube_like_faces)
+ mesh.update() # add edges
+ obj = bpy.data.objects.new(whoami(), mesh)
+ scene.objects.link(obj)
+
+ defaults_object(obj)
+ return obj
+
+
+def make_cube_like_extra(scene):
+ obj = make_cube_like(scene)
+
+ # extra data layers
+ mesh_uv_add(obj)
+ mesh_vcol_add(obj)
+ mesh_vgroup_add(obj)
+
+ return obj
+
+
+def make_cube_shell(scene):
+ mesh = bpy.data.meshes.new(whoami())
+
+ mesh.from_pydata(cube_shell_vertices, (), cube_shell_face)
+ mesh.update() # add edges
+ obj = bpy.data.objects.new(whoami(), mesh)
+ scene.objects.link(obj)
+
+ defaults_object(obj)
+ return obj
+
+
+def make_cube_shell_extra(scene):
+ obj = make_cube_shell(scene)
+
+ # extra data layers
+ mesh_uv_add(obj)
+ mesh_vcol_add(obj)
+ mesh_vgroup_add(obj)
+
+ return obj
+
+
+def make_monkey(scene):
+ bpy.ops.mesh.primitive_monkey_add(view_align=False,
+ enter_editmode=False,
+ location=(0, 0, 0),
+ rotation=(0, 0, 0),
+ )
+ obj = scene.objects.active
+
+ defaults_object(obj)
+ return obj
+
+
+def make_monkey_extra(scene):
+ obj = make_monkey(scene)
+
+ # extra data layers
+ mesh_uv_add(obj)
+ mesh_vcol_add(obj)
+ mesh_vgroup_add(obj)
+
+ return obj
+
+
+# -----------------------------------------------------------------------------
+# tests (utils)
+
+global_tests = []
+
+global_tests.append(("none",
+ (),
+ ))
+
+# single
+global_tests.append(("subsurf_single",
+ ((modifier_subsurf_add, dict(levels=2)), ),
+ ))
+
+
+global_tests.append(("armature_single",
+ ((modifier_armature_add, dict()), ),
+ ))
+
+
+global_tests.append(("mirror_single",
+ ((modifier_mirror_add, dict()), ),
+ ))
+
+global_tests.append(("hook_single",
+ ((modifier_hook_add, dict()), ),
+ ))
+
+global_tests.append(("decimate_single",
+ ((modifier_decimate_add, dict()), ),
+ ))
+
+global_tests.append(("build_single",
+ ((modifier_build_add, dict()), ),
+ ))
+
+global_tests.append(("mask_single",
+ ((modifier_mask_add, dict()), ),
+ ))
+
+
+# combinations
+global_tests.append(("mirror_subsurf",
+ ((modifier_mirror_add, dict()),
+ (modifier_subsurf_add, dict(levels=2))),
+ ))
+
+global_tests.append(("solidify_subsurf",
+ ((modifier_solidify_add, dict()),
+ (modifier_subsurf_add, dict(levels=2))),
+ ))
+
+
+def apply_test(test, scene, obj,
+ render_func=None,
+ render_args=None,
+ render_kwargs=None,
+ ):
+
+ test_name, test_funcs = test
+
+ for cb, kwargs in test_funcs:
+ cb(scene, obj, **kwargs)
+
+ render_kwargs_copy = render_kwargs.copy()
+
+ # add test name in filepath
+ render_kwargs_copy["filepath"] += "_%s" % test_name
+
+ render_func(*render_args, **render_kwargs_copy)
+
+
+# -----------------------------------------------------------------------------
+# tests themselves!
+# having the 'test_' prefix automatically means these functions are called
+# for testing
+
+
+def test_cube(context, test):
+ scene = context.scene
+ obj = make_cube_extra(scene)
+ ctx_camera_setup(context, location=(3, 3, 3))
+
+ apply_test(test, scene, obj,
+ render_func=render_gl_all_modes,
+ render_args=(context, obj),
+ render_kwargs=dict(filepath=whoami()))
+
+
+def test_cube_like(context, test):
+ scene = context.scene
+ obj = make_cube_like_extra(scene)
+ ctx_camera_setup(context, location=(5, 5, 5))
+
+ apply_test(test, scene, obj,
+ render_func=render_gl_all_modes,
+ render_args=(context, obj),
+ render_kwargs=dict(filepath=whoami()))
+
+
+def test_cube_shell(context, test):
+ scene = context.scene
+ obj = make_cube_shell_extra(scene)
+ ctx_camera_setup(context, location=(4, 4, 4))
+
+ apply_test(test, scene, obj,
+ render_func=render_gl_all_modes,
+ render_args=(context, obj),
+ render_kwargs=dict(filepath=whoami()))
+
+
+# -----------------------------------------------------------------------------
+# call all tests
+
+def main():
+ print("Calling main!")
+ #render_gl(bpy.context, "/testme")
+ #ctx_clear_scene()
+
+ context = bpy.context
+
+ ctx_clear_scene()
+
+ # run all tests
+ for key, val in sorted(globals().items()):
+ if key.startswith("test_") and hasattr(val, "__call__"):
+ print("calling:", key)
+ for t in global_tests:
+ val(context, test=t)
+ ctx_clear_scene()
+
+
+# -----------------------------------------------------------------------------
+# annoying workaround for theme initialization
+
+if __name__ == "__main__":
+ import bpy
+ from bpy.app.handlers import persistent
+
+ @persistent
+ def load_handler(dummy):
+ print("Load Handler:", bpy.data.filepath)
+ if load_handler.first is False:
+ bpy.app.handlers.scene_update_post.remove(load_handler)
+ try:
+ main()
+ import sys
+ sys.exit(0)
+ except:
+ import traceback
+ traceback.print_exc()
+
+ import sys
+ # sys.exit(1) # comment to debug
+
+ else:
+ load_handler.first = False
+
+ load_handler.first = True
+ bpy.app.handlers.scene_update_post.append(load_handler)