Blender  V2.93
gpencil_trace_ops.c
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 "MEM_guardedalloc.h"
25 
26 #include "BLI_math.h"
27 
28 #include "BLT_translation.h"
29 
30 #include "DNA_gpencil_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 
34 #include "BKE_context.h"
35 #include "BKE_global.h"
36 #include "BKE_gpencil.h"
37 #include "BKE_image.h"
38 #include "BKE_layer.h"
39 #include "BKE_lib_id.h"
40 #include "BKE_main.h"
41 #include "BKE_object.h"
42 #include "BKE_report.h"
43 
44 #include "DEG_depsgraph.h"
45 #include "DEG_depsgraph_query.h"
46 
47 #include "WM_api.h"
48 #include "WM_types.h"
49 
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 
53 #include "IMB_imbuf_types.h"
54 
55 #include "ED_gpencil.h"
56 #include "ED_object.h"
57 
58 #include "gpencil_intern.h"
59 #include "gpencil_trace.h"
60 
61 typedef struct TraceJob {
62  /* from wmJob */
63  struct Object *owner;
64  short *stop, *do_update;
65  float *progress;
66 
78 
81 
83  float threshold;
84  float scale;
85  float sample;
90 
91  bool success;
94 
100 static bool gpencil_trace_image(TraceJob *trace_job, ImBuf *ibuf, bGPDframe *gpf)
101 {
102  potrace_bitmap_t *bm = NULL;
103  potrace_param_t *param = NULL;
104  potrace_state_t *st = NULL;
105 
106  /* Create an empty BW bitmap. */
107  bm = ED_gpencil_trace_bitmap_new(ibuf->x, ibuf->y);
108  if (!bm) {
109  return false;
110  }
111 
112  /* Set tracing parameters, starting from defaults */
113  param = potrace_param_default();
114  if (!param) {
115  return false;
116  }
117  param->turdsize = 0;
118  param->turnpolicy = trace_job->turnpolicy;
119 
120  /* Load BW bitmap with image. */
121  ED_gpencil_trace_image_to_bitmap(ibuf, bm, trace_job->threshold);
122 
123  /* Trace the bitmap. */
124  st = potrace_trace(param, bm);
125  if (!st || st->status != POTRACE_STATUS_OK) {
127  if (st) {
128  potrace_state_free(st);
129  }
130  potrace_param_free(param);
131  return false;
132  }
133  /* Free BW bitmap. */
135 
136  /* Convert the trace to strokes. */
137  int32_t offset[2];
138  offset[0] = ibuf->x / 2;
139  offset[1] = ibuf->y / 2;
140 
141  /* Scale correction for Potrace.
142  * Really, there isn't documented in Potrace about how the scale is calculated,
143  * but after doing a lot of tests, it looks is using a VGA resolution (640) as a base.
144  * Maybe there are others ways to get the right scale conversion, but this solution works. */
145  float scale_potrace = trace_job->scale * (640.0f / (float)ibuf->x) *
146  ((float)ibuf->x / (float)ibuf->y);
147  if (ibuf->x > ibuf->y) {
148  scale_potrace *= (float)ibuf->y / (float)ibuf->x;
149  }
150 
152  st,
153  trace_job->ob_gpencil,
154  gpf,
155  offset,
156  scale_potrace,
157  trace_job->sample,
158  trace_job->resolution,
159  trace_job->thickness);
160 
161  /* Free memory. */
162  potrace_state_free(st);
163  potrace_param_free(param);
164 
165  return true;
166 }
167 
168 /* Trace Image to Grease Pencil. */
170 {
172  if ((ob == NULL) || (ob->type != OB_EMPTY) || (ob->data == NULL)) {
173  CTX_wm_operator_poll_msg_set(C, "No image empty selected");
174  return false;
175  }
176 
177  Image *image = (Image *)ob->data;
179  CTX_wm_operator_poll_msg_set(C, "No valid image format selected");
180  return false;
181  }
182 
183  return true;
184 }
185 
186 static void trace_initialize_job_data(TraceJob *trace_job)
187 {
188  /* Create a new grease pencil object. */
189  if (trace_job->ob_gpencil == NULL) {
190  ushort local_view_bits = (trace_job->v3d && trace_job->v3d->localvd) ?
191  trace_job->v3d->local_view_uuid :
192  0;
193  trace_job->ob_gpencil = ED_gpencil_add_object(
194  trace_job->C, trace_job->ob_active->loc, local_view_bits);
195  /* Apply image rotation. */
196  copy_v3_v3(trace_job->ob_gpencil->rot, trace_job->ob_active->rot);
197  /* Grease pencil is rotated 90 degrees in X axis by default. */
198  trace_job->ob_gpencil->rot[0] -= DEG2RADF(90.0f);
199  trace_job->was_ob_created = true;
200  /* Apply image Scale. */
201  copy_v3_v3(trace_job->ob_gpencil->scale, trace_job->ob_active->scale);
202  /* The default display size of the image is 5.0 and this is used as scale = 1.0. */
203  mul_v3_fl(trace_job->ob_gpencil->scale, trace_job->ob_active->empty_drawsize / 5.0f);
204  }
205 
206  /* Create Layer. */
207  trace_job->gpd = (bGPdata *)trace_job->ob_gpencil->data;
208  trace_job->gpl = BKE_gpencil_layer_active_get(trace_job->gpd);
209  if (trace_job->gpl == NULL) {
210  trace_job->gpl = BKE_gpencil_layer_addnew(trace_job->gpd, DATA_("Trace"), true);
211  }
212 }
213 
214 static void trace_start_job(void *customdata, short *stop, short *do_update, float *progress)
215 {
216  TraceJob *trace_job = customdata;
217 
218  trace_job->stop = stop;
219  trace_job->do_update = do_update;
220  trace_job->progress = progress;
221  trace_job->was_canceled = false;
222  const int init_frame = max_ii((trace_job->use_current_frame) ? trace_job->frame_target : 0, 0);
223 
224  G.is_break = false;
225 
226  /* Single Image. */
227  if ((trace_job->image->source == IMA_SRC_FILE) ||
228  (trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) {
229  void *lock;
230  ImageUser *iuser = trace_job->ob_active->iuser;
231  iuser->framenr = init_frame;
232  ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
233  if (ibuf) {
234  /* Create frame. */
236  trace_job->gpl, trace_job->frame_target, GP_GETFRAME_ADD_NEW);
237  gpencil_trace_image(trace_job, ibuf, gpf);
238  BKE_image_release_ibuf(trace_job->image, ibuf, lock);
239  *(trace_job->progress) = 1.0f;
240  }
241  }
242  /* Image sequence. */
243  else if (trace_job->image->type == IMA_TYPE_IMAGE) {
244  ImageUser *iuser = trace_job->ob_active->iuser;
245  for (int i = init_frame; i < iuser->frames; i++) {
246  if (G.is_break) {
247  trace_job->was_canceled = true;
248  break;
249  }
250 
251  *(trace_job->progress) = (float)i / (float)iuser->frames;
252  *do_update = true;
253 
254  iuser->framenr = i + 1;
255 
256  void *lock;
257  ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
258  if (ibuf) {
259  /* Create frame. */
261  gpencil_trace_image(trace_job, ibuf, gpf);
262 
263  BKE_image_release_ibuf(trace_job->image, ibuf, lock);
264  }
265  }
266  }
267 
268  trace_job->success = !trace_job->was_canceled;
269  *do_update = true;
270  *stop = 0;
271 }
272 
273 static void trace_end_job(void *customdata)
274 {
275  TraceJob *trace_job = customdata;
276 
277  /* If canceled, delete all previously created object and data-block. */
278  if ((trace_job->was_canceled) && (trace_job->was_ob_created) && (trace_job->ob_gpencil)) {
279  bGPdata *gpd = trace_job->ob_gpencil->data;
280  BKE_id_delete(trace_job->bmain, &trace_job->ob_gpencil->id);
281  BKE_id_delete(trace_job->bmain, &gpd->id);
282  }
283 
284  if (trace_job->success) {
285  DEG_relations_tag_update(trace_job->bmain);
286 
289 
292  }
293 }
294 
295 static void trace_free_job(void *customdata)
296 {
297  TraceJob *tj = customdata;
298  MEM_freeN(tj);
299 }
300 
302 {
303  TraceJob *job = MEM_mallocN(sizeof(TraceJob), "TraceJob");
304  job->C = C;
306  job->wm = CTX_wm_manager(C);
307  job->bmain = CTX_data_main(C);
309  job->scene = scene;
310  job->v3d = CTX_wm_view3d(C);
312  job->ob_active = job->base_active->object;
313  job->image = (Image *)job->ob_active->data;
314  job->frame_target = CFRA;
315  job->use_current_frame = RNA_boolean_get(op->ptr, "use_current_frame");
316 
317  /* Create a new grease pencil object or reuse selected. */
318  eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
320  CTX_data_view_layer(C), job->v3d) :
321  NULL;
322 
323  if (job->ob_gpencil != NULL) {
324  if (job->ob_gpencil->type != OB_GPENCIL) {
325  BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!");
326  job->ob_gpencil = NULL;
327  }
328  else if (BKE_object_obdata_is_libdata(job->ob_gpencil)) {
329  BKE_report(op->reports, RPT_WARNING, "Target object library-data, ignoring!");
330  job->ob_gpencil = NULL;
331  }
332  }
333 
334  job->was_ob_created = false;
335 
336  job->threshold = RNA_float_get(op->ptr, "threshold");
337  job->scale = RNA_float_get(op->ptr, "scale");
338  job->sample = RNA_float_get(op->ptr, "sample");
339  job->resolution = RNA_int_get(op->ptr, "resolution");
340  job->thickness = RNA_int_get(op->ptr, "thickness");
341  job->turnpolicy = RNA_enum_get(op->ptr, "turnpolicy");
342  job->mode = RNA_enum_get(op->ptr, "mode");
343 
345 
346  /* Back to active base. */
348 
349  if (job->image->source == IMA_SRC_FILE) {
350  short stop = 0, do_update = true;
351  float progress;
352  trace_start_job(job, &stop, &do_update, &progress);
353  trace_end_job(job);
354  trace_free_job(job);
355  }
356  else {
357  wmJob *wm_job = WM_jobs_get(job->wm,
358  CTX_wm_window(C),
359  job->scene,
360  "Trace Image",
363 
365  WM_jobs_timer(wm_job, 0.1, NC_GEOM | ND_DATA, NC_GEOM | ND_DATA);
367 
368  WM_jobs_start(CTX_wm_manager(C), wm_job);
369  }
370 
371  return OPERATOR_FINISHED;
372 }
373 
375 {
376  /* Show popup dialog to allow editing. */
377  /* FIXME: hard-coded dimensions here are just arbitrary. */
378  return WM_operator_props_dialog_popup(C, op, 250);
379 }
380 
382 {
383  static const EnumPropertyItem turnpolicy_type[] = {
384  {POTRACE_TURNPOLICY_BLACK,
385  "BLACK",
386  0,
387  "Black",
388  "Prefers to connect black (foreground) components"},
389  {POTRACE_TURNPOLICY_WHITE,
390  "WHITE",
391  0,
392  "White",
393  "Prefers to connect white (background) components"},
394  {POTRACE_TURNPOLICY_LEFT, "LEFT", 0, "Left", "Always take a left turn"},
395  {POTRACE_TURNPOLICY_RIGHT, "RIGHT", 0, "Right", "Always take a right turn"},
396  {POTRACE_TURNPOLICY_MINORITY,
397  "MINORITY",
398  0,
399  "Minority",
400  "Prefers to connect the color (black or white) that occurs least frequently in the local "
401  "neighborhood of the current position"},
402  {POTRACE_TURNPOLICY_MAJORITY,
403  "MAJORITY",
404  0,
405  "Majority",
406  "Prefers to connect the color (black or white) that occurs most frequently in the local "
407  "neighborhood of the current position"},
408  {POTRACE_TURNPOLICY_RANDOM, "RANDOM", 0, "Random", "Choose pseudo-randomly"},
409  {0, NULL, 0, NULL, NULL},
410  };
411 
412  static const EnumPropertyItem trace_modes[] = {
413  {GPENCIL_TRACE_MODE_SINGLE, "SINGLE", 0, "Single", "Trace the current frame of the image"},
414  {GPENCIL_TRACE_MODE_SEQUENCE, "SEQUENCE", 0, "Sequence", "Trace full sequence"},
415  {0, NULL, 0, NULL, NULL},
416  };
417 
418  static const EnumPropertyItem target_object_modes[] = {
419  {GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""},
420  {GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""},
421  {0, NULL, 0, NULL, NULL},
422  };
423 
424  /* identifiers */
425  ot->name = "Trace Image to Grease Pencil";
426  ot->idname = "GPENCIL_OT_trace_image";
427  ot->description = "Extract Grease Pencil strokes from image";
428 
429  /* callbacks */
433 
434  /* flags */
436 
437  /* properties */
438  ot->prop = RNA_def_enum(ot->srna,
439  "target",
440  target_object_modes,
442  "Target Object",
443  "Target grease pencil");
445 
446  RNA_def_int(ot->srna, "thickness", 10, 1, 1000, "Thickness", "", 1, 1000);
447  RNA_def_int(
448  ot->srna, "resolution", 5, 1, 20, "Resolution", "Resolution of the generated curves", 1, 20);
449 
451  "scale",
452  1.0f,
453  0.001f,
454  100.0f,
455  "Scale",
456  "Scale of the final stroke",
457  0.001f,
458  100.0f);
460  "sample",
461  0.0f,
462  0.0f,
463  100.0f,
464  "Sample",
465  "Distance to sample points, zero to disable",
466  0.0f,
467  100.0f);
469  "threshold",
470  0.5f,
471  0.0f,
472  1.0f,
473  "Color Threshold",
474  "Determine the lightness threshold above which strokes are generated",
475  0.0f,
476  1.0f);
478  "turnpolicy",
479  turnpolicy_type,
480  POTRACE_TURNPOLICY_MINORITY,
481  "Turn Policy",
482  "Determines how to resolve ambiguities during decomposition of bitmaps into paths");
484  "mode",
485  trace_modes,
487  "Mode",
488  "Determines if trace simple image or full sequence");
490  "use_current_frame",
491  true,
492  "Start At Current Frame",
493  "Trace Image starting in current image frame");
494 }
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Base * CTX_data_active_base(const bContext *C)
Definition: context.c:1284
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
Definition: context.c:1006
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
struct bGPDlayer * BKE_gpencil_layer_active_get(struct bGPdata *gpd)
Definition: gpencil.c:1650
struct bGPDframe * BKE_gpencil_layer_frame_get(struct bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
Definition: gpencil.c:1307
struct bGPDlayer * BKE_gpencil_layer_addnew(struct bGPdata *gpd, const char *name, bool setactive)
Definition: gpencil.c:659
@ GP_GETFRAME_ADD_NEW
Definition: BKE_gpencil.h:190
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
Definition: image.c:5113
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
Definition: image.c:5100
struct Object * BKE_view_layer_non_active_selected_object(struct ViewLayer *view_layer, const struct View3D *v3d)
Definition: layer_utils.c:202
void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL()
General operations, lookup, etc. for blender objects.
bool BKE_object_obdata_is_libdata(const struct Object *ob)
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
MINLINE int max_ii(int a, int b)
#define DEG2RADF(_deg)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
unsigned short ushort
Definition: BLI_sys_types.h:84
#define UNUSED(x)
#define ELEM(...)
#define DATA_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_SELECT
Definition: DNA_ID.h:638
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ IMA_TYPE_IMAGE
@ IMA_SRC_FILE
@ IMA_SRC_MOVIE
@ IMA_SRC_SEQUENCE
@ OB_EMPTY
@ OB_GPENCIL
#define CFRA
@ OPERATOR_FINISHED
eGP_TargetObjectMode
Definition: ED_gpencil.h:84
@ GP_TARGET_OB_SELECTED
Definition: ED_gpencil.h:86
@ GP_TARGET_OB_NEW
Definition: ED_gpencil.h:85
void ED_object_base_activate(struct bContext *C, struct Base *base)
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
@ WM_JOB_TYPE_TRACE_IMAGE
Definition: WM_api.h:757
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
#define NC_GEOM
Definition: WM_types.h:294
#define ND_OB_ACTIVE
Definition: WM_types.h:340
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DATA
Definition: WM_types.h:408
#define NC_SCENE
Definition: WM_types.h:279
#define NA_ADDED
Definition: WM_types.h:464
#define NC_OBJECT
Definition: WM_types.h:280
ATTR_WARN_UNUSED_RESULT BMesh * bm
short type
short source
Scene scene
#define GPENCIL_TRACE_MODE_SINGLE
Definition: gpencil_trace.h:59
void ED_gpencil_trace_bitmap_free(const potrace_bitmap_t *bm)
#define GPENCIL_TRACE_MODE_SEQUENCE
Definition: gpencil_trace.h:60
void ED_gpencil_trace_data_to_strokes(struct Main *bmain, potrace_state_t *st, struct Object *ob, struct bGPDframe *gpf, int32_t offset[2], const float scale, const float sample, const int32_t resolution, const int32_t thickness)
void ED_gpencil_trace_image_to_bitmap(struct ImBuf *ibuf, const potrace_bitmap_t *bm, const float threshold)
potrace_bitmap_t * ED_gpencil_trace_bitmap_new(int32_t w, int32_t h)
static bool gpencil_trace_image_poll(bContext *C)
struct TraceJob TraceJob
static bool gpencil_trace_image(TraceJob *trace_job, ImBuf *ibuf, bGPDframe *gpf)
static void trace_free_job(void *customdata)
static int gpencil_trace_image_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static void trace_start_job(void *customdata, short *stop, short *do_update, float *progress)
static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
static void trace_end_job(void *customdata)
void GPENCIL_OT_trace_image(wmOperatorType *ot)
static void trace_initialize_job_data(TraceJob *trace_job)
Object * ED_gpencil_add_object(bContext *C, const float loc[3], ushort local_view_bits)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:4133
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
signed int int32_t
Definition: stdint.h:80
struct Object * object
Definition: BKE_main.h:116
float loc[3]
float scale[3]
float rot[3]
ImageUser * iuser
float empty_drawsize
void * data
bool use_current_frame
bContext * C
int32_t thickness
bGPdata * gpd
int32_t resolution
bool was_ob_created
Scene * scene
float * progress
Image * image
View3D * v3d
Object * ob_active
int32_t mode
Object * ob_gpencil
struct Object * owner
short * do_update
Base * base_active
int32_t turnpolicy
int32_t frame_target
bGPDlayer * gpl
wmWindowManager * wm
short * stop
unsigned short local_view_uuid
struct View3D * localvd
Definition: wm_jobs.c:73
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
#define G(x, y, z)
void WM_main_add_notifier(unsigned int type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:450
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:372
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width)