Blender  V3.3
gpencil_io_export_svg.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
8 #include "BLI_math_vector.h"
9 #include "BLI_string.h"
10 #include "BLI_utildefines.h"
11 
12 #include "DNA_gpencil_types.h"
13 #include "DNA_material_types.h"
14 #include "DNA_object_types.h"
15 #include "DNA_scene_types.h"
16 #include "DNA_screen_types.h"
17 
18 #include "BKE_gpencil.h"
19 #include "BKE_gpencil_geom.h"
20 #include "BKE_main.h"
21 #include "BKE_material.h"
22 
23 #include "DEG_depsgraph.h"
24 #include "DEG_depsgraph_query.h"
25 
26 #include "ED_gpencil.h"
27 #include "ED_view3d.h"
28 
29 #ifdef WIN32
30 # include "utfconv.h"
31 #endif
32 
33 #include "UI_view2d.h"
34 
35 #include "gpencil_io.h"
36 #include "gpencil_io_export_svg.hh"
37 
38 #include "pugixml.hpp"
39 
40 namespace blender ::io ::gpencil {
41 
42 /* Constructor. */
43 GpencilExporterSVG::GpencilExporterSVG(const char *filepath, const GpencilIOParams *iparams)
44  : GpencilExporter(iparams)
45 {
46  filepath_set(filepath);
47 
48  invert_axis_[0] = false;
49  invert_axis_[1] = true;
50 }
51 
53 {
54  create_document_header();
55  return true;
56 }
57 
59 {
60  export_gpencil_layers();
61  return true;
62 }
63 
65 {
66  bool result = true;
67 /* Support unicode character paths on Windows. */
68 #ifdef WIN32
69  char filepath_cstr[FILE_MAX];
70  BLI_strncpy(filepath_cstr, filepath_, FILE_MAX);
71 
72  UTF16_ENCODE(filepath_cstr);
73  std::wstring wstr(filepath_cstr_16);
74  result = main_doc_.save_file(wstr.c_str());
75 
76  UTF16_UN_ENCODE(filepath_cstr);
77 #else
78  result = main_doc_.save_file(filepath_);
79 #endif
80 
81  return result;
82 }
83 
84 void GpencilExporterSVG::create_document_header()
85 {
86  /* Add a custom document declaration node. */
87  pugi::xml_node decl = main_doc_.prepend_child(pugi::node_declaration);
88  decl.append_attribute("version") = "1.0";
89  decl.append_attribute("encoding") = "UTF-8";
90 
91  pugi::xml_node comment = main_doc_.append_child(pugi::node_comment);
92  char txt[128];
93  sprintf(txt, " Generator: Blender, %s - %s ", SVG_EXPORTER_NAME, SVG_EXPORTER_VERSION);
94  comment.set_value(txt);
95 
96  pugi::xml_node doctype = main_doc_.append_child(pugi::node_doctype);
97  doctype.set_value(
98  "svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "
99  "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"");
100 
101  main_node_ = main_doc_.append_child("svg");
102  main_node_.append_attribute("version").set_value("1.0");
103  main_node_.append_attribute("x").set_value("0px");
104  main_node_.append_attribute("y").set_value("0px");
105  main_node_.append_attribute("xmlns").set_value("http://www.w3.org/2000/svg");
106 
107  std::string width;
108  std::string height;
109 
112 
113  main_node_.append_attribute("width").set_value((width + "px").c_str());
114  main_node_.append_attribute("height").set_value((height + "px").c_str());
115  std::string viewbox = "0 0 " + width + " " + height;
116  main_node_.append_attribute("viewBox").set_value(viewbox.c_str());
117 }
118 
119 void GpencilExporterSVG::export_gpencil_layers()
120 {
121  const bool is_clipping = is_camera_mode() && (params_.flag & GP_EXPORT_CLIP_CAMERA) != 0;
122 
123  /* If is doing a set of frames, the list of objects can change for each frame. */
125 
126  for (ObjectZ &obz : ob_list_) {
127  Object *ob = obz.ob;
128 
129  /* Camera clipping. */
130  if (is_clipping) {
131  pugi::xml_node clip_node = main_node_.append_child("clipPath");
132  clip_node.append_attribute("id").set_value(("clip-path" + std::to_string(cfra_)).c_str());
133 
134  add_rect(clip_node, 0, 0, render_x_, render_y_, 0.0f, "#000000");
135  }
136 
137  frame_node_ = main_node_.append_child("g");
138  std::string frametxt = "blender_frame_" + std::to_string(cfra_);
139  frame_node_.append_attribute("id").set_value(frametxt.c_str());
140 
141  /* Clip area. */
142  if (is_clipping) {
143  frame_node_.append_attribute("clip-path")
144  .set_value(("url(#clip-path" + std::to_string(cfra_) + ")").c_str());
145  }
146 
147  pugi::xml_node ob_node = frame_node_.append_child("g");
148 
149  char obtxt[96];
150  sprintf(obtxt, "blender_object_%s", ob->id.name + 2);
151  ob_node.append_attribute("id").set_value(obtxt);
152 
153  /* Use evaluated version to get strokes with modifiers. */
154  Object *ob_eval_ = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id);
155  bGPdata *gpd_eval = (bGPdata *)ob_eval_->data;
156 
157  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) {
158  if (gpl->flag & GP_LAYER_HIDE) {
159  continue;
160  }
162 
163  bGPDframe *gpf = gpl->actframe;
164  if ((gpf == nullptr) || (gpf->strokes.first == nullptr)) {
165  continue;
166  }
167 
168  /* Layer node. */
169  std::string txt = "Layer: ";
170  txt.append(gpl->info);
171  ob_node.append_child(pugi::node_comment).set_value(txt.c_str());
172 
173  pugi::xml_node node_gpl = ob_node.append_child("g");
174  node_gpl.append_attribute("id").set_value(gpl->info);
175 
176  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
177  if (gps->totpoints < 2) {
178  continue;
179  }
180  if (!ED_gpencil_stroke_material_visible(ob, gps)) {
181  continue;
182  }
183 
184  /* Duplicate the stroke to apply any layer thickness change. */
185  bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false);
186 
188  gps_duplicate->mat_nr + 1);
189 
190  const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) &&
191  (gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH));
192  const bool is_fill = ((gp_style->flag & GP_MATERIAL_FILL_SHOW) &&
193  (gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH));
194 
195  prepare_stroke_export_colors(ob, gps_duplicate);
196 
197  /* Apply layer thickness change. */
198  gps_duplicate->thickness += gpl->line_change;
199  /* Apply object scale to thickness. */
200  gps_duplicate->thickness *= mat4_to_scale(ob->obmat);
201  CLAMP_MIN(gps_duplicate->thickness, 1.0f);
202 
203  const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) ||
205 
206  /* Fill. */
207  if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) {
208  /* Fill is always exported as polygon because the stroke of the fill is done
209  * in a different SVG command. */
210  export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, true);
211  }
212 
213  /* Stroke. */
214  if (is_stroke) {
215  if (is_normalized) {
216  export_stroke_to_polyline(gpl, gps_duplicate, node_gpl, is_stroke, false);
217  }
218  else {
220  rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values);
221 
222  /* Sample stroke. */
223  if (params_.stroke_sample > 0.0f) {
224  BKE_gpencil_stroke_sample(gpd_eval, gps_perimeter, params_.stroke_sample, false, 0);
225  }
226 
227  export_stroke_to_path(gpl, gps_perimeter, node_gpl, false);
228 
229  BKE_gpencil_free_stroke(gps_perimeter);
230  }
231  }
232 
233  BKE_gpencil_free_stroke(gps_duplicate);
234  }
235  }
236  }
237 }
238 
239 void GpencilExporterSVG::export_stroke_to_path(bGPDlayer *gpl,
240  bGPDstroke *gps,
241  pugi::xml_node node_gpl,
242  const bool do_fill)
243 {
244  pugi::xml_node node_gps = node_gpl.append_child("path");
245 
246  float col[3];
247  std::string stroke_hex;
248  if (do_fill) {
249  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
250 
252  }
253  else {
254  node_gps.append_attribute("fill-opacity")
255  .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity);
256 
258  }
259 
261  stroke_hex = rgb_to_hexstr(col);
262 
263  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
264  node_gps.append_attribute("stroke").set_value("none");
265 
266  std::string txt = "M";
267  for (const int i : IndexRange(gps->totpoints)) {
268  if (i > 0) {
269  txt.append("L");
270  }
271  bGPDspoint &pt = gps->points[i];
272  const float2 screen_co = gpencil_3D_point_to_2D(&pt.x);
273  txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y));
274  }
275  /* Close patch (cyclic). */
276  if (gps->flag & GP_STROKE_CYCLIC) {
277  txt.append("z");
278  }
279 
280  node_gps.append_attribute("d").set_value(txt.c_str());
281 }
282 
283 void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl,
284  bGPDstroke *gps,
285  pugi::xml_node node_gpl,
286  const bool is_stroke,
287  const bool do_fill)
288 {
289  const bool cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0);
290  const float avg_pressure = BKE_gpencil_stroke_average_pressure_get(gps);
291 
292  /* Get the thickness in pixels using a simple 1 point stroke. */
293  bGPDstroke *gps_temp = BKE_gpencil_stroke_duplicate(gps, false, false);
294  gps_temp->totpoints = 1;
295  gps_temp->points = MEM_new<bGPDspoint>("gp_stroke_points");
296  bGPDspoint *pt_src = &gps->points[0];
297  bGPDspoint *pt_dst = &gps_temp->points[0];
298  copy_v3_v3(&pt_dst->x, &pt_src->x);
299  pt_dst->pressure = avg_pressure;
300 
301  const float radius = stroke_point_radius_get(gpl, gps_temp);
302 
303  BKE_gpencil_free_stroke(gps_temp);
304 
305  pugi::xml_node node_gps = node_gpl.append_child(do_fill || cyclic ? "polygon" : "polyline");
306 
307  color_string_set(gpl, gps, node_gps, do_fill);
308 
309  if (is_stroke && !do_fill) {
310  node_gps.append_attribute("stroke-width").set_value((radius * 2.0f) - gpl->line_change);
311  }
312 
313  std::string txt;
314  for (const int i : IndexRange(gps->totpoints)) {
315  if (i > 0) {
316  txt.append(" ");
317  }
318  bGPDspoint *pt = &gps->points[i];
319  const float2 screen_co = gpencil_3D_point_to_2D(&pt->x);
320  txt.append(std::to_string(screen_co.x) + "," + std::to_string(screen_co.y));
321  }
322 
323  node_gps.append_attribute("points").set_value(txt.c_str());
324 }
325 
326 void GpencilExporterSVG::color_string_set(bGPDlayer *gpl,
327  bGPDstroke *gps,
328  pugi::xml_node node_gps,
329  const bool do_fill)
330 {
331  const bool round_cap = (gps->caps[0] == GP_STROKE_CAP_ROUND ||
332  gps->caps[1] == GP_STROKE_CAP_ROUND);
333 
334  float col[3];
335  if (do_fill) {
338  std::string stroke_hex = rgb_to_hexstr(col);
339  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
340  node_gps.append_attribute("stroke").set_value("none");
341  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
342  }
343  else {
346  std::string stroke_hex = rgb_to_hexstr(col);
347  node_gps.append_attribute("stroke").set_value(stroke_hex.c_str());
348  node_gps.append_attribute("stroke-opacity")
349  .set_value(stroke_color_[3] * stroke_average_opacity_get() * gpl->opacity);
350 
351  if (gps->totpoints > 1) {
352  node_gps.append_attribute("fill").set_value("none");
353  node_gps.append_attribute("stroke-linecap").set_value(round_cap ? "round" : "square");
354  }
355  else {
356  node_gps.append_attribute("fill").set_value(stroke_hex.c_str());
357  node_gps.append_attribute("fill-opacity").set_value(fill_color_[3] * gpl->opacity);
358  }
359  }
360 }
361 
362 void GpencilExporterSVG::add_rect(pugi::xml_node node,
363  float x,
364  float y,
365  float width,
366  float height,
367  float thickness,
368  std::string hexcolor)
369 {
370  pugi::xml_node rect_node = node.append_child("rect");
371  rect_node.append_attribute("x").set_value(x);
372  rect_node.append_attribute("y").set_value(y);
373  rect_node.append_attribute("width").set_value(width);
374  rect_node.append_attribute("height").set_value(height);
375  rect_node.append_attribute("fill").set_value("none");
376  if (thickness > 0.0f) {
377  rect_node.append_attribute("stroke").set_value(hexcolor.c_str());
378  rect_node.append_attribute("stroke-width").set_value(thickness);
379  }
380 }
381 
382 void GpencilExporterSVG::add_text(pugi::xml_node node,
383  float x,
384  float y,
385  std::string text,
386  const float size,
387  std::string hexcolor)
388 {
389  pugi::xml_node nodetxt = node.append_child("text");
390 
391  nodetxt.append_attribute("x").set_value(x);
392  nodetxt.append_attribute("y").set_value(y);
393  // nodetxt.append_attribute("font-family").set_value("'system-ui'");
394  nodetxt.append_attribute("font-size").set_value(size);
395  nodetxt.append_attribute("fill").set_value(hexcolor.c_str());
396  nodetxt.text().set(text.c_str());
397 }
398 
399 std::string GpencilExporterSVG::rgb_to_hexstr(const float color[3])
400 {
401  uint8_t r = color[0] * 255.0f;
402  uint8_t g = color[1] * 255.0f;
403  uint8_t b = color[2] * 255.0f;
404  char hex_string[20];
405  sprintf(hex_string, "#%02X%02X%02X", r, g, b);
406 
407  std::string hexstr = hex_string;
408 
409  return hexstr;
410 }
411 
412 } // namespace blender::io::gpencil
struct bGPDstroke * BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src, bool dup_points, bool dup_curve)
Definition: gpencil.c:855
#define GPENCIL_ALPHA_OPACITY_THRESH
Definition: BKE_gpencil.h:323
void BKE_gpencil_free_stroke(struct bGPDstroke *gps)
Definition: gpencil.c:391
float BKE_gpencil_stroke_average_pressure_get(struct bGPDstroke *gps)
struct bGPDstroke * BKE_gpencil_stroke_perimeter_from_view(struct RegionView3D *rv3d, struct bGPdata *gpd, const struct bGPDlayer *gpl, struct bGPDstroke *gps, int subdivisions, const float diff_mat[4][4])
bool BKE_gpencil_stroke_sample(struct bGPdata *gpd, struct bGPDstroke *gps, const float dist, const bool select, const float sharp_threshold)
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:805
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
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:2185
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
#define FILE_MAX
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#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 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
_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
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static void add_rect(pugi::xml_node node, float x, float y, float width, float height, float thickness, std::string hexcolor)
static void add_text(pugi::xml_node node, float x, float y, std::string text, float size, std::string hexcolor)
void filepath_set(const char *filepath)
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 prepare_layer_export_matrix(struct Object *ob, struct bGPDlayer *gpl)
OperationNode * node
@ GP_EXPORT_NORM_THICKNESS
Definition: gpencil_io.h:47
@ GP_EXPORT_CLIP_CAMERA
Definition: gpencil_io.h:49
@ GP_EXPORT_FILL
Definition: gpencil_io.h:45
#define SVG_EXPORTER_NAME
#define SVG_EXPORTER_VERSION
bool ED_gpencil_stroke_material_visible(Object *ob, const bGPDstroke *gps)
uint col
std::string to_string(const T &n)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
unsigned char uint8_t
Definition: stdint.h:78
float stroke_sample
Definition: gpencil_io.h:36
uint32_t flag
Definition: gpencil_io.h:29
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
float obmat[4][4]
void * data
ListBase strokes
float tintcolor[4]
bGPDspoint * points
ListBase layers
float values[4][4]
Definition: BLI_float4x4.hh:13
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
#define UTF16_ENCODE(in8str)
Definition: utfconv.h:83
#define UTF16_UN_ENCODE(in8str)
Definition: utfconv.h:87