Ejemplo n.º 1
0
    def _convert_matrix(m):
        """
        Converts a Blender matrix to an appleseed matrix

        We have the following conventions:

        Both Blender and appleseed use right-hand coordinate systems.
        Both Blender and appleseed use column-major matrices.
        Both Blender and appleseed use pre-multiplication.
        In Blender, given a matrix m, m[i][j] is the element at the i'th row, j'th column.

        The only difference between the coordinate systems of Blender and appleseed is the up vector:
        in Blender, up is Z+; in appleseed, up is Y+.  So we need to add a -90 degree rotation along the x
        axis to translate.
        :param m: Input Blender object matrix
        :return: appleseed transform of the modified matrix
        """

        matrix = asr.Matrix4d([
            m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2],
            m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1],
            m[3][2], m[3][3]
        ])

        rotation_modify = asr.Matrix4d.make_rotation(
            asr.Vector3d(1.0, 0.0, 0.0), math.radians(-90.0))

        matrix = rotation_modify * matrix

        return asr.Transformd(matrix)
Ejemplo n.º 2
0
def get_matrix(element):
    values = [float(x) for x in element.attrib["value"].split()]
    if len(values) != 16:
        fatal("Matrix was expected to contain 16 coefficients but contained {0} instead".format(len(values)))
    matrix = asr.Matrix4d()
    for i in range(16):
        matrix[int(i / 4), i % 4] = values[i]
    return matrix
Ejemplo n.º 3
0
 def __create_camera(self, scene):
     # Define the render camera
     camera = asr.Camera('pinhole_camera', "preview_camera", {"film_width": 0.032,
                                                              "focal_length": 0.035,
                                                              "aspect_ratio": util.get_frame_aspect_ratio(scene)})
     camera_matrix = asr.Matrix4d([1.0, 0.0, 0.0, -0.03582507744431496,
                                   0.0, -4.371138828673793e-08, -1.0, -2.135615587234497,
                                   0.0, 1.0, -4.371138828673793e-08, 0.5015512704849243,
                                   0.0, 0.0, 0.0, 1.0])
     camera.transform_sequence().set_transform(0.0, asr.Transformd(camera_matrix))
     self.__project.get_scene().cameras().insert(camera)
Ejemplo n.º 4
0
 def __create_lamp(self, preview_template_dir):
     # Define the single area lamp used for illumination
     lamp = asr.MeshObjectReader.read(self.__project.get_search_paths(), "lamp_obj",
                                      {'filename': os.path.join(preview_template_dir, 'material_preview_lamp.binarymesh')})
     lamp_matrix = asr.Matrix4d([0.8611875772476196, 0.508287250995636, 0.0, 0.0,
                                 -0.508287250995636, 0.8611875772476196, 0.0, 0.0,
                                 0.0, 0.0, 1.0, 0.0,
                                 0.0, 0.0, 0.0, 1.0])
     lamp_inst = asr.ObjectInstance("lamp", {}, "lamp_obj.part_0", asr.Transformd(lamp_matrix),
                                    {'default': "lamp_mat"}, {'default': "lamp_mat"})
     lamp_mat = asr.Material("generic_material", "lamp_mat", {'edf': "lamp_edf", 'surface_shader': "base_shader"})
     lamp_edf = asr.EDF("diffuse_edf", "lamp_edf", {'radiance': 7})
     return lamp, lamp_edf, lamp_inst, lamp_mat
Ejemplo n.º 5
0
    def update_obj_instance(self):
        self.__ass.object_instances().remove(self.__as_mesh_inst)

        self.__as_mesh_inst_params = self.__get_mesh_inst_params()

        self.__front_materials, self.__back_materials = self.__get_material_mappings(
        )

        mesh_name = self.__object_instance_mesh_name(self.orig_name)

        self.__as_mesh_inst = asr.ObjectInstance(
            self.__obj_inst_name, self.__as_mesh_inst_params, mesh_name,
            asr.Transformd(asr.Matrix4d().identity()), self.__front_materials,
            self.__back_materials)

        self.__ass.object_instances().insert(self.__as_mesh_inst)
        self.__as_mesh_inst = self.__ass.object_instances().get_by_name(
            self.__obj_inst_name)
Ejemplo n.º 6
0
    def update_object(self, context, depsgraph, as_assembly, textures_to_add,
                      as_texture_translators):
        logger.debug("Updating translator for %s", self.appleseed_name)
        mesh_name = self.__object_instance_mesh_name(
            f"{self.appleseed_name}_obj")

        self.__as_mesh_inst_params = self.__get_mesh_inst_params()
        self.__front_materials, self.__back_materials = self.__get_material_mappings(
        )

        self.__ass.object_instances().remove(self.__as_mesh_inst)

        self.__as_mesh_inst = asr.ObjectInstance(
            self.appleseed_name, self.__as_mesh_inst_params, mesh_name,
            asr.Transformd(asr.Matrix4d().identity()), self.__front_materials,
            self.__back_materials)

        self.__ass.object_instances().insert(self.__as_mesh_inst)
        self.__as_mesh_inst = self.__ass.object_instances().get_by_name(
            self.appleseed_name)
Ejemplo n.º 7
0
    def _convert_matrix(m):
        """
        Converts a Blender matrix to an appleseed matrix

         We have the following conventions:

           Both Blender and appleseed use right-hand coordinate systems.
           Both Blender and appleseed use column-major matrices.
           Both Blender and appleseed use pre-multiplication.
           In Blender, given a matrix m, m[i][j] is the element at the i'th row, j'th column.

         The only difference between the coordinate systems of Blender and appleseed is the up vector:
         in Blender, up is Z+; in appleseed, up is Y+.
        """

        matrix = asr.Matrix4d([m[0][0], m[0][1], m[0][2], m[0][3],
                               m[1][0], m[1][1], m[1][2], m[1][3],
                               m[2][0], m[2][1], m[2][2], m[2][3],
                               m[3][0], m[3][1], m[3][2], m[3][3]])

        return asr.Transformd(matrix)
Ejemplo n.º 8
0
    def flush_entities(self, as_assembly, as_project):
        logger.debug("Flushing entity for %s", self.appleseed_name)
        for instance in self.__instances.values():
            instance.optimize()

        mesh_name = f"{self.appleseed_name}_obj"

        if self.__export_mode == ProjectExportMode.PROJECT_EXPORT:
            # Replace the MeshObject by an empty one referencing
            # the binarymesh files we saved before.

            params = {}

            if len(self.__mesh_filenames) == 1:
                # No motion blur. Write a single filename.
                params['filename'] = "_geometry/" + self.__mesh_filenames[0]
            else:
                # Motion blur. Write one filename per motion pose.

                params['filename'] = {}

                for i, f in enumerate(self.__mesh_filenames):
                    params['filename'][str(i)] = "_geometry/" + f

            self.__as_mesh = asr.MeshObject(mesh_name, params)

        mesh_name = self.__object_instance_mesh_name(
            f"{self.appleseed_name}_obj")

        if self.__export_mode == ProjectExportMode.INTERACTIVE_RENDER or len(
                self.__instances) > 1:
            self.__has_assembly = True
        else:
            for instance in self.__instances.values():
                xform_seq = instance
                if xform_seq.size() > 1:
                    self.__has_assembly = True

        if self.__has_assembly:
            self.__as_mesh_inst = asr.ObjectInstance(
                self.appleseed_name, self.__as_mesh_inst_params, mesh_name,
                asr.Transformd(asr.Matrix4d().identity()),
                self.__front_materials, self.__back_materials)

            ass_name = f"{self.appleseed_name}_ass"

            self.__ass = asr.Assembly(ass_name)

            self.__ass.objects().insert(self.__as_mesh)
            self.__as_mesh = self.__ass.objects().get_by_name(mesh_name)

            self.__ass.object_instances().insert(self.__as_mesh_inst)
            self.__as_mesh_inst = self.__ass.object_instances().get_by_name(
                self.appleseed_name)

            as_assembly.assemblies().insert(self.__ass)
            self.__ass = as_assembly.assemblies().get_by_name(ass_name)

            for key, transform_matrix in self.__instances.items():
                ass_inst_name = f"{key}_ass_inst"
                ass_inst = asr.AssemblyInstance(ass_inst_name, {}, ass_name)
                ass_inst.set_transform_sequence(transform_matrix)
                as_assembly.assembly_instances().insert(ass_inst)
                self.__instances[key] = as_assembly.assembly_instances(
                ).get_by_name(ass_inst_name)

        else:
            self.__as_mesh_inst = asr.ObjectInstance(
                self.appleseed_name, self.__as_mesh_inst_params, mesh_name,
                xform_seq.get_earliest_transform(), self.__front_materials,
                self.__back_materials)

            as_assembly.objects().insert(self.__as_mesh)
            self.__as_mesh = as_assembly.objects().get_by_name(mesh_name)

            as_assembly.object_instances().insert(self.__as_mesh_inst)
            self.__as_mesh_inst = as_assembly.object_instances().get_by_name(
                self.appleseed_name)
Ejemplo n.º 9
0
    def update_lamp(self, depsgraph, as_main_assembly, as_scene, as_project):
        logger.debug(f"appleseed: Updating lamp entity for {self.orig_name}")
        as_lamp_data = self.bl_lamp.data.appleseed

        current_model = self.__lamp_model

        self.__lamp_model = self.__get_lamp_model()

        if current_model == self.__lamp_model:
            if self.__lamp_model != 'area_lamp':
                # Check if the radiance has changed.
                current_radiance = self.__radiance
                self.__radiance = self._convert_color(as_lamp_data.radiance)

                if current_radiance != self.__radiance:
                    as_main_assembly.colors().remove(self.__as_lamp_radiance)

                    lamp_radiance_name = f"{self.orig_name}_radiance"

                    self.__as_lamp_radiance = asr.ColorEntity(
                        lamp_radiance_name, {'color_space': 'linear_rgb'},
                        self.__radiance)

                    as_main_assembly.colors().insert(self.__as_lamp_radiance)
                    self.__as_lamp_radiance = as_main_assembly.colors(
                    ).get_by_name(lamp_radiance_name)

                # Update lamp parameters.
                if self.__lamp_model == 'point_light':
                    self.__as_lamp_params = self.__get_point_lamp_params()
                if self.__lamp_model == 'spot_light':
                    self.__as_lamp_params = self.__get_spot_lamp_params()
                if self.__lamp_model == 'directional_light':
                    self.__as_lamp_params = self.__get_directional_lamp_params(
                    )
                if self.__lamp_model == 'sun_light':
                    self.__as_lamp_params = self.__get_sun_lamp_params()

                self.__as_lamp.set_parameters(self.__as_lamp_params)
            else:
                self.__ass.object_instances().remove(self.__as_area_lamp_inst)
                self.__ass.objects().remove(self.__as_area_lamp_mesh)

                shape_params = self._get_area_mesh_params()
                mesh_name = f"{self.orig_name}_mesh"
                mat_name = f"{self.orig_name}_mat"

                self.__as_area_lamp_mesh = asr.create_primitive_mesh(
                    mesh_name, shape_params)

                self.__instance_params = self._get_area_mesh_instance_params()

                self.__as_area_lamp_inst = asr.ObjectInstance(
                    self.__as_area_lamp_inst_name, self.__instance_params,
                    mesh_name, asr.Transformd(asr.Matrix4d().identity()),
                    {"default": mat_name}, {"default": "__null_material"})

                self.__ass.objects().insert(self.__as_area_lamp_mesh)
                self.__as_area_lamp_mesh = self.__ass.objects().get_by_name(
                    mesh_name)

                self.__ass.object_instances().insert(self.__as_area_lamp_inst)
                self.__as_area_lamp_inst = self.__ass.object_instances(
                ).get_by_name(self.__as_area_lamp_inst_name)

                if self.bl_lamp.data.use_nodes:
                    if self.__as_area_lamp_shadergroup is not None:
                        as_main_assembly.shader_groups().remove(
                            self.__as_area_lamp_shadergroup)
                        self.__as_area_lamp_shadergroup = None
                        self.__node_tree = NodeTreeTranslator(
                            self.bl_lamp.data.node_tree, self._asset_handler,
                            self.orig_name)
                        self.__node_tree.create_entities(depsgraph.scene_eval)
                    else:
                        self.__node_tree.update_nodetree(depsgraph.scene_eval)
                else:
                    if self.__node_tree is not None:
                        self.__node_tree.delete_nodetree(as_main_assembly)
                        self.__node_tree = None

                        shader_name = f"{self.orig_name}_tree"

                        self.__as_area_lamp_shadergroup = asr.ShaderGroup(
                            shader_name)
                        self._set_shadergroup()
                    else:
                        self._set_shadergroup()

        else:
            # Delete current light.
            if current_model != 'area_lamp':
                self.__ass.lights().remove(self.__as_lamp)

                as_main_assembly.colors().remove(self.__as_lamp_radiance)
            else:
                self.__ass.objects().remove(self.__as_area_lamp_mesh)
                self.__ass.object_instances().remove(self.__as_area_lamp_inst)
                as_main_assembly.materials().remove(
                    self.__as_area_lamp_material)

                if self.__as_area_lamp_shadergroup is not None:
                    as_main_assembly.shader_groups().remove(
                        self.__as_area_lamp_shadergroup)
                    self.__as_area_lamp_shadergroup = None
                else:
                    self.__node_tree.delete_nodetree(as_main_assembly)

            # Create new light.
            self.create_entities(depsgraph, 0)

            if self.__lamp_model != 'area_lamp':
                radiance_name = self.__as_lamp_radiance.get_name()
                as_main_assembly.colors().insert(self.__as_lamp_radiance)
                self.__as_lamp_radiance = as_main_assembly.colors(
                ).get_by_name(radiance_name)

                self.__ass.lights().insert(self.__as_lamp)
                self.__as_lamp = self.__ass.lights().get_by_name(
                    self.orig_name)
            else:
                mat_name = f"{self.orig_name}_mat"

                mesh_name = f"{self.orig_name}_mesh"

                self.__as_area_lamp_inst_name = f"{self.orig_name}_inst"

                as_main_assembly.materials().insert(
                    self.__as_area_lamp_material)
                self.__as_area_lamp_material = as_main_assembly.materials(
                ).get_by_name(mat_name)

                if self.__as_area_lamp_shadergroup is not None:
                    shadergroup_name = self.__as_area_lamp_shadergroup.get_name(
                    )
                    as_main_assembly.shader_groups().insert(
                        self.__as_area_lamp_shadergroup)
                    self.__as_area_lamp_shadergroup = as_main_assembly.shader_groups(
                    ).get_by_name(shadergroup_name)
                else:
                    self.__node_tree.flush_entities(as_scene, as_main_assembly,
                                                    as_project)

                self.__as_area_lamp_inst = asr.ObjectInstance(
                    self.__as_area_lamp_inst_name, self.__instance_params,
                    mesh_name, asr.Transformd(asr.Matrix4d().identity()),
                    {"default": mat_name}, {"default": "__null_material"})

                self.__ass.objects().insert(self.__as_area_lamp_mesh)
                self.__as_area_lamp_mesh = self.__ass.objects().get_by_name(
                    mesh_name)

                self.__ass.object_instances().insert(self.__as_area_lamp_inst)
                self.__as_area_lamp_inst = self.__ass.object_instances(
                ).get_by_name(self.__as_area_lamp_inst_name)
Ejemplo n.º 10
0
    def flush_entities(self, as_scene, as_main_assembly, as_project):
        logger.debug(
            f"appleseed: Flushing lamp entity for {self.orig_name} to project")
        self.__instance_lib.optimize_xforms()

        needs_assembly = self.__export_mode == ProjectExportMode.INTERACTIVE_RENDER or self.__instance_lib.needs_assembly(
        )

        if self.__lamp_model != 'area_lamp':
            radiance_name = self.__as_lamp_radiance.get_name()
            as_main_assembly.colors().insert(self.__as_lamp_radiance)
            self.__as_lamp_radiance = as_main_assembly.colors().get_by_name(
                radiance_name)

            if needs_assembly:
                self.__ass_name = f"{self.orig_name}_ass"
                self.__ass = asr.Assembly(self.__ass_name)

                self.__ass.lights().insert(self.__as_lamp)
                self.__as_lamp = self.__ass.lights().get_by_name(
                    self.orig_name)

                as_main_assembly.assemblies().insert(self.__ass)
                self.__ass = as_main_assembly.assemblies().get_by_name(
                    self.__ass_name)

                self.flush_instances(as_main_assembly)
            else:
                self.__as_lamp.set_transform(
                    self.__instance_lib.get_single_transform())
                as_main_assembly.lights().insert(self.__as_lamp)
                self.__as_lamp = as_main_assembly.lights().get_by_name(
                    self.obj_name)

        else:
            mat_name = f"{self.orig_name}_mat"

            mesh_name = f"{self.orig_name}_mesh"

            self.__as_area_lamp_inst_name = f"{self.orig_name}_inst"

            as_main_assembly.materials().insert(self.__as_area_lamp_material)
            self.__as_area_lamp_material = as_main_assembly.materials(
            ).get_by_name(mat_name)

            if self.__as_area_lamp_shadergroup is not None:
                shadergroup_name = self.__as_area_lamp_shadergroup.get_name()
                as_main_assembly.shader_groups().insert(
                    self.__as_area_lamp_shadergroup)
                self.__as_area_lamp_shadergroup = as_main_assembly.shader_groups(
                ).get_by_name(shadergroup_name)
            else:
                self.__node_tree.flush_entities(as_scene, as_main_assembly,
                                                as_project)

            if needs_assembly:
                self.__as_area_lamp_inst = asr.ObjectInstance(
                    self.__as_area_lamp_inst_name, self.__instance_params,
                    mesh_name, asr.Transformd(asr.Matrix4d().identity()),
                    {"default": mat_name}, {"default": "__null_material"})

                self.__ass_name = f"{self.orig_name}_ass"

                self.__ass = asr.Assembly(self.__ass_name)

                self.__ass.objects().insert(self.__as_area_lamp_mesh)
                self.__as_area_lamp_mesh = self.__ass.objects().get_by_name(
                    mesh_name)

                self.__ass.object_instances().insert(self.__as_area_lamp_inst)
                self.__as_area_lamp_inst = self.__ass.object_instances(
                ).get_by_name(self.__as_area_lamp_inst_name)

                as_main_assembly.assemblies().insert(self.__ass)
                self.__ass = as_main_assembly.assemblies().get_by_name(
                    self.__ass_name)

                self.flush_instances(as_main_assembly)

            else:
                self.__as_area_lamp_inst = asr.ObjectInstance(
                    self.__as_area_lamp_inst_name, self.__instance_params,
                    mesh_name, self.__instance_lib.get_single_transform(),
                    {"default": mat_name}, {"default": "__null_material"})

                as_main_assembly.objects().insert(self.__as_area_lamp_mesh)
                self.__as_area_lamp_mesh = as_main_assembly.objects(
                ).get_by_name(mesh_name)

                as_main_assembly.object_instances().insert(
                    self.__as_area_lamp_inst)
                self.__as_mesh_inst = as_main_assembly.object_instances(
                ).get_by_name(self.__as_area_lamp_inst_name)
Ejemplo n.º 11
0
    def _convert_matrix(self, m):
        matrix = asr.Matrix4d(super()._convert_matrix(m))

        return asr.Transformd(matrix)
Ejemplo n.º 12
0
    def flush_entities(self, assembly):
        # Compute tangents if needed.
        if self.__export_mode != ProjectExportMode.PROJECT_EXPORT:
            if self.bl_obj.data.appleseed.smooth_tangents and self.bl_obj.data.appleseed.export_uvs:
                asr.compute_smooth_vertex_tangents(self.__mesh_object)

        asr_obj_props = self.bl_obj.appleseed

        mesh_name = self.__mesh_object.get_name()
        object_instance_params = {'visibility': {'camera': asr_obj_props.camera_visible,
                                                 'light': asr_obj_props.light_visible,
                                                 'shadow': asr_obj_props.shadow_visible,
                                                 'diffuse': asr_obj_props.diffuse_visible,
                                                 'glossy': asr_obj_props.glossy_visible,
                                                 'specular': asr_obj_props.specular_visible,
                                                 'transparency': asr_obj_props.transparency_visible},
                                  'medium_priority': asr_obj_props.medium_priority,
                                  'ray_bias_method': asr_obj_props.object_ray_bias_method,
                                  'ray_bias_distance': asr_obj_props.object_ray_bias_distance}

        if asr_obj_props.object_sss_set != "":
            object_instance_params['sss_set_id'] = asr_obj_props.object_sss_set

        if self.__export_mode == ProjectExportMode.PROJECT_EXPORT:
            # Replace the MeshObject by an empty one referencing
            # the binarymesh files we saved before.

            params = {}

            if len(self.__mesh_filenames) == 1:
                # No motion blur. Write a single filename.
                params['filename'] = "_geometry/" + self.__mesh_filenames[0]
            else:
                # Motion blur. Write one filename per motion pose.

                params['filename'] = {}

                for i, f in enumerate(self.__mesh_filenames):
                    params['filename'][str(i)] = "_geometry/" + f

            self.__mesh_object = asr.MeshObject(mesh_name, params)

        self._xform_seq.optimize()

        logger.debug(
            "Flushing object %s, num instances = %s, num xform keys = %s",
            self.appleseed_name,
            self._num_instances,
            self._xform_seq.size())

        if self.__export_mode == ProjectExportMode.INTERACTIVE_RENDER:
            # We always create assemblies when doing IPR to allow quick xform edits.
            needs_assembly = True
        else:
            # Only create an assembly if the object is instanced or has xform motion blur.
            needs_assembly = self._num_instances > 1 or self._xform_seq.size() > 1

        if needs_assembly:
            logger.debug("Creating assembly for object %s, name: %s", mesh_name, self.assembly_name)

            ass = asr.Assembly(self.assembly_name)

            logger.debug("Creating object instance for object %s, name: %s", mesh_name, self.appleseed_name)

            obj_inst = asr.ObjectInstance(
                self.appleseed_name,
                object_instance_params,
                self.__object_instance_mesh_name(mesh_name),
                asr.Transformd(asr.Matrix4d().identity()),
                self.__front_materials,
                self.__back_materials)

            ass.objects().insert(self.__mesh_object)
            self.__mesh_object = ass.objects().get_by_name(mesh_name)

            obj_inst_name = obj_inst.get_name()
            ass.object_instances().insert(obj_inst)
            self.__obj_inst = ass.object_instances().get_by_name(obj_inst_name)

            assembly_instance_name = self.assembly_name + "_inst"

            logger.debug("Creating assembly instance for object %s, name: %s", mesh_name, assembly_instance_name)

            ass_name = self._insert_entity_with_unique_name(assembly.assemblies(), ass, ass.get_name())
            self.__ass = assembly.assemblies().get_by_name(ass_name)

            ass_inst = asr.AssemblyInstance(
                assembly_instance_name,
                {},
                ass_name)
            ass_inst.set_transform_sequence(self._xform_seq)

            ass_inst_name = self._insert_entity_with_unique_name(assembly.assembly_instances(), ass_inst, ass_inst.get_name())
            self.__ass_inst = assembly.assembly_instances().get_by_name(ass_inst_name)

            if self.__alpha_tex is not None:
                self.__ass.textures().insert(self.__alpha_tex)
            if self.__alpha_tex_inst is not None:
                self.__ass.texture_instances().insert(self.__alpha_tex_inst)

        else:
            logger.debug("Creating object instance for object %s, name: %s", mesh_name, self.appleseed_name)

            mesh_name = self._insert_entity_with_unique_name(assembly.objects(), self.__mesh_object, mesh_name)
            self.__mesh_object = assembly.objects().get_by_name(mesh_name)

            obj_inst = asr.ObjectInstance(
                self.appleseed_name,
                object_instance_params,
                self.__object_instance_mesh_name(mesh_name),
                self._xform_seq.get_earliest_transform(),
                self.__front_materials,
                self.__back_materials)

            obj_inst_name = self._insert_entity_with_unique_name(assembly.object_instances(), obj_inst, obj_inst.get_name())
            self.__obj_inst = assembly.object_instances().get_by_name(obj_inst_name)

            if self.__alpha_tex is not None:
                assembly.textures().insert(self.__alpha_tex)
            if self.__alpha_tex_inst is not None:
                assembly.texture_instances().insert(self.__alpha_tex_inst)
Ejemplo n.º 13
0
    def flush_entities(self, as_scene, as_main_assembly, as_project):
        logger.debug(
            "appleseed: Flusing mesh entity for {self.orig_name} into project")

        if self.__export_mode == ProjectExportMode.PROJECT_EXPORT:
            # Replace the MeshObject by an empty one referencing
            # the binarymesh files we saved before.

            params = {}

            if len(self.__mesh_filenames) == 1:
                # No motion blur. Write a single filename.
                params['filename'] = f"_geometry/{self.__mesh_filenames[0]}"
            else:
                # Motion blur. Write one filename per motion pose.

                params['filename'] = dict()

                for i, f in enumerate(self.__mesh_filenames):
                    params['filename'][str(i)] = f"_geometry/{f}"

            self.__as_mesh = asr.MeshObject(self.orig_name, params)

        mesh_name = self.__object_instance_mesh_name(self.orig_name)

        self.__obj_inst_name = f"{self.orig_name}_inst"

        self.__instance_lib.optimize_xforms()

        needs_assembly = self.__export_mode == ProjectExportMode.INTERACTIVE_RENDER or self.__instance_lib.needs_assembly(
        )

        if needs_assembly:
            self.__ass_name = f"{self.orig_name}_ass"
            self.__ass = asr.Assembly(self.__ass_name)

            self.__as_mesh_inst = asr.ObjectInstance(
                self.__obj_inst_name, self.__as_mesh_inst_params, mesh_name,
                asr.Transformd(asr.Matrix4d().identity()),
                self.__front_materials, self.__back_materials)

            self.__ass.objects().insert(self.__as_mesh)
            self.__as_mesh = self.__ass.objects().get_by_name(mesh_name)

            self.__ass.object_instances().insert(self.__as_mesh_inst)
            self.__as_mesh_inst = self.__ass.object_instances().get_by_name(
                self.__obj_inst_name)

            as_main_assembly.assemblies().insert(self.__ass)
            self.__ass = as_main_assembly.assemblies().get_by_name(
                self.__ass_name)

            self.flush_instances(as_main_assembly)

        else:
            self.__as_mesh_inst = asr.ObjectInstance(
                self.__obj_inst_name, self.__as_mesh_inst_params, mesh_name,
                self.__instance_lib.get_single_transform(),
                self.__front_materials, self.__back_materials)

            as_main_assembly.objects().insert(self.__as_mesh)
            self.__as_mesh = as_main_assembly.objects().get_by_name(mesh_name)

            as_main_assembly.object_instances().insert(self.__as_mesh_inst)
            self.__as_mesh_inst = as_main_assembly.object_instances(
            ).get_by_name(self.__obj_inst_name)