예제 #1
0
bool Frame::write_image(
    const char*             file_path,
    const Image&            image,
    const ImageAttributes&  image_attributes) const
{
    assert(file_path);

    Image final_image(image);
    transform_to_output_color_space(final_image);

    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    try
    {
        try
        {
            GenericImageFileWriter writer;
            writer.write(file_path, final_image, image_attributes);
        }
        catch (const ExceptionUnsupportedFileFormat&)
        {
            const string extension = lower_case(filesystem::path(file_path).extension());

            RENDERER_LOG_ERROR(
                "file format '%s' not supported, writing the image in OpenEXR format "
                "(but keeping the filename unmodified).",
                extension.c_str());

            EXRImageFileWriter writer;
            writer.write(file_path, final_image, image_attributes);
        }
    }
    catch (const ExceptionIOError&)
    {
        RENDERER_LOG_ERROR(
            "failed to write image file %s: i/o error.",
            file_path);

        return false;
    }
    catch (const Exception& e)
    {
        RENDERER_LOG_ERROR(
            "failed to write image file %s: %s.",
            file_path,
            e.what());

        return false;
    }

    stopwatch.measure();

    RENDERER_LOG_INFO(
        "wrote image file %s in %s.",
        file_path,
        pretty_time(stopwatch.get_seconds()).c_str());

    return true;
}
예제 #2
0
bool MeshObjectWriter::write(
    const MeshObject&   object,
    const char*         object_name,
    const char*         filename)
{
    assert(filename);

    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    try
    {
        GenericMeshFileWriter writer(filename);
        MeshObjectWalker walker(object, object_name);
        writer.write(walker);
    }
    catch (const exception& e)
    {
        RENDERER_LOG_ERROR(
            "failed to write mesh file %s: %s.",
            filename,
            e.what());
        return false;
    }

    stopwatch.measure();

    RENDERER_LOG_INFO(
        "wrote mesh file %s in %s.",
        filename,
        pretty_time(stopwatch.get_seconds()).c_str());

    return true;
}
예제 #3
0
CurveTree::CurveTree(const Arguments& arguments)
  : TreeType(AlignedAllocator<void>(System::get_l1_data_cache_line_size()))
  , m_arguments(arguments)
{
    // Retrieve construction parameters.
    const MessageContext message_context(
        format("while building curve tree for assembly \"{0}\"", m_arguments.m_assembly.get_path()));
    const ParamArray& params = m_arguments.m_assembly.get_parameters().child("acceleration_structure");
    const string algorithm = params.get_optional<string>("algorithm", "bvh", make_vector("bvh", "sbvh"), message_context);
    const double time = params.get_optional<double>("time", 0.5);

    // Start stopwatch.
    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    // Build the tree.
    Statistics statistics;
    if (algorithm == "bvh")
        build_bvh(params, time, statistics);
    else throw ExceptionNotImplemented();

    // Print curve tree statistics.
    statistics.insert_size("nodes alignment", alignment(&m_nodes[0]));
    statistics.insert_time("total time", stopwatch.measure().get_seconds());
    RENDERER_LOG_DEBUG("%s",
        StatisticsVector::make(
            "curve tree #" + to_string(m_arguments.m_curve_tree_uid) + " statistics",
            statistics).to_string().c_str());
}
예제 #4
0
    // Render the project.
    MasterRenderer::RenderingResult render()
    {
        // RenderingResult is initialized to Failed.
        RenderingResult result;

        // Perform basic integrity checks on the scene.
        if (!check_scene())
            return result;

        // Initialize thread-local variables.
        Spectrum::set_mode(get_spectrum_mode(m_params));

        // Reset the frame's render info.
        m_project.get_frame()->render_info().clear();

        try
        {
            // Render.
            m_stopwatch.start();
            result.m_status = do_render();
            m_stopwatch.measure();
            result.m_render_time = m_stopwatch.get_seconds();

            // Insert render time into the frame's render info.
            // Note that the frame entity may have replaced during rendering.
            ParamArray& render_info = m_project.get_frame()->render_info();
            render_info.insert("render_time", result.m_render_time);

            // Don't proceed further if rendering failed.
            if (result.m_status != RenderingResult::Succeeded)
                return result;

            // Post-process.
            m_stopwatch.start();
            postprocess(result);
            m_stopwatch.measure();
            result.m_post_processing_time = m_stopwatch.get_seconds();
            render_info.insert("post_processing_time", result.m_post_processing_time);
        }
        catch (const bad_alloc&)
        {
            m_renderer_controller->on_rendering_abort();
            RENDERER_LOG_ERROR("rendering failed (ran out of memory).");
            result.m_status = RenderingResult::Failed;
        }
#ifdef NDEBUG
        catch (const exception& e)
        {
            m_renderer_controller->on_rendering_abort();
            RENDERER_LOG_ERROR("rendering failed (%s).", e.what());
            result.m_status = RenderingResult::Failed;
        }
        catch (...)
        {
            m_renderer_controller->on_rendering_abort();
            RENDERER_LOG_ERROR("rendering failed (unknown exception).");
            result.m_status = RenderingResult::Failed;
        }
#endif

        return result;
    }
예제 #5
0
EmbreeScene::EmbreeScene(const EmbreeScene::Arguments& arguments)
{
    // Start stopwatch.
    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    Statistics statistics;

    m_device = arguments.m_device.m_device;
    m_scene = rtcNewScene(m_device);

    rtcSetSceneBuildQuality(
        m_scene,
        RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

    const ObjectInstanceContainer& instance_container = arguments.m_assembly.object_instances();

    const size_t instance_count = instance_container.size();

    m_geometry_container.reserve(instance_count);

    for (size_t instance_idx = 0; instance_idx < instance_count; ++instance_idx)
    {
        const ObjectInstance* object_instance = instance_container.get_by_index(instance_idx);
        assert(object_instance);

        RTCGeometry geometry_handle;

        // Set per instance data.
        unique_ptr<EmbreeGeometryData> geometry_data(new EmbreeGeometryData());
        geometry_data->m_object_instance_idx = instance_idx;
        geometry_data->m_vis_flags = object_instance->get_vis_flags();

        //
        // Collect geometry data for the instance.
        //
        const char* object_model = object_instance->get_object().get_model();

        if (strcmp(object_model, MeshObjectFactory().get_model()) == 0)
        {
            geometry_data->m_geometry_type = RTC_GEOMETRY_TYPE_TRIANGLE;

            // Retrieve triangle data.
            collect_triangle_data(*object_instance, *geometry_data);

            geometry_handle = rtcNewGeometry(
                m_device,
                RTC_GEOMETRY_TYPE_TRIANGLE);

            rtcSetGeometryBuildQuality(
                geometry_handle,
                RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

            rtcSetGeometryTimeStepCount(
                geometry_handle,
                geometry_data->m_motion_steps_count);

            geometry_data->m_geometry_handle = geometry_handle;

            const unsigned int vertices_count = geometry_data->m_vertices_count;
            const unsigned int vertices_stride = geometry_data->m_vertices_stride;

            for (unsigned int m = 0; m < geometry_data->m_motion_steps_count; ++m)
            {
                // Byte offset for the current motion segment.
                const unsigned int vertices_offset = m * vertices_count * vertices_stride;

                // Set vertices.
                rtcSetSharedGeometryBuffer(
                    geometry_handle,                            // geometry
                    RTC_BUFFER_TYPE_VERTEX,                     // buffer type
                    m,                                          // slot
                    RTC_FORMAT_FLOAT3,                          // format
                    geometry_data->m_vertices,                  // buffer
                    vertices_offset,                            // byte offset
                    vertices_stride,                            // byte stride
                    vertices_count);                            // item count
            }

            // Set vertex indices.
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_UINT3,                               // format
                geometry_data->m_primitives,                    // buffer
                0,                                              // byte offset
                geometry_data->m_primitives_stride,             // byte stride
                geometry_data->m_primitives_count);             // item count

            rtcSetGeometryMask(
                geometry_handle,
                geometry_data->m_vis_flags);

            rtcCommitGeometry(geometry_handle);
        }
        else if (strcmp(object_model, CurveObjectFactory().get_model()) == 0)
        {
            geometry_data->m_geometry_type = RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;

            // Retrieve curve data.
            collect_curve_data(*object_instance, *geometry_data);

            geometry_handle = rtcNewGeometry(
                m_device,
                RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);

            rtcSetGeometryBuildQuality(
                geometry_handle,
                RTCBuildQuality::RTC_BUILD_QUALITY_HIGH);

            // Set vertices. (x_pos, y_pos, z_pos, radii)
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_FLOAT4,                              // format
                geometry_data->m_vertices,                      // buffer
                0,                                              // byte offset
                geometry_data->m_vertices_stride,               // byte stride
                geometry_data->m_vertices_count);               // item count

            // Set vertex indices.
            rtcSetSharedGeometryBuffer(
                geometry_handle,                                // geometry
                RTC_BUFFER_TYPE_INDEX,                          // buffer type
                0,                                              // slot
                RTC_FORMAT_UINT4,                               // format
                geometry_data->m_primitives,                    // buffer
                0,                                              // byte offset
                geometry_data->m_primitives_stride,             // byte stride
                geometry_data->m_primitives_count);             // item count

        }
        else
        {
            // Unsupported object type.
            continue;
        }

        rtcAttachGeometryByID(m_scene, geometry_handle, static_cast<unsigned int>(instance_idx));
        m_geometry_container.push_back(std::move(geometry_data));
    }

    rtcCommitScene(m_scene);

    statistics.insert_time("total build time", stopwatch.measure().get_seconds());

    RENDERER_LOG_DEBUG("%s",
        StatisticsVector::make(
            "Embree scene #" + to_string(arguments.m_assembly.get_uid()) + " statistics",
            statistics).to_string().c_str());
}