Fix/Cleanup: I18N: Bad usage of IFACE_ instead of TIP_.
[blender.git] / source / blender / editors / util / ed_util.c
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) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edutil
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_armature_types.h"
31 #include "DNA_mesh_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_screen_types.h"
34 #include "DNA_space_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_packedFile_types.h"
37
38 #include "BLI_utildefines.h"
39 #include "BLI_string.h"
40 #include "BLI_path_util.h"
41
42 #include "BLT_translation.h"
43
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_layer.h"
47 #include "BKE_main.h"
48 #include "BKE_multires.h"
49 #include "BKE_object.h"
50 #include "BKE_packedFile.h"
51 #include "BKE_paint.h"
52 #include "BKE_screen.h"
53 #include "BKE_undo_system.h"
54 #include "BKE_workspace.h"
55 #include "BKE_material.h"
56
57 #include "DEG_depsgraph.h"
58
59 #include "ED_armature.h"
60 #include "ED_buttons.h"
61 #include "ED_image.h"
62 #include "ED_mesh.h"
63 #include "ED_node.h"
64 #include "ED_object.h"
65 #include "ED_outliner.h"
66 #include "ED_paint.h"
67 #include "ED_space_api.h"
68 #include "ED_util.h"
69
70 #include "GPU_immediate.h"
71 #include "GPU_state.h"
72
73 #include "UI_interface.h"
74 #include "UI_resources.h"
75
76 #include "WM_types.h"
77 #include "WM_api.h"
78 #include "RNA_access.h"
79
80 /* ********* general editor util funcs, not BKE stuff please! ********* */
81
82 void ED_editors_init_for_undo(Main *bmain)
83 {
84   wmWindowManager *wm = bmain->wm.first;
85   for (wmWindow *win = wm->windows.first; win; win = win->next) {
86     ViewLayer *view_layer = WM_window_get_active_view_layer(win);
87     Base *base = BASACT(view_layer);
88     if (base != NULL) {
89       Object *ob = base->object;
90       if (ob->mode & OB_MODE_TEXTURE_PAINT) {
91         Scene *scene = WM_window_get_active_scene(win);
92
93         BKE_texpaint_slots_refresh_object(scene, ob);
94         BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
95       }
96     }
97   }
98 }
99
100 void ED_editors_init(bContext *C)
101 {
102   struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
103   Main *bmain = CTX_data_main(C);
104   Scene *scene = CTX_data_scene(C);
105   wmWindowManager *wm = CTX_wm_manager(C);
106
107   /* This is called during initialization, so we don't want to store any reports */
108   ReportList *reports = CTX_wm_reports(C);
109   int reports_flag_prev = reports->flag & ~RPT_STORE;
110
111   SWAP(int, reports->flag, reports_flag_prev);
112
113   /* Don't do undo pushes when calling an operator. */
114   wm->op_undo_depth++;
115
116   /* toggle on modes for objects that were saved with these enabled. for
117    * e.g. linked objects we have to ensure that they are actually the
118    * active object in this scene. */
119   Object *obact = CTX_data_active_object(C);
120   for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
121     int mode = ob->mode;
122     if (mode == OB_MODE_OBJECT) {
123       continue;
124     }
125     else if (BKE_object_has_mode_data(ob, mode)) {
126       continue;
127     }
128     else if (ob->type == OB_GPENCIL) {
129       /* For multi-edit mode we may already have mode data.
130        * (grease pencil does not need it) */
131       continue;
132     }
133
134     ID *ob_data = ob->data;
135     ob->mode = OB_MODE_OBJECT;
136     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
137     if (obact && (ob->type == obact->type) && !ID_IS_LINKED(ob) &&
138         !(ob_data && ID_IS_LINKED(ob_data))) {
139       if (mode == OB_MODE_EDIT) {
140         ED_object_editmode_enter_ex(bmain, scene, ob, 0);
141       }
142       else if (mode == OB_MODE_POSE) {
143         ED_object_posemode_enter_ex(bmain, ob);
144       }
145       else if (mode & OB_MODE_ALL_SCULPT) {
146         if (obact == ob) {
147           if (mode == OB_MODE_SCULPT) {
148             ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, true, reports);
149           }
150           else if (mode == OB_MODE_VERTEX_PAINT) {
151             ED_object_vpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob);
152           }
153           else if (mode == OB_MODE_WEIGHT_PAINT) {
154             ED_object_wpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob);
155           }
156           else {
157             BLI_assert(0);
158           }
159         }
160         else {
161           /* Create data for non-active objects which need it for
162            * mode-switching but don't yet support multi-editing. */
163           if (mode & OB_MODE_ALL_SCULPT) {
164             ob->mode = mode;
165             BKE_object_sculpt_data_create(ob);
166           }
167         }
168       }
169       else {
170         /* TODO(campbell): avoid operator calls. */
171         if (obact == ob) {
172           ED_object_mode_toggle(C, mode);
173         }
174       }
175     }
176   }
177
178   /* image editor paint mode */
179   if (scene) {
180     ED_space_image_paint_update(bmain, wm, scene);
181   }
182
183   SWAP(int, reports->flag, reports_flag_prev);
184   wm->op_undo_depth--;
185 }
186
187 /* frees all editmode stuff */
188 void ED_editors_exit(Main *bmain, bool do_undo_system)
189 {
190   if (!bmain) {
191     return;
192   }
193
194   /* frees all editmode undos */
195   if (do_undo_system && G_MAIN->wm.first) {
196     wmWindowManager *wm = G_MAIN->wm.first;
197     /* normally we don't check for NULL undo stack,
198      * do here since it may run in different context. */
199     if (wm->undo_stack) {
200       BKE_undosys_stack_destroy(wm->undo_stack);
201       wm->undo_stack = NULL;
202     }
203   }
204
205   for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
206     if (ob->type == OB_MESH) {
207       Mesh *me = ob->data;
208       if (me->edit_mesh) {
209         EDBM_mesh_free(me->edit_mesh);
210         MEM_freeN(me->edit_mesh);
211         me->edit_mesh = NULL;
212       }
213     }
214     else if (ob->type == OB_ARMATURE) {
215       bArmature *arm = ob->data;
216       if (arm->edbo) {
217         ED_armature_edit_free(ob->data);
218       }
219     }
220   }
221
222   /* global in meshtools... */
223   ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
224   ED_mesh_mirror_topo_table(NULL, NULL, 'e');
225 }
226
227 /* flush any temp data from object editing to DNA before writing files,
228  * rendering, copying, etc. */
229 bool ED_editors_flush_edits(Main *bmain, bool for_render)
230 {
231   bool has_edited = false;
232   Object *ob;
233
234   /* loop through all data to find edit mode or object mode, because during
235    * exiting we might not have a context for edit object and multiple sculpt
236    * objects can exist at the same time */
237   for (ob = bmain->objects.first; ob; ob = ob->id.next) {
238     if (ob->mode & OB_MODE_SCULPT) {
239       /* Don't allow flushing while in the middle of a stroke (frees data in use).
240        * Auto-save prevents this from happening but scripts
241        * may cause a flush on saving: T53986. */
242       if ((ob->sculpt && ob->sculpt->cache) == 0) {
243         /* flush multires changes (for sculpt) */
244         multires_force_update(ob);
245         has_edited = true;
246
247         if (for_render) {
248           /* flush changes from dynamic topology sculpt */
249           BKE_sculptsession_bm_to_me_for_render(ob);
250         }
251         else {
252           /* Set reorder=false so that saving the file doesn't reorder
253            * the BMesh's elements */
254           BKE_sculptsession_bm_to_me(ob, false);
255         }
256       }
257     }
258     else if (ob->mode & OB_MODE_EDIT) {
259       /* get editmode results */
260       has_edited = true;
261       ED_object_editmode_load(bmain, ob);
262     }
263   }
264
265   return has_edited;
266 }
267
268 /* ***** XXX: functions are using old blender names, cleanup later ***** */
269
270 /* now only used in 2d spaces, like time, ipo, nla, sima... */
271 /* XXX shift/ctrl not configurable */
272 void apply_keyb_grid(
273     int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
274 {
275   /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
276   if (invert) {
277     ctrl = !ctrl;
278   }
279
280   if (ctrl && shift) {
281     if (fac3 != 0.0f) {
282       *val = fac3 * floorf(*val / fac3 + 0.5f);
283     }
284   }
285   else if (ctrl) {
286     if (fac2 != 0.0f) {
287       *val = fac2 * floorf(*val / fac2 + 0.5f);
288     }
289   }
290   else {
291     if (fac1 != 0.0f) {
292       *val = fac1 * floorf(*val / fac1 + 0.5f);
293     }
294   }
295 }
296
297 void unpack_menu(bContext *C,
298                  const char *opname,
299                  const char *id_name,
300                  const char *abs_name,
301                  const char *folder,
302                  struct PackedFile *pf)
303 {
304   Main *bmain = CTX_data_main(C);
305   PointerRNA props_ptr;
306   uiPopupMenu *pup;
307   uiLayout *layout;
308   char line[FILE_MAX + 100];
309   wmOperatorType *ot = WM_operatortype_find(opname, 1);
310
311   pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE);
312   layout = UI_popup_menu_layout(pup);
313
314   uiItemFullO_ptr(
315       layout, ot, IFACE_("Remove Pack"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
316   RNA_enum_set(&props_ptr, "method", PF_REMOVE);
317   RNA_string_set(&props_ptr, "id", id_name);
318
319   if (G.relbase_valid) {
320     char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
321
322     BLI_split_file_part(abs_name, fi, sizeof(fi));
323     BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
324     if (!STREQ(abs_name, local_name)) {
325       switch (checkPackedFile(BKE_main_blendfile_path(bmain), local_name, pf)) {
326         case PF_NOFILE:
327           BLI_snprintf(line, sizeof(line), TIP_("Create %s"), local_name);
328           uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
329           RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
330           RNA_string_set(&props_ptr, "id", id_name);
331
332           break;
333         case PF_EQUAL:
334           BLI_snprintf(line, sizeof(line), TIP_("Use %s (identical)"), local_name);
335           // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
336           uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
337           RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
338           RNA_string_set(&props_ptr, "id", id_name);
339
340           break;
341         case PF_DIFFERS:
342           BLI_snprintf(line, sizeof(line), TIP_("Use %s (differs)"), local_name);
343           // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
344           uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
345           RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
346           RNA_string_set(&props_ptr, "id", id_name);
347
348           BLI_snprintf(line, sizeof(line), TIP_("Overwrite %s"), local_name);
349           // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL);
350           uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
351           RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
352           RNA_string_set(&props_ptr, "id", id_name);
353           break;
354       }
355     }
356   }
357
358   switch (checkPackedFile(BKE_main_blendfile_path(bmain), abs_name, pf)) {
359     case PF_NOFILE:
360       BLI_snprintf(line, sizeof(line), TIP_("Create %s"), abs_name);
361       // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
362       uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
363       RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
364       RNA_string_set(&props_ptr, "id", id_name);
365       break;
366     case PF_EQUAL:
367       BLI_snprintf(line, sizeof(line), TIP_("Use %s (identical)"), abs_name);
368       // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
369       uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
370       RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
371       RNA_string_set(&props_ptr, "id", id_name);
372       break;
373     case PF_DIFFERS:
374       BLI_snprintf(line, sizeof(line), TIP_("Use %s (differs)"), abs_name);
375       // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
376       uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
377       RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
378       RNA_string_set(&props_ptr, "id", id_name);
379
380       BLI_snprintf(line, sizeof(line), TIP_("Overwrite %s"), abs_name);
381       // uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
382       uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
383       RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
384       RNA_string_set(&props_ptr, "id", id_name);
385       break;
386   }
387
388   UI_popup_menu_end(C, pup);
389 }
390
391 /* ********************* generic callbacks for drawcall api *********************** */
392
393 /**
394  * Callback that draws a line between the mouse and a position given as the initial argument.
395  */
396 void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info)
397 {
398   wmWindow *win = CTX_wm_window(C);
399   const float *mval_src = (float *)arg_info;
400   const float mval_dst[2] = {
401       win->eventstate->x - ar->winrct.xmin,
402       win->eventstate->y - ar->winrct.ymin,
403   };
404
405   const uint shdr_pos = GPU_vertformat_attr_add(
406       immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
407
408   GPU_line_width(1.0f);
409
410   immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
411
412   float viewport_size[4];
413   GPU_viewport_size_get_f(viewport_size);
414   immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
415
416   immUniform1i("colors_len", 0); /* "simple" mode */
417   immUniformThemeColor(TH_VIEW_OVERLAY);
418   immUniform1f("dash_width", 6.0f);
419   immUniform1f("dash_factor", 0.5f);
420
421   immBegin(GPU_PRIM_LINES, 2);
422   immVertex2fv(shdr_pos, mval_src);
423   immVertex2fv(shdr_pos, mval_dst);
424   immEnd();
425
426   immUnbindProgram();
427 }
428
429 /**
430  * Use to free ID references within runtime data (stored outside of DNA)
431  *
432  * \param new_id: may be NULL to unlink \a old_id.
433  */
434 void ED_spacedata_id_remap(struct ScrArea *sa, struct SpaceLink *sl, ID *old_id, ID *new_id)
435 {
436   SpaceType *st = BKE_spacetype_from_id(sl->spacetype);
437
438   if (st && st->id_remap) {
439     st->id_remap(sa, sl, old_id, new_id);
440   }
441 }
442
443 static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op))
444 {
445   Main *bmain = CTX_data_main(C);
446   ED_editors_flush_edits(bmain, false);
447   return OPERATOR_FINISHED;
448 }
449
450 void ED_OT_flush_edits(wmOperatorType *ot)
451 {
452   /* identifiers */
453   ot->name = "Flush Edits";
454   ot->description = "Flush edit data from active editing modes";
455   ot->idname = "ED_OT_flush_edits";
456
457   /* api callbacks */
458   ot->exec = ed_flush_edits_exec;
459
460   /* flags */
461   ot->flag = OPTYPE_INTERNAL;
462 }