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:
Diffstat (limited to 'source/tests/bl_mesh_modifiers.py')
-rw-r--r--source/tests/bl_mesh_modifiers.py866
1 files changed, 0 insertions, 866 deletions
diff --git a/source/tests/bl_mesh_modifiers.py b/source/tests/bl_mesh_modifiers.py
deleted file mode 100644
index 2f342f2c65e..00000000000
--- a/source/tests/bl_mesh_modifiers.py
+++ /dev/null
@@ -1,866 +0,0 @@
-# ##### 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 source/tests/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)