def test_only_obj_blur(self):
        """
        Only one object ("moving_obj") is moving. Camera blur is disabled.
        """
        blender_scene = bpy.context.scene

        # Switch to the static camera
        blender_scene.camera = bpy.data.objects["static_camera"]

        # Switch to correct frame in case someone messed it up on save
        blender_scene.frame_set(TEST_FRAME, TEST_SUBFRAME)

        # Get the object that moves and should be blurred
        moving_obj = bpy.data.objects["moving_obj"]
        moving_obj_name = utils.get_luxcore_name(moving_obj,
                                                 is_viewport_render=False)

        # Make sure the settings are correct
        # (can only change if someone messes with the test scene)
        self.assertIsNotNone(blender_scene.camera)
        blur_settings = blender_scene.camera.data.luxcore.motion_blur
        self.assertTrue(blur_settings.enable)
        self.assertAlmostEqual(blur_settings.shutter, 4.0)
        self.assertTrue(blur_settings.object_blur)
        self.assertFalse(blur_settings.camera_blur)
        self.assertEqual(blur_settings.steps, 2)
        # Make sure we are at the correct frame
        self.assertEqual(blender_scene.frame_current, 3)
        self.assertAlmostEqual(blender_scene.frame_subframe, 0.0)

        # Export the scene
        scene_props = export(blender_scene)

        # Check properties for correctness
        all_exported_obj_prefixes = scene_props.GetAllUniqueSubNames(
            "scene.objects")

        for prefix in all_exported_obj_prefixes:
            luxcore_name = prefix.split(".")[-1]

            if luxcore_name == moving_obj_name:
                test_moving_object(self, scene_props, prefix)

        # Check if camera shutter settings are correct
        # Total shutter duration is 4.0 frames, so these should be -2.0 and 2.0
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.shutteropen").GetFloat(), -2.0)
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.shutterclose").GetFloat(), 2.0)
Example #2
0
def export_first_mat(type_str):
    """
    Export material node tree on material slot 0.
    type_str is the name of the object with the material to export, e.g. "matte"
    """
    obj = bpy.data.objects[type_str]
    mat = obj.material_slots[0].material
    node_tree = mat.luxcore.node_tree
    active_output = get_active_output(node_tree)

    luxcore_name = utils.get_luxcore_name(mat, is_viewport_render=False)
    props = pyluxcore.Properties()

    # Now export the material node tree, starting at the output node
    active_output.export(props, luxcore_name)
    prefix = "scene.materials." + luxcore_name

    return props, luxcore_name, prefix
    def test_materials(self):
        blender_scene = bpy.context.scene

        # Export the scene
        scene_props = export(blender_scene)

        # Note: the "000" at the end of the name is there because LuxCore objects can only have
        # one material, while Blender objects can have multiple, so one Blender object might be
        # split into multiple LuxCore objects on export and an index is added to the name
        particle_base_obj = bpy.data.objects["ParticleBase"]
        particle_base_obj_name = utils.get_luxcore_name(
            particle_base_obj, is_viewport_render=False) + "000"
        particle_base_mat = particle_base_obj.material_slots[0].material
        particle_base_mat_name = utils.get_luxcore_name(
            particle_base_mat, is_viewport_render=False)

        emitter_obj = bpy.data.objects["Emitter"]
        emitter_obj_name = utils.get_luxcore_name(
            emitter_obj, is_viewport_render=False) + "000"
        emitter_mat = emitter_obj.material_slots[0].material
        emitter_mat_name = utils.get_luxcore_name(emitter_mat,
                                                  is_viewport_render=False)

        # Check properties for correctness
        all_exported_obj_prefixes = scene_props.GetAllUniqueSubNames(
            "scene.objects")

        for prefix in all_exported_obj_prefixes:
            luxcore_name = prefix.split(".")[-1]

            if luxcore_name == particle_base_obj_name:
                self.assertEqual(
                    scene_props.Get(prefix + ".material").GetString(),
                    particle_base_mat_name)
                mat_prefix = "scene.materials." + particle_base_mat_name
                # LuxCore inserts an implicit property texture here (probably because we use DuplicateObject)
                kd_tex_name = scene_props.Get(mat_prefix + ".kd").GetString()
                kd_tex_prefix = "scene.textures." + kd_tex_name
                assertListsAlmostEqual(
                    self,
                    scene_props.Get(kd_tex_prefix + ".value").GetFloats(),
                    [0.7, 0.0, 0.0])
            elif luxcore_name == emitter_obj_name:
                self.assertEqual(
                    scene_props.Get(prefix + ".material").GetString(),
                    emitter_mat_name)
                mat_prefix = "scene.materials." + emitter_mat_name
                # LuxCore inserts an implicit property texture here (probably because we use DuplicateObject)
                kd_tex_name = scene_props.Get(mat_prefix + ".kd").GetString()
                kd_tex_prefix = "scene.textures." + kd_tex_name
                assertListsAlmostEqual(
                    self,
                    scene_props.Get(kd_tex_prefix + ".value").GetFloats(),
                    [0.0, 0.7, 0.0])
            else:
                # It is one of the instanced particles
                self.assertEqual(
                    scene_props.Get(prefix + ".material").GetString(),
                    particle_base_mat_name)
                mat_prefix = "scene.materials." + particle_base_mat_name
                # LuxCore inserts an implicit property texture here (probably because we use DuplicateObject)
                kd_tex_name = scene_props.Get(mat_prefix + ".kd").GetString()
                kd_tex_prefix = "scene.textures." + kd_tex_name
                assertListsAlmostEqual(
                    self,
                    scene_props.Get(kd_tex_prefix + ".value").GetFloats(),
                    [0.7, 0.0, 0.0])
    def test_obj_and_cam_blur(self):
        """
        One object ("moving_obj") and the camera ("moving_camera") are moving.
        Camera and object motion blur are enabled.
        """
        blender_scene = bpy.context.scene

        # Switch to the moving camera
        blender_scene.camera = bpy.data.objects["moving_camera"]

        # Switch to correct frame in case someone messed it up on save
        blender_scene.frame_set(TEST_FRAME, TEST_SUBFRAME)

        # Get the object that moves and should be blurred
        moving_obj = bpy.data.objects["moving_obj"]
        moving_obj_name = utils.get_luxcore_name(moving_obj,
                                                 is_viewport_render=False)

        # Make sure the settings are correct
        # (can only change if someone messes with the test scene)
        self.assertIsNotNone(blender_scene.camera)
        blur_settings = blender_scene.camera.data.luxcore.motion_blur
        self.assertTrue(blur_settings.enable)
        self.assertAlmostEqual(blur_settings.shutter, 4.0)
        self.assertTrue(blur_settings.object_blur)
        self.assertTrue(blur_settings.camera_blur)
        self.assertEqual(blur_settings.steps, 2)
        # Make sure we are at the correct frame
        self.assertEqual(blender_scene.frame_current, 3)
        self.assertAlmostEqual(blender_scene.frame_subframe, 0.0)

        # Export the scene
        scene_props = export(blender_scene)

        # Check properties for correctness
        all_exported_obj_prefixes = scene_props.GetAllUniqueSubNames(
            "scene.objects")

        for prefix in all_exported_obj_prefixes:
            luxcore_name = prefix.split(".")[-1]

            if luxcore_name == moving_obj_name:
                test_moving_object(self, scene_props, prefix)

        # Check if camera shutter settings are correct
        # Total shutter duration is 4.0 frames, so these should be -2.0 and 2.0
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.shutteropen").GetFloat(), -2.0)
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.shutterclose").GetFloat(), 2.0)

        # Check if camera transformation props are correct

        # Test the times
        # step 0. Shutter is 4.0 frames, so this step should be minus half of the shutter value
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.motion.0.time").GetFloat(), -2.0)
        # step 1. This should be half of the shutter value
        self.assertAlmostEqual(
            scene_props.Get("scene.camera.motion.1.time").GetFloat(), 2.0)

        # Test the transformation matrices

        # step 0. We are at X = 3m, Y = 0, Z = 0m
        translation = Matrix.Translation([3, 0, 0])
        rotation = Matrix.Rotation(math.radians(-90.0), 4, "X")
        scale = Matrix.Scale(1, 4)
        expected_step_0 = create_expected_matrix(blender_scene, translation,
                                                 rotation, scale)
        # For some reason we need to invert these two... my matrix math is rusty
        expected_step_0[6] *= -1
        expected_step_0[9] *= -1

        transformation_step_0 = scene_props.Get(
            "scene.camera.motion.0.transformation").GetFloats()
        assertListsAlmostEqual(self, transformation_step_0, expected_step_0)

        # step 1. We are at X = -3m, Y = 0, Z = 0m
        translation = Matrix.Translation([-3, 0, 0])
        rotation = Matrix.Rotation(math.radians(-90.0), 4, "X")
        scale = Matrix.Scale(1, 4)
        expected_step_1 = create_expected_matrix(blender_scene, translation,
                                                 rotation, scale)
        # For some reason we need to invert these two... my matrix math is rusty
        expected_step_1[6] *= -1
        expected_step_1[9] *= -1

        transformation_step_1 = scene_props.Get(
            "scene.camera.motion.1.transformation").GetFloats()
        assertListsAlmostEqual(self, transformation_step_1, expected_step_1)