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; }
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; }
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()); }
// 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; }
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()); }