Blender  V2.93
gpencil_io_export_svg.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation
17  * All rights reserved.
18  */
19 
24 #include "BLI_math_vector.h"
25 #include "BLI_string.h"
26 #include "BLI_utildefines.h"
27 
28 #include "DNA_gpencil_types.h"
29 #include "DNA_material_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 
34 #include "BKE_gpencil.h"
35 #include "BKE_gpencil_geom.h"
36 #include "BKE_main.h"
37 #include "BKE_material.h"
38 
39 #include "DEG_depsgraph.h"
40 #include "DEG_depsgraph_query.h"
41 
42 #include "ED_gpencil.h"
43 #include "ED_view3d.h"
44 
45 #ifdef WIN32
46 # include "utfconv.h"
47 #endif
48 
49 #include "UI_view2d.h"
50 
51 #include "gpencil_io.h"
52 #include "gpencil_io_export_svg.hh"
53 
54 #include "pugixml.hpp"
55 
56 namespace blender ::io ::gpencil {
57 
58 /* Constructor. */
59 GpencilExporterSVG::GpencilExporterSVG(const char *filename, const GpencilIOParams *iparams)
60  : GpencilExporter(iparams)
61 {
62  filename_set(filename);
63 
64  invert_axis_[0] = false;
65  invert_axis_[1] = true;
66 }
67 
69 {
70  create_document_header();
71  return true;
72 }
73 
75 {
76  export_gpencil_layers();
77  return true;
78 }
79 
81 {
82  bool result = true;
83 /* Support unicode character paths on Windows. */
84 #ifdef WIN32
85  char filename_cstr[FILE_MAX];
86  BLI_strncpy(filename_cstr, filename_, FILE_MAX);
87 
88  UTF16_ENCODE(filename_cstr);
89  std::wstring wstr(filename_cstr_16);
90  result = main_doc_.save_file(wstr.c_str());
91 
92  UTF16_UN_ENCODE(filename_cstr);
93 #else
94  result = main_doc_.save_file(filename_);
95 #endif
96 
97  return result;
98 }
99 
100 /* Create document header and main svg node. */
101 void GpencilExporterSVG::create_document_header()
102 {
103  /* Add a custom document declaration node. */
104  pugi::xml_node decl = main_doc_.prepend_child(pugi::node_declaration);
105  decl.append_attribute("version") = "1.0";
106  decl.append_attribute("encoding") = "UTF-8";
107 
108  pugi::xml_node comment = main_doc_.append_child(pugi::node_comment);
109  char txt[128];
110  sprintf(txt, " Generator: Blender, %s - %s ", SVG_EXPORTER_NAME, SVG_EXPORTER_VERSION);
111  comment.set_value(txt);
112 
113  pugi::xml_node doctype = main_doc_.append_child(pugi::node_doctype);
114  doctype.set_value(
115  "svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "
116  "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"");
117 
118  main_node_ = main_doc_.append_child("svg");
119  main_node_.append_attribute("version").set_value("1.0");
120  main_node_.append_attribute("x").set_value("0px");
121  main_node_.append_attribute("y").set_value("0px");
122  main_node_.append_attribute("xmlns").set_value("http://www.w3.org/2000/svg");
123 
124  std::string width;
125  std::string height;
126 
129 
130  main_node_.append_attribute("width").set_value((width + "px").c_str());
131  main_node_.append_attribute("height").set_value((height + "px").c_str());
132  std::string viewbox = "0 0 " + width + " " + height;
133  main_node_.append_attribute("viewBox").set_value(viewbox.c_str());
134 }
135 
136 /* Main layer loop. */
137 void GpencilExporterSVG::export_gpencil_layers()
138 {
139  const bool is_clipping = is_camera_mode() && (params_.flag & GP_EXPORT_CLIP_CAMERA) != 0;
140 
141  /* If is doing a set of frames, the list of objects can change for each frame. */
143 
144  for (ObjectZ &obz : ob_list_) {
145  Object *ob = obz.ob;
146 
147  /* Camera clipping. */
148  if (is_clipping) {
149  pugi::xml_node clip_node = main_node_.append_child("clipPath");
150  clip_node.append_attribute("id").set_value(("clip-path" + std::to_string(cfra_)).c_str());
151 
152  add_rect(clip_node, 0, 0, render_x_, render_y_, 0.0f, "#000000");
153  }
154 
155  frame_node_ = main_node_.append_child("g");
156  std::string frametxt = "blender_frame_" + std::to_string(cfra_);
157  frame_node_.append_attribute("id").set_value(frametxt.c_str());
158 
159  /* Clip area. */
160  if (is_clipping) {
161  frame_node_.append_attribute("clip-path")
162  .set_value(("url(#clip-path" + std::to_string(cfra_) + ")").c_str());
163  }
164 
165  pugi::xml_node ob_node = frame_node_.append_child("g");
166 
167  char obtxt[96];
168  sprintf(obtxt, "blender_object_%s", ob->id.name + 2);
169  ob_node.append_attribute("id").set_value(obtxt);
170 
171  /* Use evaluated version to get strokes with modifiers. */
172  Object *ob_eval_ = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id);
173  bGPdata *gpd_eval = (bGPdata *)ob_eval_->data;
174 
175  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) {
176  if (gpl->flag & GP_LAYER_HIDE) {
177  continue;
178  }
180 
181  bGPDframe *gpf = gpl->actframe;
182  if ((gpf == nullptr) || (gpf->strokes.first == nullptr)) {
183  continue;
184  }
185 
186  /* Layer node. */
187  std::string txt = "Layer: ";
188  txt.append(gpl->info);
189  ob_node.append_child(pugi::node_comment).set_value(txt.c_str());
190 
191  pugi::xml_node node_gpl = ob_node.append_child("g");
192  node_gpl.append_attribute("id").set_value(gpl->info);
193 
194  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
195  if (gps->totpoints < 2) {
196  continue;
197  }
198  if (!ED_gpencil_stroke_material_visible(ob, gps)) {
199  continue;
200  }
201 
202  /* Duplicate the stroke to apply any layer thickness change. */
203  bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false);
204 
206  gps_duplicate->mat_nr + 1);
207 
208  const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) &&
209  (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH));
210  const bool is_fill = ((gp_style->flag & GP_MATERIAL_FILL_SHOW) &&
211  (gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH));
212 
213  prepare_stroke_export_colors(ob, gps_duplicate);
214 
215  /* Apply layer thickness change. */
216  gps_duplicate->thickness += gpl->line_change;
217  /* Apply object scale to thickness. */
218  gps_duplicate->thickness *= mat4_to_scale(ob->obmat);
219  CLAMP_MIN(gps_duplicate->thickness, 1.0f);
220 
221  const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) ||
223 
224  /* Fill. */
225  if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) {
226  /* Fill is always exported as polygon because the stroke of the fill is done
227  * in a different SVG command. */
228  export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, true);
229  }
230 
231  /* Stroke. */
232  if (is_stroke) {
233  if (is_normalized) {
234  export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, false);
235  }
236  else {
238  rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values);
239 
240  /* Sample stroke. */
241  if (params_.stroke_sample > 0.0f) {
242  BKE_gpencil_stroke_sample(gpd_eval, gps_perimeter, params_.stroke_sample, false);
243  }
244 
245  export_stroke_to_path(gpl, gps_perimeter, node_gpl, false);
246 
247  BKE_gpencil_free_stroke(gps_perimeter);
248  }
249  }
250 
251  BKE_gpencil_free_stroke(gps_duplicate);
252  }
253  }
254  }
255 }
256 
262 void GpencilExporterSVG::export_stroke_to_path(bGPDlayer *gpl,
263  bGPDstroke *gps,
264  pugi::xml_node node_gpl,
265  const bool do_fill)
266 {
267  pugi::xml_node node_gps = node_gpl.append_child("path");
268 
269  float col[3];
270  std::string stroke_hex;
271  if (do_fill) {
272  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
273 
275  }
276  else {
277  node_gps.append_attribute("fill-opacity")
278  .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity);
279 
281  }
282 
284  stroke_hex = rgb_to_hexstr(col);
285 
286  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
287  node_gps.append_attribute("stroke").set_value("none");
288 
289  std::string txt = "M";
290  for (const int i : IndexRange(gps->totpoints)) {
291  if (i > 0) {
292  txt.append("L");
293  }
294  bGPDspoint &pt = gps->points[i];
295  const float2 screen_co = gpencil_3D_point_to_2D(&pt.x);
296  txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y));
297  }
298  /* Close patch (cyclic)*/
299  if (gps->flag & GP_STROKE_CYCLIC) {
300  txt.append("z");
301  }
302 
303  node_gps.append_attribute("d").set_value(txt.c_str());
304 }
305 
311 void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl,
312  bGPDstroke *gps,
313  pugi::xml_node node_gpl,
314  const bool is_stroke,
315  const bool do_fill)
316 {
317  const bool cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0);
318  const float avg_pressure = BKE_gpencil_stroke_average_pressure_get(gps);
319 
320  /* Get the thickness in pixels using a simple 1 point stroke. */
321  bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, false, false);
322  gps_temp->totpoints = 1;
323  gps_temp->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint), "gp_stroke_points");
324  bGPDspoint *pt_src = &gps->points[0];
325  bGPDspoint *pt_dst = &gps_temp->points[0];
326  copy_v3_v3(&pt_dst->x, &pt_src->x);
327  pt_dst->pressure = avg_pressure;
328 
329  const float radius = stroke_point_radius_get(gpl, gps_temp);
330 
331  BKE_gpencil_free_stroke(gps_temp);
332 
333  pugi::xml_node node_gps = node_gpl.append_child(do_fill || cyclic ? "polygon" : "polyline");
334 
335  color_string_set(gpl, gps, node_gps, do_fill);
336 
337  if (is_stroke && !do_fill) {
338  node_gps.append_attribute("stroke-width").set_value((radius * 2.0f) - gpl->line_change);
339  }
340 
341  std::string txt;
342  for (const int i : IndexRange(gps->totpoints)) {
343  if (i > 0) {
344  txt.append(" ");
345  }
346  bGPDspoint *pt = &gps->points[i];
347  const float2 screen_co = gpencil_3D_point_to_2D(&pt->x);
348  txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y));
349  }
350 
351  node_gps.append_attribute("points").set_value(txt.c_str());
352 }
353 
359 void GpencilExporterSVG::color_string_set(bGPDlayer *gpl,
360  bGPDstroke *gps,
361  pugi::xml_node node_gps,
362  const bool do_fill)
363 {
364  const bool round_cap = (gps->caps[0] == GP_STROKE_CAP_ROUND ||
365  gps->caps[1] == GP_STROKE_CAP_ROUND);
366 
367  float col[3];
368  if (do_fill) {
371  std::string stroke_hex = rgb_to_hexstr(col);
372  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
373  node_gps.append_attribute("stroke").set_value("none");
374  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
375  }
376  else {
379  std::string stroke_hex = rgb_to_hexstr(col);
380  node_gps.append_attribute("stroke").set_value(stroke_hex.c_str());
381  node_gps.append_attribute("stroke-opacity")
382  .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity);
383 
384  if (gps->totpoints > 1) {
385  node_gps.append_attribute("fill").set_value("none");
386  node_gps.append_attribute("stroke-linecap").set_value(round_cap ? "round" : "square");
387  }
388  else {
389  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
390  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
391  }
392  }
393 }
394 
405 void GpencilExporterSVG::add_rect(pugi::xml_node node,
406  float x,
407  float y,
408  float width,
409  float height,
410  float thickness,
411  std::string hexcolor)
412 {
413  pugi::xml_node rect_node = node.append_child("rect");
414  rect_node.append_attribute("x").set_value(x);
415  rect_node.append_attribute("y").set_value(y);
416  rect_node.append_attribute("width").set_value(width);
417  rect_node.append_attribute("height").set_value(height);
418  rect_node.append_attribute("fill").set_value("none");
419  if (thickness > 0.0f) {
420  rect_node.append_attribute("stroke").set_value(hexcolor.c_str());
421  rect_node.append_attribute("stroke-width").set_value(thickness);
422  }
423 }
424 
434 void GpencilExporterSVG::add_text(pugi::xml_node node,
435  float x,
436  float y,
437  std::string text,
438  const float size,
439  std::string hexcolor)
440 {
441  pugi::xml_node nodetxt = node.append_child("text");
442 
443  nodetxt.append_attribute("x").set_value(x);
444  nodetxt.append_attribute("y").set_value(y);
445  // nodetxt.append_attribute("font-family").set_value("'system-ui'");
446  nodetxt.append_attribute("font-size").set_value(size);
447  nodetxt.append_attribute("fill").set_value(hexcolor.c_str());
448  nodetxt.text().set(text.c_str());
449 }
450 
452 std::string GpencilExporterSVG::rgb_to_hexstr(const float color[3])
453 {
454  uint8_t r = color[0] * 255.0f;
455  uint8_t g = color[1] * 255.0f;
456  uint8_t b = color[2] * 255.0f;
457  char hex_string[20];
458  sprintf(hex_string, "#%02X%02X%02X", r, g, b);
459 
460  std::string hexstr = hex_string;
461 
462  return hexstr;
463 }
464 
465 } // namespace blender::io::gpencil
#define GPENCIL_ALPHA_OPACITY_THRESH
Definition: BKE_gpencil.h:177
void BKE_gpencil_free_stroke(struct bGPDstroke *gps)
Definition: gpencil.c:401
struct bGPDstroke * BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src, const bool dup_points, const bool dup_curve)
Definition: gpencil.c:957
float BKE_gpencil_stroke_average_pressure_get(struct bGPDstroke *gps)
bool BKE_gpencil_stroke_sample(struct bGPdata *gpd, struct bGPDstroke *gps, const float dist, const bool select)
Definition: gpencil_geom.c:429
struct bGPDstroke * BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, struct bGPdata *gpd, const struct bGPDlayer *gpl, struct bGPDstroke *gps, const int subdivisions, const float diff_mat[4][4])
bool BKE_gpencil_stroke_is_pressure_constant(struct bGPDstroke *gps)
General operations, lookup, etc. for materials.
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
Definition: material.c:713
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2196
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define FILE_MAX
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define CLAMP_MIN(a, b)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
@ GP_STROKE_CAP_ROUND
@ GP_STROKE_CYCLIC
@ GP_LAYER_HIDE
@ GP_MATERIAL_STROKE_SHOW
@ GP_MATERIAL_FILL_SHOW
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static void add_text(pugi::xml_node node, float x, float y, std::string text, const float size, std::string hexcolor)
static void add_rect(pugi::xml_node node, float x, float y, float width, float height, float thickness, std::string hexcolor)
float stroke_point_radius_get(struct bGPDlayer *gpl, struct bGPDstroke *gps)
blender::Vector< ObjectZ > ob_list_
void prepare_stroke_export_colors(struct Object *ob, struct bGPDstroke *gps)
float2 gpencil_3D_point_to_2D(const float3 co)
void filename_set(const char *filename)
void prepare_layer_export_matrix(struct Object *ob, struct bGPDlayer *gpl)
OperationNode * node
@ GP_EXPORT_NORM_THICKNESS
Definition: gpencil_io.h:61
@ GP_EXPORT_CLIP_CAMERA
Definition: gpencil_io.h:63
@ GP_EXPORT_FILL
Definition: gpencil_io.h:59
#define SVG_EXPORTER_NAME
#define SVG_EXPORTER_VERSION
bool ED_gpencil_stroke_material_visible(Object *ob, const bGPDstroke *gps)
uint col
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
std::string to_string(const T &n)
unsigned char uint8_t
Definition: stdint.h:81
float stroke_sample
Definition: gpencil_io.h:52
uint32_t flag
Definition: gpencil_io.h:45
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
float obmat[4][4]
void * data
ListBase strokes
float tintcolor[4]
bGPDspoint * points
ListBase layers
float values[4][4]
Definition: BLI_float4x4.hh:25
#define UTF16_ENCODE(in8str)
Definition: utfconv.h:96
#define UTF16_UN_ENCODE(in8str)
Definition: utfconv.h:100