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/fmt/format.h>
19#include <lagrange/utils/range.h>
48template <
typename DerivedV,
typename DerivedF>
50 const fs::path& filename,
51 const Eigen::MatrixBase<DerivedV>& vertices,
52 const Eigen::MatrixBase<DerivedF>& facets,
55 using Scalar =
typename DerivedV::Scalar;
56 std::ofstream fout(filename.c_str());
58 const auto num_facets = facets.rows();
60 const Eigen::Matrix<Scalar, 1, 2> bbox_min = vertices.colwise().minCoeff().eval();
61 const Eigen::Matrix<Scalar, 1, 2> bbox_max = vertices.colwise().maxCoeff().eval();
63 std::string footer =
"</svg>";
66 float width = settings.width;
67 float height = settings.height;
68 if (settings.width <= 0) {
69 width = float(bbox_max[0] - bbox_min[0]) * settings.scaling_factor;
71 if (settings.height <= 0) {
72 height = float(bbox_max[1] - bbox_min[1]) * settings.scaling_factor;
76 "<?xml version=\"1.0\" encoding=\"utf-8\"?> <svg version=\"1.1\" id=\"Layer_1\" "
77 "xmlns=\"http://www.w3.org/2000/svg\" "
78 "xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" "
79 "y=\"0px\" viewBox=\"0 0 {} {}\" "
80 "style=\"enable-background:new 0 0 {} {};\" "
81 "xml:space=\"preserve\"> <style type=\"text/css\"> "
82 ".st0{{fill:{}; stroke:{}; stroke-miterlimit:10; stroke-width:{}px; "
83 "stroke-linejoin:\"round\";}} "
89 settings.with_fill ? format(
"#{:06x}", settings.fill_color) :
"none",
90 settings.with_stroke ? format(
"#{:06x}", settings.stroke_color) :
"none",
91 settings.with_stroke ? settings.stroke_width : 0)
94 for (
auto i :
range(num_facets)) {
95 fout <<
"<polygon class=\"st0\" points=\""
96 << (vertices(facets(i, 0), 0) - bbox_min[0]) * settings.scaling_factor <<
","
97 << (bbox_max[1] - vertices(facets(i, 0), 1)) * settings.scaling_factor <<
" "
98 << (vertices(facets(i, 1), 0) - bbox_min[0]) * settings.scaling_factor <<
","
99 << (bbox_max[1] - vertices(facets(i, 1), 1)) * settings.scaling_factor <<
" "
100 << (vertices(facets(i, 2), 0) - bbox_min[0]) * settings.scaling_factor <<
","
101 << (bbox_max[1] - vertices(facets(i, 2), 1)) * settings.scaling_factor <<
"\"/>"
105 fout << footer << std::endl;
112template <
typename MeshType>
113void save_image_svg(
const fs::path& filename,
const MeshType& mesh,
const SVGSetting& settings = {})
115 if (settings.use_uv_mesh) {
116 const auto& uv = mesh.get_uv();
117 const auto& uv_indices = mesh.get_uv_indices();
118 save_image_svg(filename, uv, uv_indices, settings);
120 const auto& vertices = mesh.get_vertices();
121 const auto& facets = mesh.get_facets();
122 save_image_svg(filename, vertices, facets, settings);
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition range.h:176
Main namespace for Lagrange.
Definition save_image_svg.h:27
bool use_uv_mesh
Whether to use UV coordinates or vertex coordinates.
Definition save_image_svg.h:30
float scaling_factor
Uniform scaling factor.
Definition save_image_svg.h:33
uint32_t fill_color
Fill color.
Definition save_image_svg.h:32
float height
Image height. Auto-compute if <=0.
Definition save_image_svg.h:36
float stroke_width
Stroke width.
Definition save_image_svg.h:34
bool with_stroke
Whether to stroke the edges.
Definition save_image_svg.h:28
bool with_fill
Whether to fill the facets.
Definition save_image_svg.h:29
uint32_t stroke_color
Stroke color.
Definition save_image_svg.h:31
float width
Image width. Auto-compute if <=0.
Definition save_image_svg.h:35