14#include <lagrange/Logger.h>
15#include <lagrange/Mesh.h>
16#include <lagrange/common.h>
17#include <lagrange/fs/filesystem.h>
18#include <lagrange/utils/range.h>
47template <
typename DerivedV,
typename DerivedF>
49 const fs::path& filename,
50 const Eigen::MatrixBase<DerivedV>& vertices,
51 const Eigen::MatrixBase<DerivedF>& facets,
54 using Scalar =
typename DerivedV::Scalar;
55 std::ofstream fout(filename.c_str());
57 const auto num_facets = facets.rows();
59 const Eigen::Matrix<Scalar, 1, 2> bbox_min = vertices.colwise().minCoeff().eval();
60 const Eigen::Matrix<Scalar, 1, 2> bbox_max = vertices.colwise().maxCoeff().eval();
62 std::string footer =
"</svg>";
65 float width = settings.width;
66 float height = settings.height;
67 if (settings.width <= 0) {
68 width = float(bbox_max[0] - bbox_min[0]) * settings.scaling_factor;
70 if (settings.height <= 0) {
71 height = float(bbox_max[1] - bbox_min[1]) * settings.scaling_factor;
75 "<?xml version=\"1.0\" encoding=\"utf-8\"?> <svg version=\"1.1\" id=\"Layer_1\" "
76 "xmlns=\"http://www.w3.org/2000/svg\" "
77 "xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" "
78 "y=\"0px\" viewBox=\"0 0 {} {}\" "
79 "style=\"enable-background:new 0 0 {} {};\" "
80 "xml:space=\"preserve\"> <style type=\"text/css\"> "
81 ".st0{{fill:{}; stroke:{}; stroke-miterlimit:10; stroke-width:{}px; "
82 "stroke-linejoin:\"round\";}} "
88 settings.with_fill ? fmt::format(
"#{:06x}", settings.fill_color) :
"none",
89 settings.with_stroke ? fmt::format(
"#{:06x}", settings.stroke_color) :
"none",
90 settings.with_stroke ? settings.stroke_width : 0)
93 for (
auto i :
range(num_facets)) {
94 fout <<
"<polygon class=\"st0\" points=\""
95 << (vertices(facets(i, 0), 0) - bbox_min[0]) * settings.scaling_factor <<
","
96 << (bbox_max[1] - vertices(facets(i, 0), 1)) * settings.scaling_factor <<
" "
97 << (vertices(facets(i, 1), 0) - bbox_min[0]) * settings.scaling_factor <<
","
98 << (bbox_max[1] - vertices(facets(i, 1), 1)) * settings.scaling_factor <<
" "
99 << (vertices(facets(i, 2), 0) - bbox_min[0]) * settings.scaling_factor <<
","
100 << (bbox_max[1] - vertices(facets(i, 2), 1)) * settings.scaling_factor <<
"\"/>"
104 fout << footer << std::endl;
111template <
typename MeshType>
112void save_image_svg(
const fs::path& filename,
const MeshType& mesh,
const SVGSetting& settings = {})
114 if (settings.use_uv_mesh) {
115 const auto& uv = mesh.get_uv();
116 const auto& uv_indices = mesh.get_uv_indices();
117 save_image_svg(filename, uv, uv_indices, settings);
119 const auto& vertices = mesh.get_vertices();
120 const auto& facets = mesh.get_facets();
121 save_image_svg(filename, vertices, facets, settings);
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: save_image_svg.h:26
bool use_uv_mesh
Whether to use UV coordinates or vertex coordinates.
Definition: save_image_svg.h:29
float scaling_factor
Uniform scaling factor.
Definition: save_image_svg.h:32
uint32_t fill_color
Fill color.
Definition: save_image_svg.h:31
float height
Image height. Auto-compute if <=0.
Definition: save_image_svg.h:35
float stroke_width
Stroke width.
Definition: save_image_svg.h:33
bool with_stroke
Whether to stroke the edges.
Definition: save_image_svg.h:27
bool with_fill
Whether to fill the facets.
Definition: save_image_svg.h:28
uint32_t stroke_color
Stroke color.
Definition: save_image_svg.h:30
float width
Image width. Auto-compute if <=0.
Definition: save_image_svg.h:34