def test_all_soa_grease_pencil(self): import array bpy.ops.object.gpencil_add(type="STROKE") proxy = BpyBlendProxy() proxy.load(test_context) gp_layers = proxy.data("grease_pencils").data("Stroke").data("layers") gp_points = gp_layers.data("Lines").data("frames").data(0).data( "strokes").data(0).data("points")._data expected = ( ("co", array.array, "f"), ("pressure", array.array, "f"), ("strength", array.array, "f"), ("uv_factor", array.array, "f"), ("uv_rotation", array.array, "f"), ("select", list, bool), ) for name, type_, element_type in expected: self.assertIn("co", gp_points) item = gp_points[name] self.assertIsInstance(item, SoaElement) self.assertIsInstance(item._data, type_) if type_ is array.array: self.assertEqual(item._data.typecode, element_type) else: self.assertIsInstance(item._data[0], element_type) self.assertEqual(len(gp_points["pressure"]._data), len(gp_points["strength"]._data)) self.assertEqual(3 * len(gp_points["pressure"]._data), len(gp_points["co"]._data))
class TestCodec(unittest.TestCase): def setUp(self): bpy.ops.wm.open_mainfile(filepath=test_blend_file) self.proxy = BpyBlendProxy() register_bl_equals(self, test_context) def test_camera(self): # test_codec.TestCodec.test_camera # prepare camera transmit_name = "transmit_camera" cam_sent = D.cameras["Camera_0"] cam_sent.dof.focus_object = D.objects["Cube"] # load into proxy self.proxy.load(test_context) # patch the name so that it does not get mixed up as we restore later in the same scene cam_proxy_sent = self.proxy.data("cameras").data("Camera_0") cam_proxy_sent._data["name"] = transmit_name self.assertIsInstance(cam_proxy_sent, BpyIDProxy) # encode codec = Codec() message = codec.encode(cam_proxy_sent) # # transmit # # create cam_received = D.cameras.new(transmit_name) # decode into proxy cam_proxy_received = codec.decode(message) focus_object_proxy = cam_proxy_received.data("dof").data( "focus_object") self.assertIsInstance(focus_object_proxy, BpyIDRefProxy) self.assertEqual(focus_object_proxy._datablock_uuid, cam_sent.dof.focus_object.mixer_uuid) # save into blender cam_proxy_received.save(D.cameras, transmit_name, self.proxy.visit_state()) self.assertEqual(cam_sent, cam_received) pass
class TestLoadProxy(unittest.TestCase): def setUp(self): file = test_blend_file # file = r"D:\work\data\test_files\BlenderSS 2_82.blend" bpy.ops.wm.open_mainfile(filepath=file) self.proxy = BpyBlendProxy() self.proxy.load(test_context) def check(self, item, expected_elements): self.assertSetEqual(set(item._data.keys()), set(expected_elements)) # @unittest.skip("") def test_blenddata(self): blend_data = self.proxy._data expected_data = { "scenes", "collections", "objects", "materials", "lights" } self.assertTrue(all([e in blend_data.keys() for e in expected_data])) self.check(self.proxy._data["scenes"], {"Scene_0", "Scene_1"}) self.check(self.proxy._data["cameras"], {"Camera_0", "Camera_1"}) self.check(self.proxy._data["objects"], {"Camera_obj_0", "Camera_obj_1", "Cone", "Cube", "Light"}) self.check( self.proxy._data["collections"], { "Collection_0_0", "Collection_0_1", "Collection_0_0_0", "Collection_1_0" }) def test_blenddata_filtered(self): blend_data = self.proxy._data scene = blend_data["scenes"]._data["Scene_0"]._data self.assertTrue("eevee" in scene) filter_stack = copy.copy(test_filter) filter_stack.append({T.Scene: TypeFilterOut(T.SceneEEVEE)}) proxy = BpyBlendProxy() proxy.load(Context(filter_stack)) blend_data_ = proxy._data scene_ = blend_data_["scenes"]._data["Scene_0"]._data self.assertFalse("eevee" in scene_) # @unittest.skip("") def test_scene(self): # test_misc.TestLoadProxy.test_scene scene = self.proxy._data["scenes"]._data["Scene_0"]._data # will vary slightly during tiune tuning of the default filter self.assertGreaterEqual(len(scene), 45) self.assertLessEqual(len(scene), 55) # objects = scene["objects"]._data # self.assertEqual(4, len(objects)) # for o in objects.values(): # self.assertEqual(type(o), BpyIDRefProxy, o) # builtin attributes (floats) frame_properties = [ name for name in scene.keys() if name.startswith("frame_") ] self.assertEqual(7, len(frame_properties)) # bpy_struct eevee = scene["eevee"]._data self.assertEqual(58, len(eevee)) # Currently mot loaded # # PropertiesGroup # cycles_proxy = scene["view_layers"]._data["View Layer"]._data["cycles"] # self.assertIsInstance(cycles_proxy, BpyPropertyGroupProxy) # self.assertEqual(32, len(cycles_proxy._data)) # # The master collection # master_collection = scene["collection"] # self.assertIsInstance(master_collection, BpyIDProxy) def test_collections(self): collections = self.proxy._data["collections"] coll_0_0 = collections._data["Collection_0_0"]._data coll_0_0_children = coll_0_0["children"] self.check(coll_0_0_children, {"Collection_0_0_0"}) for c in coll_0_0_children._data.values(): self.assertIsInstance(c, BpyIDRefProxy) coll_0_0_objects = coll_0_0["objects"] self.check(coll_0_0_objects, {"Camera_obj_0", "Camera_obj_1", "Cube", "Light"}) for o in coll_0_0_objects._data.values(): self.assertIsInstance(o, BpyIDRefProxy) pass def test_camera_focus_object_idref(self): # test_misc.TestLoadProxy.test_camera_focus_object_idref cam = D.cameras["Camera_0"] cam.dof.focus_object = D.objects["Cube"] self.proxy = BpyBlendProxy() self.proxy.load(test_context) # load into proxy cam_proxy = self.proxy.data("cameras").data("Camera_0") focus_object_proxy = cam_proxy.data("dof").data("focus_object") self.assertIsInstance(focus_object_proxy, BpyIDRefProxy) self.assertEqual(focus_object_proxy.collection, "objects") self.assertEqual(focus_object_proxy.key, "Cube") def test_camera_focus_object_none(self): # test_misc.TestLoadProxy.test_camera_focus_object_none self.proxy = BpyBlendProxy() self.proxy.load(test_context) # load into proxy cam_proxy = self.proxy.data("cameras").data("Camera_0") focus_object_proxy = cam_proxy.data("dof").data("focus_object") self.assertIs(focus_object_proxy, None)
class TestWriteAttribute(unittest.TestCase): def setUp(self): bpy.ops.wm.open_mainfile(filepath=test_blend_file) # otherwise the loaded scene way have curves despite use_curve_mapping==False and # the new one will not have curves and will not receive them as they are not send # use_curve_mapping == False D.scenes["Scene_0"].view_settings.use_curve_mapping = True self.proxy = BpyBlendProxy() self.proxy.load(context) register_bl_equals(self, context) def test_write_simple_types(self): scene = D.scenes[0] object_ = D.objects[0] # matrix = [10.0, 20.0, 30.0, 40.0, 11.0, 21.0, 31.0, 41.0, 12.0, 22.0, 32.0, 42.0, 14.0, 24.0, 34.0, 44] matrix2 = [[10.0, 20.0, 30.0, 40], [11.0, 21.0, 31.0, 41], [12.0, 22.0, 32.0, 42], [14.0, 24.0, 34.0, 44]] values = [ # (scene, "name", "Plop"), (scene, "frame_current", 99), (scene, "use_gravity", False), (scene, "gravity", [-1, -2, -3]), (scene, "gravity", Vector([-10, -20, -30])), (scene, "sync_mode", "FRAME_DROP"), # (object_, "matrix_world", matrix), (object_, "matrix_world", Matrix(matrix2)), ] for bl_instance, name, value in values: write_attribute(bl_instance, name, value, self.proxy.visit_state()) stored_value = getattr(bl_instance, name) stored_type = type(stored_value) self.assertEqual(stored_type(value), stored_value) def test_write_bpy_struct_scene_eevee(self): scene = D.scenes[0] eevee_proxy = self.proxy._data["scenes"]._data["Scene_0"]._data[ "eevee"] eevee_proxy._data["gi_cubemap_resolution"] = "64" eevee_proxy.save(scene, "eevee", self.proxy.visit_state()) self.assertEqual("64", scene.eevee.gi_cubemap_resolution) def test_write_bpy_property_group_scene_cycles(self): # Not very useful it derives from struct scene = D.scenes[0] cycles_proxy = self.proxy._data["scenes"]._data["Scene_0"]._data[ "cycles"] cycles_proxy._data["shading_system"] = True cycles_proxy.save(scene, "cycles", self.proxy.visit_state()) self.assertEqual(True, scene.cycles.shading_system) def test_write_array_of_struct_with_vec(self): # self.addTypeEqualityFunc(D.bpy_struct, bl_equalityfunc) cube = D.meshes["Cube"] vertices_proxy = self.proxy._data["meshes"]._data["Cube"]._data[ "vertices"] # loaded as SOA into array.array co_proxy = vertices_proxy._data["co"]._data # first vertex co_proxy[0] *= 2 co_proxy[1] *= 2 co_proxy[2] *= 2 vertices_proxy.save(cube, "vertices", self.proxy.visit_state()) self.assertListEqual(list(cube.vertices[0].co[0:3]), co_proxy[0:3].tolist()) # explicit test per data type , including addition in collections def test_write_datablock_light(self): # Write a whole scene datablock light_name = "Light" light = D.lights[light_name] light_type = light.type light_proxy = self.proxy.data("lights").data(light_name) light.name = "light_bak" light_bak = D.lights["light_bak"] light = D.lights.new(light_name, light_type) light_proxy.save(D.lights, light_name, self.proxy.visit_state()) self.assertEqual(D.lights[light_name], light_bak) def test_write_datablock_world(self): # Write a whole scene datablock world_name = "World" world = D.worlds[world_name] world_proxy = self.proxy.data("worlds").data(world_name) world.name = "world_bak" world_bak = D.worlds["world_bak"] world = D.worlds.new(world_name) world_proxy.save(D.worlds, world_name, self.proxy.visit_state()) self.assertEqual(D.worlds[world_name], world_bak) def test_write_array_curvemap(self): bpy.ops.wm.open_mainfile(filepath=test_blend_file) light_name = "Light" light = D.lights["Light"] points = [(0.111, 0.222), (0.333, 0.444)] curve0 = light.falloff_curve.curves[0] for i, point in enumerate(points): curve0.points[i].location = point self.proxy = BpyBlendProxy() self.proxy.load(context) light.name = "light_bak" light_bak = D.lights["light_bak"] light = None light_proxy = self.proxy.data("lights").data(light_name) light_proxy.save(D.lights, light_name, self.proxy.visit_state()) light = D.lights[light_name] curve = light.falloff_curve.curves[0] for i, point in enumerate(points): for clone, expected in zip(curve.points[i].location, point): self.assertAlmostEqual(clone, expected) self.assertEqual(D.lights[light_name], light_bak) def test_array_curvemap_shrink(self): bpy.ops.wm.open_mainfile(filepath=test_blend_file) light_name = "Light" light = D.lights["Light"] src_points = [(0.666, 0.777), (0.888, 0.999)] curve0 = light.falloff_curve.curves[0] for i, point in enumerate(src_points): curve0.points[i].location = point self.proxy = BpyBlendProxy() self.proxy.load(context) light.name = "light_bak" light = None light_proxy = self.proxy.data("lights").data(light_name) light_proxy.save(D.lights, light_name, self.proxy.visit_state()) light = D.lights[light_name] dst_curve = light.falloff_curve.curves[0] self.assertEqual(len(src_points), len(dst_curve.points)) # extend the dst curvemap to 3 points dst_points = [(0.111, 0.222), (0.333, 0.444), (0.555, 0.666)] curve0 = light.falloff_curve.curves[0] curve0.points.new(*dst_points[2]) for i, point in enumerate(dst_points): curve0.points[i].location = point self.assertEqual(len(dst_points), len(dst_curve.points)) # restore again, save needs to shrink light_proxy.save(D.lights, light_name, self.proxy.visit_state()) light = D.lights[light_name] dst_curve = light.falloff_curve.curves[0] self.assertEqual(len(src_points), len(dst_curve.points)) for i, point in enumerate(src_points): for dst, expected in zip(dst_curve.points[i].location, point): self.assertAlmostEqual(dst, expected) def test_array_curvemap_extend(self): bpy.ops.wm.open_mainfile(filepath=test_blend_file) light_name = "Light" light = D.lights["Light"] light_type = light.type # extend the source curvemap to 3 points src_points = [(0.111, 0.222), (0.333, 0.444), (0.555, 0.666)] curve0 = light.falloff_curve.curves[0] curve0.points.new(*src_points[2]) for i, point in enumerate(src_points): curve0.points[i].location = point self.proxy = BpyBlendProxy() self.proxy.load(context) light.name = "light_bak" light = D.lights.new(light_name, light_type) # the dst curvemap has 2 points by default # save() needs to extend light_proxy = self.proxy.data("lights").data(light_name) light_proxy.save(D.lights, light_name, self.proxy.visit_state()) dst_curve = light.falloff_curve.curves[0] self.assertEqual(len(src_points), len(dst_curve.points)) for i, point in enumerate(src_points): for dst, expected in zip(dst_curve.points[i].location, point): self.assertAlmostEqual(dst, expected) def test_write_datablock_scene(self): # Write a whole scene datablock scene_name = "Scene_0" scene = D.scenes[scene_name] scene_proxy = self.proxy.data("scenes").data(scene_name) self.assertIsInstance(scene_proxy, BpyIDProxy) scene.name = "scene_bak" scene_bak = D.scenes["scene_bak"] scene_proxy.save(D.scenes, scene_name, self.proxy.visit_state()) self.assertEqual(D.scenes[scene_name], scene_bak) def test_write_datablock_reference_scene_world(self): # just write the Scene.world attribute scene_name = "Scene_0" scene = D.scenes[scene_name] expected_world = scene.world assert expected_world is not None world_ref_proxy = self.proxy.data("scenes").data(scene_name).data( "world") self.assertIsInstance(world_ref_proxy, BpyIDRefProxy) scene.world = None assert scene.world != expected_world world_ref_proxy.save(scene, "world", self.proxy.visit_state()) self.assertEqual(scene.world, expected_world) def test_write_datablock_with_reference_camera_dof_target(self): # Write the whole camera datablock, including its reference to dof target camera_name = "Camera_0" camera = D.cameras[camera_name] # setup the scene and reload focus_object = D.objects["Cube"] camera.dof.focus_object = focus_object self.proxy = BpyBlendProxy() self.proxy.load(context) camera.name = "camera_bak" camera_proxy = self.proxy.data("cameras").data(camera_name) camera_proxy.save(D.cameras, camera_name, self.proxy.visit_state()) self.assertEqual(D.cameras[camera_name].dof.focus_object, focus_object)