def _prepare_animation(): arm = bpy.data.armatures.new('test') obj = bpy.data.objects.new('test', arm) utils.link_object(obj) utils.set_active_object(obj) bpy.ops.object.mode_set(mode='EDIT') try: bone = arm.edit_bones.new('bone') bone.head.z = 0.5 cbone = arm.edit_bones.new('cbone') cbone.parent = bone cbone.head.z = 0.5 finally: bpy.ops.object.mode_set(mode='OBJECT') pbone = obj.pose.bones['bone'] pbone.keyframe_insert('location', frame=1, group='bone') pbone.location = (1, 2, 3) pbone.keyframe_insert('location', frame=5, group='bone') motion = obj.xray.motions_collection.add() motion.name = bpy.data.actions[0].name bmesh = utils.create_bmesh(( (0, 0, 0), (-1, -1, 0), (+1, -1, 0), (+1, +1, 0), (-1, +1, 0), ), ((0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 1)), True) obj_me = utils.create_object(bmesh, True) group = obj_me.vertex_groups.new(name='bone') group.add(range(len(obj_me.data.vertices)), 1, 'REPLACE') obj_me.parent = obj obj_me.xray.isroot = False return obj
def _create_armature(name, connected=False, rigid=False): arm = bpy.data.armatures.new(name) obj = bpy.data.objects.new(name, arm) utils.link_object(obj) utils.set_active_object(obj) children = [] with using_mode(mode='EDIT'): root = arm.edit_bones.new('root') root.tail = (0, 0, 1) child1 = arm.edit_bones.new('child1') child1.parent = root child1.head = root.tail if connected else (1, 0, 0) child1.tail = (0, 1, 1) children.append(child1.name) child2 = arm.edit_bones.new('child2') child2.parent = root child2.head = root.tail if connected else (1, 0, 0) child2.tail = (1, 0, 1) children.append(child2.name) with using_mode(mode='OBJECT'): ikjoint_type = '0' if rigid else '1' for child_name in children: arm.bones[child_name].xray.ikjoint.type = ikjoint_type return obj.data
def _create_details_objects(self, version, create_uv=True, create_material=True): bmesh = utils.create_bmesh(( (0, 0, 0), (-1, -1, 0), (+1, -1, 0), (+1, +1, 0), (-1, +1, 0), ), ((0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 1)), create_uv) root_object = bpy.data.objects.new('Details', None) bpy.ops.object.select_all(action='DESELECT') utils.link_object(root_object) if bpy.app.version >= (2, 80, 0): root_object.select_set(True) else: root_object.select = True root_object.xray.is_details = True data = root_object.xray.detail self._create_details_images(data, version) self._create_details_slots_objects(data) meshes_object = bpy.data.objects.new('DM Meshes', None) utils.link_object(meshes_object) meshes_object.parent = root_object data.slots.meshes_object = meshes_object.name objs = [] for i in range(3): obj = utils.create_object(bmesh, create_material) obj.name = 'tdm%d' % (i + 1) obj.parent = meshes_object obj.xray.is_details = True obj.xray.detail.model.index = i objs.append(obj) bpy_texture = bpy.data.textures.new('test_texture', 'IMAGE') bpy_image = bpy.data.images.new('test_image.dds', 0, 0) bpy_image.source = 'FILE' bpy_image.filepath = 'test_image.dds' if bpy.app.version >= (2, 80, 0): obj.data.materials[0].use_nodes = True node_tree = obj.data.materials[0].node_tree texture_node = node_tree.nodes.new('ShaderNodeTexImage') texture_node.image = bpy_image texture_node.location.x -= 500 princ_shader = node_tree.nodes['Principled BSDF'] node_tree.links.new(texture_node.outputs['Color'], princ_shader.inputs['Base Color']) else: bpy_texture.image = bpy_image texture_slot = obj.data.materials[0].texture_slots.add() texture_slot.texture = bpy_texture return objs
def _create_armature(self, bone_name): arm = bpy.data.armatures.new('tarm') obj = bpy.data.objects.new('tobj', arm) utils.link_object(obj) utils.set_active_object(obj) bpy.ops.object.mode_set(mode='EDIT') try: bone = arm.edit_bones.new(bone_name) bone.tail.y = 1 finally: bpy.ops.object.mode_set(mode='OBJECT')
def test_import_sg_maya(self): # Arrange arm = bpy.data.armatures.new('test') obj = bpy.data.objects.new('test', arm) utils.link_object(obj) utils.set_active_object(obj) bpy.ops.object.mode_set(mode='EDIT') try: bone = arm.edit_bones.new('non-exp') bone.head.z = 0.5 bone = arm.edit_bones.new('exp') bone.head.z = 0.5 finally: bpy.ops.object.mode_set(mode='OBJECT') arm.bones['non-exp'].xray.exportable = False bmesh = utils.create_bmesh(( (0, 0, 0), (-1, -1, 0), (+1, -1, 0), (+1, +1, 0), (-1, +1, 0), ), ((0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 1)), True) obj_me = utils.create_object(bmesh, True) obj_me.parent = obj obj_me.xray.isroot = False group = obj_me.vertex_groups.new(name='exp') group.add(range(len(obj_me.data.vertices)), 1, 'REPLACE') # Act bpy.ops.xray_export.object( objects=obj.name, directory=self.outpath(), texture_name_from_image_path=False, export_motions=False, ) # Assert bpy.ops.xray_import.object( directory=self.outpath(), files=[{ 'name': 'test.object' }], ) obj_arm = bpy.data.objects[-1] self.assertEqual(obj_arm.type, 'ARMATURE') self.assertEqual(obj_arm.xray.isroot, True) imp_arm = bpy.data.armatures[1] self.assertEqual(len(imp_arm.bones), 1)
def test_verify_uv(self): # test without selected objects bpy.ops.io_scene_xray.verify_uv() verts = [ [0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0] ] faces = ( (0, 1, 2), (2, 3, 0) ) uvs = [ 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 ] uv_offsets = ( (0, 0), (50, 50), (-1, -1) ) for i in range(3): mesh = bpy.data.meshes.new('test_verify_uv') mesh.from_pydata(verts, (), faces) if bpy.app.version >= (2, 80, 0): uv_layer = mesh.uv_layers.new(name='uv') else: uv_tex = mesh.uv_textures.new(name='uv') uv_layer = mesh.uv_layers[uv_tex.name] uv_layer.data.foreach_set('uv', uvs) obj = bpy.data.objects.new('test_verify_uv', mesh) utils.link_object(obj) utils.select_object(obj) for vert in verts: vert[0] += 2 uv_offset_x, uv_offset_y = uv_offsets[i] for uv_index in range(0, len(uvs), 2): uvs[uv_index] += uv_offset_x uvs[uv_index + 1] += uv_offset_y obj = bpy.data.objects.new('test_verify_uv_empty', None) utils.link_object(obj) utils.select_object(obj) bpy.ops.io_scene_xray.verify_uv() self.assertEqual(len(bpy.context.selected_objects), 1)
def test_change_fake_user(self): for index in range(3): name = str(index) me = bpy.data.meshes.new(name) obj = bpy.data.objects.new(name, me) utils.link_object(obj) utils.select_object(obj) mat = bpy.data.materials.new(name) me.materials.append(mat) img = bpy.data.images.new(name, 0, 0) img.source = 'FILE' mat.use_nodes = True img_node = mat.node_tree.nodes.new('ShaderNodeTexImage') img_node.image = img arm = bpy.data.armatures.new(name) obj = bpy.data.objects.new(name + '_arm', arm) utils.link_object(obj) utils.select_object(obj) act = bpy.data.actions.new(name) motion = obj.xray.motions_collection.add() motion.name = act.name utils.set_active_object(bpy.data.objects[0]) modes = ( 'ACTIVE_OBJECT', 'SELECTED_OBJECTS', 'ALL_OBJECTS', 'ALL_DATA' ) data = ( 'OBJECTS', 'MESHES', 'MATERIALS', 'TEXTURES', 'IMAGES', 'ARMATURES', 'ACTIONS', 'ALL' ) fake_users = ('TRUE', 'FALSE', 'INVERT') for mode in modes: for data_ in data: for fake_user in fake_users: bpy.ops.io_scene_xray.change_fake_user( mode=mode, data={data_, }, fake_user=fake_user )
def _create_details_slots_objects(self, data): vertices_1 = ((112.0000, -6.0000, -7.2000), (114.0000, -6.0000, -7.2000), (114.0000, -4.0000, -7.2000), (112.0000, -4.0000, -7.2000), (114.0000, -6.0000, -7.4000), (116.0000, -6.0000, -7.4000), (116.0000, -4.0000, -7.4000), (114.0000, -4.0000, -7.4000), (112.0000, -4.0000, -7.2000), (114.0000, -4.0000, -7.2000), (114.0000, -2.0000, -7.2000), (112.0000, -2.0000, -7.2000), (114.0000, -4.0000, -7.4000), (116.0000, -4.0000, -7.4000), (116.0000, -2.0000, -7.4000), (114.0000, -2.0000, -7.4000)) vertices_2 = ((112.0000, -6.0000, -7.0500), (114.0000, -6.0000, -7.0500), (114.0000, -4.0000, -7.0500), (112.0000, -4.0000, -7.0500), (114.0000, -6.0000, -7.0500), (116.0000, -6.0000, -7.0500), (116.0000, -4.0000, -7.0500), (114.0000, -4.0000, -7.0500), (112.0000, -4.0000, -7.0500), (114.0000, -4.0000, -7.0500), (114.0000, -2.0000, -7.0500), (112.0000, -2.0000, -7.0500), (114.0000, -4.0000, -7.0500), (116.0000, -4.0000, -7.0500), (116.0000, -2.0000, -7.0500), (114.0000, -2.0000, -7.0500)) polygons = ((0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15)) mesh_1 = bpy.data.meshes.new('slots_1') mesh_2 = bpy.data.meshes.new('slots_2') mesh_1.from_pydata(vertices_1, (), polygons) mesh_2.from_pydata(vertices_2, (), polygons) object_1 = bpy.data.objects.new('slots_1', mesh_1) object_2 = bpy.data.objects.new('slots_2', mesh_2) utils.link_object(object_1) utils.link_object(object_2) data.slots.slots_base_object = object_1.name data.slots.slots_top_object = object_2.name
def test_init_shaders_dynamic(self): # Arrange version = utl.plugin_version_number() obj = bpy.data.objects.new('', None) obj.xray.flags_custom_type = 'dy' utils.link_object(obj) utils.set_active_object(obj) mat = bpy.data.materials.new('') # Act plugin.scene_update_post(bpy.context.scene) # Assert self.assertEqual(mat.xray.version, version) self.assertEqual(mat.xray.eshader, 'models\\model')
def test_init_version_and_shaders(self): # Arrange version = utl.plugin_version_number() obj = bpy.data.objects.new('', None) obj.xray.flags_custom_type = 'st' utils.link_object(obj) utils.set_active_object(obj) mat = bpy.data.materials.new('') # Act handlers.scene_update_post(bpy.context.scene) # Assert self.assertEqual(mat.xray.version, version) self.assertEqual(mat.xray.eshader, 'default')
def test_export_with_empty(self): # Arrange root = bpy.data.objects.new('empty', None) utils.link_object(root) objs = self._create_objects() obj = _create_armature(objs[0]) obj.parent = root utils.set_active_object(root) # Act bpy.ops.xray_export.object(object='empty', filepath=self.outpath('test.object'), texture_name_from_image_path=False) # Assert self.assertOutputFiles({'test.object'})
def test_copy_paste_action_settings(self): # copy act = bpy.data.actions.new('test_act_copy') arm = bpy.data.armatures.new('test_arm_copy') obj = bpy.data.objects.new('test_obj_copy', arm) obj.animation_data_create().action = act utils.link_object(obj) utils.select_object(obj) utils.set_active_object(obj) bpy.ops.io_scene_xray.copy_action_settings() # paste act = bpy.data.actions.new('test_act_paste') arm = bpy.data.armatures.new('test_arm_paste') obj = bpy.data.objects.new('test_obj_paste', arm) obj.animation_data_create().action = act utils.link_object(obj) utils.select_object(obj) utils.set_active_object(obj) bpy.ops.io_scene_xray.paste_action_settings()
def _create_armature(target): arm = bpy.data.armatures.new('tarm') obj = bpy.data.objects.new('tobj', arm) utils.link_object(obj) utils.set_active_object(obj) bpy.ops.object.mode_set(mode='EDIT') try: bone = arm.edit_bones.new('tbone') bone.tail.y = 1 finally: bpy.ops.object.mode_set(mode='OBJECT') target.modifiers.new(name='Armature', type='ARMATURE').object = obj target.parent = obj grp = target.vertex_groups.new(name='tbone') vertices_count = len(target.data.vertices) grp.add(range(vertices_count), 1, 'REPLACE') grp = target.vertex_groups.new(name=io_scene_xray.utils.BAD_VTX_GROUP_NAME) grp.add([vertices_count], 1, 'REPLACE') return obj
def _create_active_object(self): obj = bpy.data.objects.new('tobj', None) utils.link_object(obj) utils.set_active_object(obj) return obj
def test_empty_bone_groups(self): # Arrange arm = bpy.data.armatures.new('tarm') obj = bpy.data.objects.new('tobj', arm) utils.link_object(obj) utils.set_active_object(obj) b_exp0, b_non0, b_exp1, b_non1 = ('b-exportable0', 'b-non-exportable0', 'b-exportable1', 'b-non-exportable1') bpy.ops.object.mode_set(mode='EDIT') try: for n in (b_exp0, b_non0, b_exp1, b_non1): bone = arm.edit_bones.new(n) bone.tail.y = 1 for n in (b_non0, b_exp1, b_non1): bone = arm.edit_bones[n] parent = arm.edit_bones[b_exp0] bone.parent = parent finally: bpy.ops.object.mode_set(mode='POSE') bg_exp = obj.pose.bone_groups.new(name='bg-only-exportable') bg_mix = obj.pose.bone_groups.new(name='bg-mixed') bg_non = obj.pose.bone_groups.new(name='bg-only-non-exportable') bg_emp = obj.pose.bone_groups.new(name='bg-empty') obj.pose.bones[b_exp0].bone_group = bg_exp obj.pose.bones[b_non0].bone_group = bg_mix obj.pose.bones[b_exp1].bone_group = bg_mix obj.pose.bones[b_non0].bone_group = bg_non arm.bones[b_non0].xray.exportable = False arm.bones[b_non1].xray.exportable = False bmesh = utils.create_bmesh(( (0, 0, 0), (-1, -1, 0), (+1, -1, 0), (+1, +1, 0), (-1, +1, 0), ), ((0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 1)), True) obj_me = utils.create_object(bmesh, True) obj_me.parent = obj obj_me.xray.isroot = False vertex_group = obj_me.vertex_groups.new(name='b-exportable0') vertex_group.add(range(len(obj_me.data.vertices)), 1.0, 'REPLACE') # Act bpy.ops.export_object.xray_objects( objects='tobj', directory=self.outpath(), texture_name_from_image_path=False, export_motions=False, ) # Assert self.assertReportsNotContains('WARNING') self.assertOutputFiles({ 'tobj.object', }) content = self.getFileSafeContent('tobj.object') self.assertRegex(content, re.compile(bytes(b_exp0, 'cp1251'))) self.assertRegex(content, re.compile(bytes(b_exp1, 'cp1251'))) self.assertNotRegex(content, re.compile(bytes(b_non0, 'cp1251'))) self.assertNotRegex(content, re.compile(bytes(b_non1, 'cp1251'))) self.assertRegex(content, re.compile(bytes(bg_exp.name, 'cp1251'))) self.assertRegex(content, re.compile(bytes(bg_mix.name, 'cp1251'))) self.assertNotRegex(content, re.compile(bytes(bg_non.name, 'cp1251'))) self.assertNotRegex(content, re.compile(bytes(bg_emp.name, 'cp1251')))
def test_change_action_bake_settings(self): for index in range(3): name = 'test_' + str(index) act = bpy.data.actions.new(name) obj = bpy.data.objects.new(name, None) obj.animation_data_create().action = act utils.link_object(obj) utils.select_object(obj) utils.set_active_object(obj) motion = obj.xray.motions_collection.add() motion.name = act.name for index in range(3, 6): name = 'test_' + str(index) act = bpy.data.actions.new(name) obj = bpy.data.objects.new(name, None) obj.animation_data_create().action = act for index in range(6, 9): name = 'test_' + str(index) act = bpy.data.actions.new(name) bpy.ops.io_scene_xray.change_action_bake_settings() bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ACTIVE_ACTION' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ACTIVE_OBJECT' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='SELECTED_OBJECTS' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_OBJECTS' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', change_auto_bake_mode=False ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', auto_bake_mode='auto' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', auto_bake_mode='on' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', auto_bake_mode='off' ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', change_use_custom_thresholds=False ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', use_custom_threshold=False ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', change_location_threshold=False ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', change_rotation_threshold=False ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', value_location_threshold=1.0 ) bpy.ops.io_scene_xray.change_action_bake_settings( change_mode='ALL_ACTIONS', value_rotation_threshold=1.0 )