Blender  V2.93
gpencil_io_base.cc
Go to the documentation of this file.
1 
2 
3 /*
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2020 Blender Foundation
19  * All rights reserved.
20  */
21 
26 #include "BLI_float2.hh"
27 #include "BLI_float3.hh"
28 #include "BLI_float4x4.hh"
29 #include "BLI_path_util.h"
30 #include "BLI_span.hh"
31 
32 #include "DNA_gpencil_types.h"
33 #include "DNA_layer_types.h"
34 #include "DNA_material_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 
38 #include "BKE_camera.h"
39 #include "BKE_context.h"
40 #include "BKE_gpencil.h"
41 #include "BKE_gpencil_geom.h"
42 #include "BKE_main.h"
43 #include "BKE_material.h"
44 
45 #include "UI_view2d.h"
46 
47 #include "ED_view3d.h"
48 
49 #include "DEG_depsgraph.h"
50 #include "DEG_depsgraph_query.h"
51 
52 #include "gpencil_io_base.hh"
53 
54 using blender::Span;
55 
57 
58 /* Constructor. */
60 {
61  params_ = *iparams;
62 
63  /* Easy access data. */
68  gpd_ = (params_.ob != nullptr) ? (bGPdata *)params_.ob->data : nullptr;
69  cfra_ = iparams->frame_cur;
70 
71  /* Calculate camera matrix. */
72  prepare_camera_params(iparams);
73 }
74 
76 {
77  params_ = *iparams;
78  const bool is_pdf = params_.mode == GP_EXPORT_TO_PDF;
79  const bool any_camera = (params_.v3d->camera != nullptr);
80  const bool force_camera_view = is_pdf && any_camera;
81 
82  /* Calculate camera matrix. */
83  Object *cam_ob = params_.v3d->camera;
84  if (cam_ob != nullptr) {
85  /* Set up parameters. */
89 
90  /* Compute matrix, viewplane, .. */
91  RenderData *rd = &scene_->r;
94 
95  float viewmat[4][4];
96  invert_m4_m4(viewmat, cam_ob->obmat);
97 
98  mul_m4_m4m4(persmat_, params.winmat, viewmat);
99  is_ortho_ = params.is_ortho;
100  }
101  else {
102  unit_m4(persmat_);
103  is_ortho_ = false;
104  }
105 
108 
109  /* Camera rectangle. */
110  if ((rv3d_->persp == RV3D_CAMOB) || (force_camera_view)) {
111  render_x_ = (scene_->r.xsch * scene_->r.size) / 100;
112  render_y_ = (scene_->r.ysch * scene_->r.size) / 100;
113 
115  depsgraph_,
116  params_.region,
117  params_.v3d,
118  rv3d_,
119  &camera_rect_,
120  true);
121  is_camera_ = true;
125  }
126  else {
127  is_camera_ = false;
128  is_ortho_ = false;
129  /* Calc selected object boundbox. Need set initial value to some variables. */
130  camera_ratio_ = 1.0f;
131  offset_.x = 0.0f;
132  offset_.y = 0.0f;
133 
135 
137  rctf boundbox;
139 
140  render_x_ = boundbox.xmax - boundbox.xmin;
141  render_y_ = boundbox.ymax - boundbox.ymin;
142  offset_.x = boundbox.xmin;
143  offset_.y = boundbox.ymin;
144  }
145 }
146 
149 {
150  ViewLayer *view_layer = CTX_data_view_layer(params_.C);
151 
152  float3 camera_z_axis;
153  copy_v3_v3(camera_z_axis, rv3d_->viewinv[2]);
154  ob_list_.clear();
155 
156  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
157  Object *object = base->object;
158 
159  if (object->type != OB_GPENCIL) {
160  continue;
161  }
162  if ((params_.select_mode == GP_EXPORT_ACTIVE) && (params_.ob != object)) {
163  continue;
164  }
165 
166  if ((params_.select_mode == GP_EXPORT_SELECTED) && ((base->flag & BASE_SELECTED) == 0)) {
167  continue;
168  }
169 
170  /* Save z-depth from view to sort from back to front. */
171  if (is_camera_) {
172  float camera_z = dot_v3v3(camera_z_axis, object->obmat[3]);
173  ObjectZ obz = {camera_z, object};
174  ob_list_.append(obz);
175  }
176  else {
177  float zdepth = 0;
178  if (rv3d_) {
179  if (rv3d_->is_persp) {
180  zdepth = ED_view3d_calc_zfac(rv3d_, object->obmat[3], nullptr);
181  }
182  else {
183  zdepth = -dot_v3v3(rv3d_->viewinv[2], object->obmat[3]);
184  }
185  ObjectZ obz = {zdepth * -1.0f, object};
186  ob_list_.append(obz);
187  }
188  }
189  }
190  /* Sort list of objects from point of view. */
191  std::sort(ob_list_.begin(), ob_list_.end(), [](const ObjectZ &obz1, const ObjectZ &obz2) {
192  return obz1.zdepth < obz2.zdepth;
193  });
194 }
195 
200 void GpencilIO::filename_set(const char *filename)
201 {
202  BLI_strncpy(filename_, filename, FILE_MAX);
204 }
205 
208 {
209  float3 parent_co = diff_mat_ * co;
210  float2 screen_co;
212  if (ED_view3d_project_float_global(params_.region, parent_co, screen_co, test) ==
213  V3D_PROJ_RET_OK) {
214  if (!ELEM(V2D_IS_CLIPPED, screen_co[0], screen_co[1])) {
215  copy_v2_v2(r_co, screen_co);
216  /* Invert X axis. */
217  if (invert_axis_[0]) {
218  r_co[0] = winx_ - r_co[0];
219  }
220  /* Invert Y axis. */
221  if (invert_axis_[1]) {
222  r_co[1] = winy_ - r_co[1];
223  }
224  /* Apply offset and scale. */
225  sub_v2_v2(r_co, &offset_.x);
226  mul_v2_fl(r_co, camera_ratio_);
227 
228  return true;
229  }
230  }
231  r_co[0] = V2D_IS_CLIPPED;
232  r_co[1] = V2D_IS_CLIPPED;
233 
234  /* Invert X axis. */
235  if (invert_axis_[0]) {
236  r_co[0] = winx_ - r_co[0];
237  }
238  /* Invert Y axis. */
239  if (invert_axis_[1]) {
240  r_co[1] = winy_ - r_co[1];
241  }
242 
243  return false;
244 }
245 
248 {
249  float3 parent_co = diff_mat_ * co;
250  mul_m4_v3(persmat_, parent_co);
251 
252  if (!is_ortho) {
253  parent_co.x = parent_co.x / max_ff(FLT_MIN, parent_co.z);
254  parent_co.y = parent_co.y / max_ff(FLT_MIN, parent_co.z);
255  }
256 
257  float2 r_co;
258  r_co.x = (parent_co.x + 1.0f) / 2.0f * (float)render_x_;
259  r_co.y = (parent_co.y + 1.0f) / 2.0f * (float)render_y_;
260 
261  /* Invert X axis. */
262  if (invert_axis_[0]) {
263  r_co.x = (float)render_x_ - r_co.x;
264  }
265  /* Invert Y axis. */
266  if (invert_axis_[1]) {
267  r_co.y = (float)render_y_ - r_co.y;
268  }
269 
270  return r_co;
271 }
272 
275 {
276  const bool is_camera = (bool)(rv3d_->persp == RV3D_CAMOB);
277  if (is_camera) {
279  }
280  float2 result;
282  return result;
283 }
284 
287 {
288  bGPDspoint *pt = &gps->points[0];
289  const float2 screen_co = gpencil_3D_point_to_2D(&pt->x);
290 
291  /* Radius. */
293  rv3d_, gpd_, gpl, gps, 3, diff_mat_.values);
294 
295  pt = &gps_perimeter->points[0];
296  const float2 screen_ex = gpencil_3D_point_to_2D(&pt->x);
297 
298  const float2 v1 = screen_co - screen_ex;
299  float radius = v1.length();
300  BKE_gpencil_free_stroke(gps_perimeter);
301 
302  return MAX2(radius, 1.0f);
303 }
304 
306 {
309 }
310 
312 {
314 
315  /* Stroke color. */
317  avg_opacity_ = 0.0f;
318  /* Get average vertex color and apply. */
319  float avg_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
320  for (const bGPDspoint &pt : Span(gps->points, gps->totpoints)) {
321  add_v4_v4(avg_color, pt.vert_color);
322  avg_opacity_ += pt.strength;
323  }
324 
325  mul_v4_v4fl(avg_color, avg_color, 1.0f / (float)gps->totpoints);
326  interp_v3_v3v3(stroke_color_, stroke_color_, avg_color, avg_color[3]);
327  avg_opacity_ /= (float)gps->totpoints;
328 
329  /* Fill color. */
330  copy_v4_v4(fill_color_, gp_style->fill_rgba);
331  /* Apply vertex color for fill. */
333 }
334 
336 {
337  return avg_opacity_;
338 }
339 
341 {
342  return is_camera_;
343 }
344 
346 {
347  return is_ortho_;
348 }
349 
350 /* Calculate selected strokes boundbox. */
352 {
353  const float gap = 10.0f;
354 
355  float2 min, max;
356  INIT_MINMAX2(min, max);
357 
358  for (ObjectZ &obz : ob_list_) {
359  Object *ob = obz.ob;
360  /* Use evaluated version to get strokes with modifiers. */
361  Object *ob_eval = (Object *)DEG_get_evaluated_id(depsgraph_, &ob->id);
362  bGPdata *gpd_eval = (bGPdata *)ob_eval->data;
363 
364  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_eval->layers) {
365  if (gpl->flag & GP_LAYER_HIDE) {
366  continue;
367  }
369 
370  bGPDframe *gpf = gpl->actframe;
371  if (gpf == nullptr) {
372  continue;
373  }
374 
375  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
376  if (gps->totpoints == 0) {
377  continue;
378  }
379  for (const bGPDspoint &pt : MutableSpan(gps->points, gps->totpoints)) {
380  const float2 screen_co = gpencil_3D_point_to_2D(&pt.x);
381  minmax_v2v2_v2(min, max, screen_co);
382  }
383  }
384  }
385  }
386  /* Add small gap. */
387  add_v2_fl(min, gap * -1.0f);
388  add_v2_fl(max, gap);
389 
390  select_boundbox_.xmin = min[0];
391  select_boundbox_.ymin = min[1];
392  select_boundbox_.xmax = max[0];
393  select_boundbox_.ymax = max[1];
394 }
395 
397 {
398  boundbox->xmin = select_boundbox_.xmin;
399  boundbox->xmax = select_boundbox_.xmax;
400  boundbox->ymin = select_boundbox_.ymin;
401  boundbox->ymax = select_boundbox_.ymax;
402 }
403 
404 void GpencilIO::frame_number_set(const int value)
405 {
406  cfra_ = value;
407 }
408 
409 } // namespace blender::io::gpencil
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
void BKE_camera_params_init(CameraParams *params)
Definition: camera.c:271
void BKE_camera_params_from_object(CameraParams *params, const struct Object *cam_ob)
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float aspx, float aspy)
Definition: camera.c:370
void BKE_camera_params_compute_matrix(CameraParams *params)
Definition: camera.c:436
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
void BKE_gpencil_free_stroke(struct bGPDstroke *gps)
Definition: gpencil.c:401
void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph, struct Object *obact, struct bGPDlayer *gpl, float diff_mat[4][4])
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])
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
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 float max_ff(float a, float b)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
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 sub_v2_v2(float r[2], const float a[2])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
Definition: math_vector.c:1043
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v2_fl(float r[2], float f)
#define FILE_MAX
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define INIT_MINMAX2(min, max)
#define MAX2(a, b)
#define ELEM(...)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
@ GP_LAYER_HIDE
@ BASE_SELECTED
@ OB_GPENCIL
#define RV3D_CAMOB
void ED_view3d_calc_camera_border(const struct Scene *scene, struct Depsgraph *depsgraph, const struct ARegion *region, const struct View3D *v3d, const struct RegionView3D *rv3d, struct rctf *r_viewborder, const bool no_shift)
eV3DProjTest
Definition: ED_view3d.h:192
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:176
eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip)
_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 v1
#define V2D_IS_CLIPPED
Definition: UI_view2d.h:40
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
void prepare_camera_params(const GpencilIOParams *iparams)
void selected_objects_boundbox_get(rctf *boundbox)
void frame_number_set(const int value)
float stroke_point_radius_get(struct bGPDlayer *gpl, struct bGPDstroke *gps)
GpencilIO(const GpencilIOParams *iparams)
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)
float2 gpencil_3D_point_to_render_space(const float3 co, const bool is_ortho)
void filename_set(const char *filename)
bool gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co)
void prepare_layer_export_matrix(struct Object *ob, struct bGPDlayer *gpl)
@ GP_EXPORT_SELECTED
Definition: gpencil_io.h:77
@ GP_EXPORT_ACTIVE
Definition: gpencil_io.h:76
@ GP_EXPORT_TO_PDF
Definition: gpencil_io.h:68
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define min(a, b)
Definition: sort.c:51
void * regiondata
int32_t frame_cur
Definition: gpencil_io.h:44
uint16_t select_mode
Definition: gpencil_io.h:48
bContext * C
Definition: gpencil_io.h:35
uint16_t mode
Definition: gpencil_io.h:41
View3D * v3d
Definition: gpencil_io.h:37
ARegion * region
Definition: gpencil_io.h:36
Object * ob
Definition: gpencil_io.h:39
float obmat[4][4]
void * data
float viewinv[4][4]
struct RenderData r
struct Object * camera
ListBase object_bases
ListBase strokes
float layer_invmat[4][4]
bGPDspoint * points
float vert_color_fill[4]
ListBase layers
float values[4][4]
Definition: BLI_float4x4.hh:25
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
float max