/* This file is part of the Gudhi Library. The Gudhi library * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * * Author(s): Clement Jamin * * Copyright (C) 2016 Inria * * Modification(s): * - YYYY/MM Author: Description of the modification */ #ifndef GUDHI_TC_RIB_EXPORTER_H #define GUDHI_TC_RIB_EXPORTER_H #include #include #include template class RIB_exporter { typedef typename PointRandomAccessRange::value_type Point; typedef typename SimplexRange::value_type Simplex; public: typedef std::tuple Color; // RGBA typedef std::tuple Coords_choice; // Constructor RIB_exporter( PointRandomAccessRange const& points, SimplexRange const& simplices, std::ofstream &out, std::string const& rendered_image_filename = "export.tif", bool is_preview = false, // low-quality Coords_choice coords_choice = std::make_tuple(0, 1, 2), int image_width = 1920, int image_height = 1080, Color const& triangle_color = std::make_tuple(1., 1., 1., 1.), bool ambient_light = true, double ambient_intensity = 0.3, bool shadow = true, double shadow_intensity = 0.85, double point_sphere_radius = 0.003) : m_points(points), m_simplices(simplices), m_out(out), m_rendered_image_filename(rendered_image_filename), m_is_preview(is_preview), m_coords_choice(coords_choice), m_image_width(image_width), m_image_height(image_height), m_current_color(0., 0., 0., 0.), m_current_alpha(1), m_triangle_color(triangle_color), m_ambient_light(ambient_light), m_ambient_intensity(ambient_intensity), m_shadow(shadow), m_shadow_intensity(shadow_intensity), m_point_sphere_radius(point_sphere_radius) { m_out.precision(8); } void write_file() { write_header(); write_lights(); /*if (m_point_sphere_radius != 0.) write_point_spheres();*/ write_triangles(); m_out << "WorldEnd\n"; } private: void write_header() { m_out << "Option \"searchpath\" \"shader\" " "\".:./shaders:%PIXIE_SHADERS%:%PIXIEHOME%/shaders\"\n"; if (m_is_preview) { m_out << "Attribute \"visibility\" \"specular\" 1\n" << "Attribute \"visibility\" \"transmission\" 1\n\n"; } m_out << "Display \"" << m_rendered_image_filename << "\" \"file\" \"rgb\"\n"; if (!m_is_preview) { m_out << "Format " << m_image_width << " " << m_image_height << " 1\n"; } else { double ratio = double(m_image_height) / double(m_image_width); int width = (ratio < 1.) ? 300 : int(300. / ratio); int height = (ratio < 1.) ? int(ratio * 300.) : 300; m_out << "Format " << width << " " << height << " 1\n"; } if (m_image_width > m_image_height) { double ratio = double(m_image_height) / double(m_image_width); m_out << "ScreenWindow -1 1 " << -ratio << " " << ratio << "\n"; } else if (m_image_height > m_image_width) { double ratio = double(m_image_width) / double(m_image_height); m_out << "ScreenWindow " << -ratio << " " << ratio << " -1 1\n"; } m_out << "Projection \"perspective\" \"fov\" 45\n" << "Translate 0 0 3\n" << "PixelSamples 4 4\n" << "PixelFilter \"catmull-rom\" 3 3\n" << "ShadingInterpolation \"smooth\"\n" << "Rotate -10 20 0 1\n" << "WorldBegin\n"; } void write_lights() { if (!m_is_preview) { // ShadowLight m_out << "LightSource \"shadowdistant\" 1 \"from\" [0 0 0] \"to\" [0 0 1]" << " \"shadowname\" \"raytrace\" \"intensity\" " << m_shadow_intensity << "\n"; // Ambient light m_out << "LightSource \"ambientlight\" 2 \"intensity\" " << m_ambient_intensity << "\n"; } else { m_out << "LightSource \"distantLight\" 1 \"from\" [0 0 0] \"to\" [0 0 1]" << " \"intensity\" " << m_shadow_intensity << "\n"; // Ambient light m_out << "LightSource \"ambientlight\" 2 \"intensity\" " << m_ambient_intensity << "\n"; } // Background light m_out << "LightSource \"ambientlight\" 99 \"intensity\" 1\n"; // Turn background light OFF turn_background_light(false); } void turn_background_light(bool turn_on) { if (!turn_on) { m_out << "Illuminate 1 1" << std::endl; if (!m_is_preview) m_out << "Illuminate 2 1" << std::endl; m_out << "Illuminate 99 0" << std::endl; } else { m_out << "Illuminate 1 0" << std::endl; if (!m_is_preview) m_out << "Illuminate 2 0" << std::endl; m_out << "Illuminate 99 1" << std::endl; } } void write_color(Color const& color, bool use_transparency) { if (m_current_color == color) return; m_current_color = color; // Write opacity data if (use_transparency) write_opacity(std::get<3>(color)); // Write color data m_out << "Color [ " << std::get<0>(color) << " " << std::get<1>(color) << " " << std::get<2>(color) << " ]\n"; } void write_opacity(const double alpha) { if (m_current_alpha == alpha) return; m_current_alpha = alpha; // Write opacity data m_out << "Opacity " << alpha << " " << alpha << " " << alpha << std::endl; } void write_point(Point const& p) { m_out << " " << p[std::get<0>(m_coords_choice)] << " " << p[std::get<1>(m_coords_choice)] << " " << p[std::get<2>(m_coords_choice)] << " "; } void write_triangles() { m_out << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.85 \"Ks\" 0.25 \"roughness\" 0.1" << std::endl; for (auto const& simplex : m_simplices) { std::vector triangles; // Get the triangles composing the simplex combinations(simplex, 3, std::back_inserter(triangles)); for (auto const& t : triangles) write_triangle(t); } } template void write_triangle(PointIndexRange const& t) { // Color write_color(m_triangle_color, true); // Triangle m_out << "Polygon \"P\" ["; for (auto idx : t) write_point(m_points[idx]); m_out << "]" << std::endl; // Edges (will be drawn later on) /*add_edge(p, q, edge_color); add_edge(p, r, edge_color); add_edge(q, r, edge_color); // Vertices (will be drawn later on) add_vertex(p, edge_color); add_vertex(q, edge_color); add_vertex(r, edge_color);*/ } void write_point_sphere(Point const& p) { if (m_point_sphere_radius == 0.) return; m_out << "Translate " << p[0] << " " << p[1] << " " << p[2] << std::endl; // Sphere radius zmin zmax thetamax m_out << "Sphere " << m_point_sphere_radius << " " << -m_point_sphere_radius << " " << m_point_sphere_radius << " 360" << std::endl; m_out << "Identity" << std::endl; } void write_point_spheres() { write_color(std::make_tuple(0.7, 0.7, 0.7, 0.5), true); for (auto const& p : m_points) write_point_sphere(p); } //=========================================================================== PointRandomAccessRange const& m_points; SimplexRange const& m_simplices; std::ofstream &m_out; std::string m_rendered_image_filename; bool m_is_preview; Coords_choice m_coords_choice; int m_image_width; int m_image_height; Color m_current_color; Color m_triangle_color; double m_current_alpha; bool m_ambient_light; double m_ambient_intensity; bool m_shadow; double m_shadow_intensity; double m_point_sphere_radius; }; #endif // GUDHI_TC_RIB_EXPORTER_H