Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / editors / object / object_edit.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
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) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2008 full recode
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/object/object_edit.c
27  *  \ingroup edobj
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <time.h>
34 #include <float.h>
35 #include <ctype.h>
36 #include <stddef.h> //for offsetof
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_math.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_ghash.h"
44 #include "BLI_string_utils.h"
45
46 #include "BLT_translation.h"
47
48 #include "DNA_armature_types.h"
49 #include "DNA_curve_types.h"
50 #include "DNA_gpencil_types.h"
51 #include "DNA_group_types.h"
52 #include "DNA_material_types.h"
53 #include "DNA_meta_types.h"
54 #include "DNA_property_types.h"
55 #include "DNA_scene_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_object_force.h"
58 #include "DNA_meshdata_types.h"
59 #include "DNA_vfont_types.h"
60 #include "DNA_mesh_types.h"
61 #include "DNA_workspace_types.h"
62
63 #include "IMB_imbuf_types.h"
64
65 #include "BKE_anim.h"
66 #include "BKE_constraint.h"
67 #include "BKE_context.h"
68 #include "BKE_curve.h"
69 #include "BKE_effect.h"
70 #include "BKE_global.h"
71 #include "BKE_image.h"
72 #include "BKE_lattice.h"
73 #include "BKE_library.h"
74 #include "BKE_main.h"
75 #include "BKE_material.h"
76 #include "BKE_mball.h"
77 #include "BKE_mesh.h"
78 #include "BKE_object.h"
79 #include "BKE_pointcache.h"
80 #include "BKE_property.h"
81 #include "BKE_sca.h"
82 #include "BKE_softbody.h"
83 #include "BKE_modifier.h"
84 #include "BKE_editmesh.h"
85 #include "BKE_report.h"
86 #include "BKE_workspace.h"
87
88 #include "DEG_depsgraph.h"
89 #include "DEG_depsgraph_build.h"
90
91 #include "ED_armature.h"
92 #include "ED_curve.h"
93 #include "ED_mesh.h"
94 #include "ED_mball.h"
95 #include "ED_lattice.h"
96 #include "ED_object.h"
97 #include "ED_screen.h"
98 #include "ED_util.h"
99 #include "ED_image.h"
100
101 #include "RNA_access.h"
102 #include "RNA_define.h"
103 #include "RNA_enum_types.h"
104
105 /* for menu/popup icons etc etc*/
106
107 #include "UI_interface.h"
108 #include "WM_api.h"
109 #include "WM_types.h"
110
111 #include "object_intern.h"  // own include
112
113 /* ************* XXX **************** */
114 static void error(const char *UNUSED(arg)) {}
115 static void waitcursor(int UNUSED(val)) {}
116 static int pupmenu(const char *UNUSED(msg)) { return 0; }
117
118 /* port over here */
119 static void error_libdata(void) {}
120
121 Object *ED_object_context(bContext *C)
122 {
123         return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
124 }
125
126 /* find the correct active object per context
127  * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */
128 Object *ED_object_active_context(bContext *C)
129 {
130         Object *ob = NULL;
131         if (C) {
132                 ob = ED_object_context(C);
133                 if (!ob) ob = CTX_data_active_object(C);
134         }
135         return ob;
136 }
137
138
139 /* ******************* toggle editmode operator  ***************** */
140
141 static bool mesh_needs_keyindex(const Mesh *me)
142 {
143         if (me->key) {
144                 return false;  /* will be added */
145         }
146
147         for (const Object *ob = G.main->object.first; ob; ob = ob->id.next) {
148                 if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
149                         return true;
150                 }
151                 if (ob->data == me) {
152                         for (const ModifierData *md = ob->modifiers.first; md; md = md->next) {
153                                 if (md->type == eModifierType_Hook) {
154                                         return true;
155                                 }
156                         }
157                 }
158         }
159         return false;
160 }
161
162 /**
163  * Load EditMode data back into the object,
164  * optionally freeing the editmode data.
165  */
166 static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool freedata)
167 {
168         if (obedit == NULL) {
169                 return false;
170         }
171
172         if (obedit->type == OB_MESH) {
173                 Mesh *me = obedit->data;
174
175                 if (me->edit_btmesh->bm->totvert > MESH_MAX_VERTS) {
176                         error("Too many vertices");
177                         return false;
178                 }
179
180                 EDBM_mesh_load(obedit);
181
182                 if (freedata) {
183                         EDBM_mesh_free(me->edit_btmesh);
184                         MEM_freeN(me->edit_btmesh);
185                         me->edit_btmesh = NULL;
186                 }
187                 if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
188                         ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
189                         ED_mesh_mirror_topo_table(NULL, NULL, 'e');
190                 }
191         }
192         else if (obedit->type == OB_ARMATURE) {
193                 ED_armature_from_edit(obedit->data);
194                 if (freedata)
195                         ED_armature_edit_free(obedit->data);
196                 /* TODO(sergey): Pose channels might have been changed, so need
197                  * to inform dependency graph about this. But is it really the
198                  * best place to do this?
199                  */
200                 DEG_relations_tag_update(bmain);
201         }
202         else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
203                 ED_curve_editnurb_load(obedit);
204                 if (freedata) ED_curve_editnurb_free(obedit);
205         }
206         else if (obedit->type == OB_FONT) {
207                 ED_curve_editfont_load(obedit);
208                 if (freedata) ED_curve_editfont_free(obedit);
209         }
210         else if (obedit->type == OB_LATTICE) {
211                 ED_lattice_editlatt_load(obedit);
212                 if (freedata) ED_lattice_editlatt_free(obedit);
213         }
214         else if (obedit->type == OB_MBALL) {
215                 ED_mball_editmball_load(obedit);
216                 if (freedata) ED_mball_editmball_free(obedit);
217         }
218
219         /* Tag update so no access to freed data referenced from
220          * derived cache will happen.
221          */
222         DEG_id_tag_update((ID *)obedit->data, 0);
223
224         return true;
225 }
226
227 bool ED_object_editmode_load(Object *obedit)
228 {
229         /* TODO(sergey): use proper main here? */
230         return ED_object_editmode_load_ex(G.main, obedit, false);
231 }
232
233 void ED_object_editmode_exit(bContext *C, int flag)
234 {
235         /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */
236         /* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */
237         Scene *scene = CTX_data_scene(C);
238         ViewLayer *sl = CTX_data_view_layer(C);
239         Object *obedit = CTX_data_edit_object(C);
240         const bool freedata = (flag & EM_FREEDATA) != 0;
241
242         if (flag & EM_WAITCURSOR) waitcursor(1);
243
244         if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) {
245                 /* in rare cases (background mode) its possible active object
246                  * is flagged for editmode, without 'obedit' being set [#35489] */
247                 if (UNLIKELY(sl->basact && (sl->basact->object->mode & OB_MODE_EDIT))) {
248                         sl->basact->object->mode &= ~OB_MODE_EDIT;
249                 }
250                 if (flag & EM_WAITCURSOR) waitcursor(0);
251                 return;
252         }
253
254         /* freedata only 0 now on file saves and render */
255         if (freedata) {
256                 ListBase pidlist;
257                 PTCacheID *pid;
258
259                 /* for example; displist make is different in editmode */
260                 scene->obedit = NULL; // XXX for context
261
262                 /* flag object caches as outdated */
263                 BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
264                 for (pid = pidlist.first; pid; pid = pid->next) {
265                         if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
266                                 pid->cache->flag |= PTCACHE_OUTDATED;
267                 }
268                 BLI_freelistN(&pidlist);
269                 
270                 BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
271
272                 /* also flush ob recalc, doesn't take much overhead, but used for particles */
273                 DEG_id_tag_update(&obedit->id, OB_RECALC_OB | OB_RECALC_DATA);
274         
275                 if (flag & EM_DO_UNDO)
276                         ED_undo_push(C, "Editmode");
277
278                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
279
280                 obedit->mode &= ~OB_MODE_EDIT;
281         }
282
283         if (flag & EM_WAITCURSOR) waitcursor(0);
284
285         /* This way we ensure scene's obedit is copied into all CoW scenes.  */
286         DEG_id_tag_update(&scene->id, 0);
287 }
288
289
290 void ED_object_editmode_enter(bContext *C, int flag)
291 {
292         Scene *scene = CTX_data_scene(C);
293         ViewLayer *sl = CTX_data_view_layer(C);
294         Object *ob;
295         bool ok = false;
296
297         if (ID_IS_LINKED(scene)) return;
298
299         if ((flag & EM_IGNORE_LAYER) == 0) {
300                 ob = CTX_data_active_object(C); /* active layer checked here for view3d */
301
302                 if (ob == NULL) return;
303         }
304         else {
305                 ob = sl->basact->object;
306         }
307
308         if (ELEM(NULL, ob, ob->data)) return;
309
310         /* this checks actual object->data, for cases when other scenes have it in editmode context */
311         if (BKE_object_is_in_editmode(ob))
312                 return;
313         
314         if (BKE_object_obdata_is_libdata(ob)) {
315                 error_libdata();
316                 return;
317         }
318
319         if (flag & EM_WAITCURSOR) waitcursor(1);
320
321         ob->restore_mode = ob->mode;
322
323         /* note, when switching scenes the object can have editmode data but
324          * not be scene->obedit: bug 22954, this avoids calling self eternally */
325         if ((ob->restore_mode & OB_MODE_EDIT) == 0)
326                 ED_object_toggle_modes(C, ob->mode);
327
328         ob->mode = OB_MODE_EDIT;
329
330         if (ob->type == OB_MESH) {
331                 BMEditMesh *em;
332                 ok = 1;
333                 scene->obedit = ob;  /* context sees this */
334
335                 const bool use_key_index = mesh_needs_keyindex(ob->data);
336
337                 EDBM_mesh_make(scene->toolsettings, ob, use_key_index);
338
339                 em = BKE_editmesh_from_object(ob);
340                 if (LIKELY(em)) {
341                         /* order doesn't matter */
342                         EDBM_mesh_normals_update(em);
343                         BKE_editmesh_tessface_calc(em);
344                 }
345
346                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MESH, scene);
347         }
348         else if (ob->type == OB_ARMATURE) {
349                 bArmature *arm = ob->data;
350                 if (!arm) return;
351                 /*
352                  * The function BKE_object_obdata_is_libdata make a problem here, the
353                  * check for ob->proxy return 0 and let blender enter to edit mode
354                  * this causes a crash when you try leave the edit mode.
355                  * The problem is that i can't remove the ob->proxy check from
356                  * BKE_object_obdata_is_libdata that prevent the bugfix #6614, so
357                  * i add this little hack here.
358                  */
359                 if (ID_IS_LINKED(arm)) {
360                         error_libdata();
361                         return;
362                 }
363                 ok = 1;
364                 scene->obedit = ob;
365                 ED_armature_to_edit(arm);
366                 /* to ensure all goes in restposition and without striding */
367                 DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */
368
369                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene);
370         }
371         else if (ob->type == OB_FONT) {
372                 scene->obedit = ob; /* XXX for context */
373                 ok = 1;
374                 ED_curve_editfont_make(ob);
375
376                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
377         }
378         else if (ob->type == OB_MBALL) {
379                 scene->obedit = ob; /* XXX for context */
380                 ok = 1;
381                 ED_mball_editmball_make(ob);
382
383                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
384         }
385         else if (ob->type == OB_LATTICE) {
386                 scene->obedit = ob; /* XXX for context */
387                 ok = 1;
388                 ED_lattice_editlatt_make(ob);
389
390                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene);
391         }
392         else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
393                 ok = 1;
394                 scene->obedit = ob; /* XXX for context */
395                 ED_curve_editnurb_make(ob);
396
397                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
398         }
399
400         if (ok) {
401                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
402                 /* This way we ensure scene's obedit is copied into all CoW scenes.  */
403                 DEG_id_tag_update(&scene->id, 0);
404         }
405         else {
406                 scene->obedit = NULL; /* XXX for context */
407                 ob->mode &= ~OB_MODE_EDIT;
408                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, scene);
409         }
410
411         if (flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode");
412         if (flag & EM_WAITCURSOR) waitcursor(0);
413 }
414
415 static int editmode_toggle_exec(bContext *C, wmOperator *op)
416 {
417         const int mode_flag = OB_MODE_EDIT;
418         const bool is_mode_set = (CTX_data_edit_object(C) != NULL);
419         Scene *scene =  CTX_data_scene(C);
420
421         if (!is_mode_set) {
422                 Object *ob = CTX_data_active_object(C);
423                 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
424                         return OPERATOR_CANCELLED;
425                 }
426         }
427
428         if (!is_mode_set)
429                 ED_object_editmode_enter(C, EM_WAITCURSOR);
430         else
431                 ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR);  /* had EM_DO_UNDO but op flag calls undo too [#24685] */
432         
433         ED_space_image_uv_sculpt_update(CTX_wm_manager(C), scene);
434
435         return OPERATOR_FINISHED;
436 }
437
438 static int editmode_toggle_poll(bContext *C)
439 {
440         Object *ob = CTX_data_active_object(C);
441
442         /* covers proxies too */
443         if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data))
444                 return 0;
445
446         /* if hidden but in edit mode, we still display */
447         if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT))
448                 return 0;
449
450         return OB_TYPE_SUPPORT_EDITMODE(ob->type);
451 }
452
453 void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
454 {
455         
456         /* identifiers */
457         ot->name = "Toggle Editmode";
458         ot->description = "Toggle object's editmode";
459         ot->idname = "OBJECT_OT_editmode_toggle";
460         
461         /* api callbacks */
462         ot->exec = editmode_toggle_exec;
463         ot->poll = editmode_toggle_poll;
464         
465         /* flags */
466         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
467 }
468
469 /* *************************** */
470
471 static int posemode_exec(bContext *C, wmOperator *op)
472 {
473         Base *base = CTX_data_active_base(C);
474         Object *ob = base->object;
475         const int mode_flag = OB_MODE_POSE;
476         const bool is_mode_set = (ob->mode & mode_flag) != 0;
477         
478         if (!is_mode_set) {
479                 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
480                         return OPERATOR_CANCELLED;
481                 }
482         }
483
484         if (ob->type == OB_ARMATURE) {
485                 if (ob == CTX_data_edit_object(C)) {
486                         ED_object_editmode_exit(C, EM_FREEDATA | EM_DO_UNDO);
487                         ED_armature_enter_posemode(C, base);
488                 }
489                 else if (is_mode_set)
490                         ED_armature_exit_posemode(C, base);
491                 else
492                         ED_armature_enter_posemode(C, base);
493                 
494                 return OPERATOR_FINISHED;
495         }
496         
497         return OPERATOR_PASS_THROUGH;
498 }
499
500 void OBJECT_OT_posemode_toggle(wmOperatorType *ot) 
501 {
502         /* identifiers */
503         ot->name = "Toggle Pose Mode";
504         ot->idname = "OBJECT_OT_posemode_toggle";
505         ot->description = "Enable or disable posing/selecting bones";
506         
507         /* api callbacks */
508         ot->exec = posemode_exec;
509         ot->poll = ED_operator_object_active_editable;
510         
511         /* flag */
512         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
513 }
514
515 static void copymenu_properties(ViewLayer *sl, Object *ob)
516 {       
517 //XXX no longer used - to be removed - replaced by game_properties_copy_exec
518         bProperty *prop;
519         Base *base;
520         int nr, tot = 0;
521         char *str;
522         
523         prop = ob->prop.first;
524         while (prop) {
525                 tot++;
526                 prop = prop->next;
527         }
528         
529         str = MEM_callocN(50 + 33 * tot, "copymenu prop");
530         
531         if (tot)
532                 strcpy(str, "Copy Property %t|Replace All|Merge All|%l");
533         else
534                 strcpy(str, "Copy Property %t|Clear All (no properties on active)");
535         
536         tot = 0;
537         prop = ob->prop.first;
538         while (prop) {
539                 tot++;
540                 strcat(str, "|");
541                 strcat(str, prop->name);
542                 prop = prop->next;
543         }
544
545         nr = pupmenu(str);
546         
547         if (nr == 1 || nr == 2) {
548                 for (base = FIRSTBASE(sl); base; base = base->next) {
549                         if ((base != BASACT(sl)) && (TESTBASELIB(base))) {
550                                 if (nr == 1) { /* replace */
551                                         BKE_bproperty_copy_list(&base->object->prop, &ob->prop);
552                                 }
553                                 else {
554                                         for (prop = ob->prop.first; prop; prop = prop->next) {
555                                                 BKE_bproperty_object_set(base->object, prop);
556                                         }
557                                 }
558                         }
559                 }
560         }
561         else if (nr > 0) {
562                 prop = BLI_findlink(&ob->prop, nr - 4); /* account for first 3 menu items & menu index starting at 1*/
563                 
564                 if (prop) {
565                         for (base = FIRSTBASE(sl); base; base = base->next) {
566                                 if ((base != BASACT(sl)) && (TESTBASELIB(base))) {
567                                         BKE_bproperty_object_set(base->object, prop);
568                                 }
569                         }
570                 }
571         }
572         MEM_freeN(str);
573         
574 }
575
576 static void copymenu_logicbricks(ViewLayer *sl, Object *ob)
577 {
578 //XXX no longer used - to be removed - replaced by logicbricks_copy_exec
579         Base *base;
580         
581         for (base = FIRSTBASE(sl); base; base = base->next) {
582                 if (base->object != ob) {
583                         if (TESTBASELIB(base)) {
584                                 
585                                 /* first: free all logic */
586                                 free_sensors(&base->object->sensors);
587                                 unlink_controllers(&base->object->controllers);
588                                 free_controllers(&base->object->controllers);
589                                 unlink_actuators(&base->object->actuators);
590                                 free_actuators(&base->object->actuators);
591                                 
592                                 /* now copy it, this also works without logicbricks! */
593                                 clear_sca_new_poins_ob(ob);
594                                 copy_sensors(&base->object->sensors, &ob->sensors, 0);
595                                 copy_controllers(&base->object->controllers, &ob->controllers, 0);
596                                 copy_actuators(&base->object->actuators, &ob->actuators, 0);
597                                 set_sca_new_poins_ob(base->object);
598                                 
599                                 /* some menu settings */
600                                 base->object->scavisflag = ob->scavisflag;
601                                 base->object->scaflag = ob->scaflag;
602                                 
603                                 /* set the initial state */
604                                 base->object->state = ob->state;
605                                 base->object->init_state = ob->init_state;
606                         }
607                 }
608         }
609 }
610
611 /* both pointers should exist */
612 static void copy_texture_space(Object *to, Object *ob)
613 {
614         float *poin1 = NULL, *poin2 = NULL;
615         short texflag = 0;
616         
617         if (ob->type == OB_MESH) {
618                 texflag = ((Mesh *)ob->data)->texflag;
619                 poin2 = ((Mesh *)ob->data)->loc;
620         }
621         else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
622                 texflag = ((Curve *)ob->data)->texflag;
623                 poin2 = ((Curve *)ob->data)->loc;
624         }
625         else if (ob->type == OB_MBALL) {
626                 texflag = ((MetaBall *)ob->data)->texflag;
627                 poin2 = ((MetaBall *)ob->data)->loc;
628         }
629         else
630                 return;
631                 
632         if (to->type == OB_MESH) {
633                 ((Mesh *)to->data)->texflag = texflag;
634                 poin1 = ((Mesh *)to->data)->loc;
635         }
636         else if (ELEM(to->type, OB_CURVE, OB_SURF, OB_FONT)) {
637                 ((Curve *)to->data)->texflag = texflag;
638                 poin1 = ((Curve *)to->data)->loc;
639         }
640         else if (to->type == OB_MBALL) {
641                 ((MetaBall *)to->data)->texflag = texflag;
642                 poin1 = ((MetaBall *)to->data)->loc;
643         }
644         else
645                 return;
646         
647         memcpy(poin1, poin2, 9 * sizeof(float));  /* this was noted in DNA_mesh, curve, mball */
648         
649         if (to->type == OB_MESH) {
650                 /* pass */
651         }
652         else if (to->type == OB_MBALL) {
653                 BKE_mball_texspace_calc(to);
654         }
655         else {
656                 BKE_curve_texspace_calc(to->data);
657         }
658         
659 }
660
661 /* UNUSED, keep in case we want to copy functionality for use elsewhere */
662 static void copy_attr(Main *bmain, Scene *scene, ViewLayer *sl, short event)
663 {
664         Object *ob;
665         Base *base;
666         Curve *cu, *cu1;
667         Nurb *nu;
668         bool do_depgraph_update = false;
669         
670         if (ID_IS_LINKED(scene)) return;
671
672         if (!(ob = OBACT(sl))) return;
673         
674         if (scene->obedit) { // XXX get from context
675                 /* obedit_copymenu(); */
676                 return;
677         }
678         if (event == 9) {
679                 copymenu_properties(sl, ob);
680                 return;
681         }
682         else if (event == 10) {
683                 copymenu_logicbricks(sl, ob);
684                 return;
685         }
686         else if (event == 24) {
687                 /* moved to BKE_object_link_modifiers */
688                 /* copymenu_modifiers(bmain, scene, v3d, ob); */
689                 return;
690         }
691
692         for (base = FIRSTBASE(sl); base; base = base->next) {
693                 if (base != BASACT(sl)) {
694                         if (TESTBASELIB(base)) {
695                                 DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
696                                 
697                                 if (event == 1) {  /* loc */
698                                         copy_v3_v3(base->object->loc, ob->loc);
699                                         copy_v3_v3(base->object->dloc, ob->dloc);
700                                 }
701                                 else if (event == 2) {  /* rot */
702                                         copy_v3_v3(base->object->rot, ob->rot);
703                                         copy_v3_v3(base->object->drot, ob->drot);
704
705                                         copy_qt_qt(base->object->quat, ob->quat);
706                                         copy_qt_qt(base->object->dquat, ob->dquat);
707                                 }
708                                 else if (event == 3) {  /* size */
709                                         copy_v3_v3(base->object->size, ob->size);
710                                         copy_v3_v3(base->object->dscale, ob->dscale);
711                                 }
712                                 else if (event == 4) {  /* drawtype */
713                                         base->object->dt = ob->dt;
714                                         base->object->dtx = ob->dtx;
715                                         base->object->empty_drawtype = ob->empty_drawtype;
716                                         base->object->empty_drawsize = ob->empty_drawsize;
717                                 }
718                                 else if (event == 5) {  /* time offs */
719                                         base->object->sf = ob->sf;
720                                 }
721                                 else if (event == 6) {  /* dupli */
722                                         base->object->dupon = ob->dupon;
723                                         base->object->dupoff = ob->dupoff;
724                                         base->object->dupsta = ob->dupsta;
725                                         base->object->dupend = ob->dupend;
726                                         
727                                         base->object->transflag &= ~OB_DUPLI;
728                                         base->object->transflag |= (ob->transflag & OB_DUPLI);
729
730                                         base->object->dup_group = ob->dup_group;
731                                         if (ob->dup_group)
732                                                 id_us_plus(&ob->dup_group->id);
733                                 }
734                                 else if (event == 7) {    /* mass */
735                                         base->object->mass = ob->mass;
736                                 }
737                                 else if (event == 8) {    /* damping */
738                                         base->object->damping = ob->damping;
739                                         base->object->rdamping = ob->rdamping;
740                                 }
741                                 else if (event == 11) {   /* all physical attributes */
742                                         base->object->gameflag = ob->gameflag;
743                                         base->object->inertia = ob->inertia;
744                                         base->object->formfactor = ob->formfactor;
745                                         base->object->damping = ob->damping;
746                                         base->object->rdamping = ob->rdamping;
747                                         base->object->min_vel = ob->min_vel;
748                                         base->object->max_vel = ob->max_vel;
749                                         base->object->min_angvel = ob->min_angvel;
750                                         base->object->max_angvel = ob->max_angvel;
751                                         if (ob->gameflag & OB_BOUNDS) {
752                                                 base->object->collision_boundtype = ob->collision_boundtype;
753                                         }
754                                         base->object->margin = ob->margin;
755                                         base->object->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
756
757                                 }
758                                 else if (event == 17) {   /* tex space */
759                                         copy_texture_space(base->object, ob);
760                                 }
761                                 else if (event == 18) {   /* font settings */
762                                         
763                                         if (base->object->type == ob->type) {
764                                                 cu = ob->data;
765                                                 cu1 = base->object->data;
766
767                                                 cu1->spacemode = cu->spacemode;
768                                                 cu1->align_y = cu->align_y;
769                                                 cu1->spacing = cu->spacing;
770                                                 cu1->linedist = cu->linedist;
771                                                 cu1->shear = cu->shear;
772                                                 cu1->fsize = cu->fsize;
773                                                 cu1->xof = cu->xof;
774                                                 cu1->yof = cu->yof;
775                                                 cu1->textoncurve = cu->textoncurve;
776                                                 cu1->wordspace = cu->wordspace;
777                                                 cu1->ulpos = cu->ulpos;
778                                                 cu1->ulheight = cu->ulheight;
779                                                 if (cu1->vfont)
780                                                         id_us_min(&cu1->vfont->id);
781                                                 cu1->vfont = cu->vfont;
782                                                 id_us_plus((ID *)cu1->vfont);
783                                                 if (cu1->vfontb)
784                                                         id_us_min(&cu1->vfontb->id);
785                                                 cu1->vfontb = cu->vfontb;
786                                                 id_us_plus((ID *)cu1->vfontb);
787                                                 if (cu1->vfonti)
788                                                         id_us_min(&cu1->vfonti->id);
789                                                 cu1->vfonti = cu->vfonti;
790                                                 id_us_plus((ID *)cu1->vfonti);
791                                                 if (cu1->vfontbi)
792                                                         id_us_min(&cu1->vfontbi->id);
793                                                 cu1->vfontbi = cu->vfontbi;
794                                                 id_us_plus((ID *)cu1->vfontbi);
795                                                 
796                                                 BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family));
797                                                 
798                                                 DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
799                                         }
800                                 }
801                                 else if (event == 19) {   /* bevel settings */
802                                         
803                                         if (ELEM(base->object->type, OB_CURVE, OB_FONT)) {
804                                                 cu = ob->data;
805                                                 cu1 = base->object->data;
806                                                 
807                                                 cu1->bevobj = cu->bevobj;
808                                                 cu1->taperobj = cu->taperobj;
809                                                 cu1->width = cu->width;
810                                                 cu1->bevresol = cu->bevresol;
811                                                 cu1->ext1 = cu->ext1;
812                                                 cu1->ext2 = cu->ext2;
813                                                 
814                                                 DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
815                                         }
816                                 }
817                                 else if (event == 25) {   /* curve resolution */
818
819                                         if (ELEM(base->object->type, OB_CURVE, OB_FONT)) {
820                                                 cu = ob->data;
821                                                 cu1 = base->object->data;
822                                                 
823                                                 cu1->resolu = cu->resolu;
824                                                 cu1->resolu_ren = cu->resolu_ren;
825                                                 
826                                                 nu = cu1->nurb.first;
827                                                 
828                                                 while (nu) {
829                                                         nu->resolu = cu1->resolu;
830                                                         nu = nu->next;
831                                                 }
832                                                 
833                                                 DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
834                                         }
835                                 }
836                                 else if (event == 21) {
837                                         if (base->object->type == OB_MESH) {
838                                                 ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf);
839
840                                                 if (md) {
841                                                         ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf);
842
843                                                         if (!tmd) {
844                                                                 tmd = modifier_new(eModifierType_Subsurf);
845                                                                 BLI_addtail(&base->object->modifiers, tmd);
846                                                         }
847
848                                                         modifier_copyData(md, tmd);
849                                                         DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
850                                                 }
851                                         }
852                                 }
853                                 else if (event == 22) {
854                                         /* Copy the constraint channels over */
855                                         BKE_constraints_copy(&base->object->constraints, &ob->constraints, true);
856                                         
857                                         do_depgraph_update = true;
858                                 }
859                                 else if (event == 23) {
860                                         base->object->softflag = ob->softflag;
861                                         if (base->object->soft) sbFree(base->object->soft);
862                                         
863                                         base->object->soft = copy_softbody(ob->soft, 0);
864
865                                         if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
866                                                 BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
867                                         }
868                                 }
869                                 else if (event == 26) {
870 #if 0 // XXX old animation system
871                                         copy_nlastrips(&base->object->nlastrips, &ob->nlastrips);
872 #endif // XXX old animation system
873                                 }
874                                 else if (event == 27) {   /* autosmooth */
875                                         if (base->object->type == OB_MESH) {
876                                                 Mesh *me = ob->data;
877                                                 Mesh *cme = base->object->data;
878                                                 cme->smoothresh = me->smoothresh;
879                                                 if (me->flag & ME_AUTOSMOOTH)
880                                                         cme->flag |= ME_AUTOSMOOTH;
881                                                 else
882                                                         cme->flag &= ~ME_AUTOSMOOTH;
883                                         }
884                                 }
885                                 else if (event == 28) { /* UV orco */
886                                         if (ELEM(base->object->type, OB_CURVE, OB_SURF)) {
887                                                 cu = ob->data;
888                                                 cu1 = base->object->data;
889                                                 
890                                                 if (cu->flag & CU_UV_ORCO)
891                                                         cu1->flag |= CU_UV_ORCO;
892                                                 else
893                                                         cu1->flag &= ~CU_UV_ORCO;
894                                         }
895                                 }
896                                 else if (event == 29) { /* protected bits */
897                                         base->object->protectflag = ob->protectflag;
898                                 }
899                                 else if (event == 30) { /* index object */
900                                         base->object->index = ob->index;
901                                 }
902                                 else if (event == 31) { /* object color */
903                                         copy_v4_v4(base->object->col, ob->col);
904                                 }
905                         }
906                 }
907         }
908         
909         if (do_depgraph_update)
910                 DEG_relations_tag_update(bmain);
911 }
912
913 static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *sl)
914 {
915         Object *ob;
916         short event;
917         char str[512];
918         
919         if (!(ob = OBACT(sl))) return;
920         
921         if (scene->obedit) { /* XXX get from context */
922 /*              if (ob->type == OB_MESH) */
923 /* XXX                  mesh_copy_menu(); */
924                 return;
925         }
926         
927         /* Object Mode */
928         
929         /* If you change this menu, don't forget to update the menu in header_view3d.c
930          * view3d_edit_object_copyattrmenu() and in toolbox.c
931          */
932         
933         strcpy(str,
934                "Copy Attributes %t|Location %x1|Rotation %x2|Size %x3|Draw Options %x4|"
935                "Time Offset %x5|Dupli %x6|Object Color %x31|%l|Mass %x7|Damping %x8|All Physical Attributes %x11|Properties %x9|"
936                "Logic Bricks %x10|Protected Transform %x29|%l");
937         
938         strcat(str, "|Object Constraints %x22");
939         strcat(str, "|NLA Strips %x26");
940         
941 /* XXX  if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { */
942 /*              strcat(str, "|Texture Space %x17"); */
943 /*      } */
944         
945         if (ob->type == OB_FONT) strcat(str, "|Font Settings %x18|Bevel Settings %x19");
946         if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings %x19|UV Orco %x28");
947         
948         if ((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
949                 strcat(str, "|Curve Resolution %x25");
950         }
951
952         if (ob->type == OB_MESH) {
953                 strcat(str, "|Subsurf Settings %x21|AutoSmooth %x27");
954         }
955
956         if (ob->soft) strcat(str, "|Soft Body Settings %x23");
957         
958         strcat(str, "|Pass Index %x30");
959         
960         if (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_LATTICE || ob->type == OB_SURF) {
961                 strcat(str, "|Modifiers ... %x24");
962         }
963
964         event = pupmenu(str);
965         if (event <= 0) return;
966         
967         copy_attr(bmain, scene, sl, event);
968 }
969
970 /* ******************* force field toggle operator ***************** */
971
972 void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
973 {
974         PartDeflect *pd = object->pd;
975         ModifierData *md = modifiers_findByType(object, eModifierType_Surface);
976
977         /* add/remove modifier as needed */
978         if (!md) {
979                 if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && !ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
980                         if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
981                                 ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface);
982                         }
983                 }
984         }
985         else {
986                 if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) || ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
987                         ED_object_modifier_remove(NULL, bmain, object, md);
988                 }
989         }
990 }
991
992 static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
993 {
994         Object *ob = CTX_data_active_object(C);
995
996         if (ob->pd == NULL)
997                 ob->pd = object_add_collision_fields(PFIELD_FORCE);
998         else if (ob->pd->forcefield == 0)
999                 ob->pd->forcefield = PFIELD_FORCE;
1000         else
1001                 ob->pd->forcefield = 0;
1002         
1003         ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob);
1004         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1005         WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1006
1007         return OPERATOR_FINISHED;
1008 }
1009
1010 void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
1011 {
1012         
1013         /* identifiers */
1014         ot->name = "Toggle Force Field";
1015         ot->description = "Toggle object's force field";
1016         ot->idname = "OBJECT_OT_forcefield_toggle";
1017         
1018         /* api callbacks */
1019         ot->exec = forcefield_toggle_exec;
1020         ot->poll = ED_operator_object_active_editable;
1021         
1022         /* flags */
1023         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1024 }
1025
1026 /* ********************************************** */
1027 /* Motion Paths */
1028
1029 /* For the objects with animation: update paths for those that have got them
1030  * This should selectively update paths that exist...
1031  *
1032  * To be called from various tools that do incremental updates 
1033  */
1034 void ED_objects_recalculate_paths(bContext *C, Scene *scene)
1035 {
1036         struct Main *bmain = CTX_data_main(C);
1037         EvaluationContext eval_ctx;
1038         CTX_data_eval_ctx(C, &eval_ctx);
1039         ListBase targets = {NULL, NULL};
1040         
1041         /* loop over objects in scene */
1042         CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
1043         {
1044                 /* set flag to force recalc, then grab path(s) from object */
1045                 ob->avs.recalc |= ANIMVIZ_RECALC_PATHS;
1046                 animviz_get_object_motionpaths(ob, &targets);
1047         }
1048         CTX_DATA_END;
1049         
1050         /* recalculate paths, then free */
1051         animviz_calc_motionpaths(&eval_ctx, bmain, scene, &targets);
1052         BLI_freelistN(&targets);
1053 }
1054
1055
1056 /* show popup to determine settings */
1057 static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1058 {
1059         Object *ob = CTX_data_active_object(C);
1060         
1061         if (ob == NULL)
1062                 return OPERATOR_CANCELLED;
1063         
1064         /* set default settings from existing/stored settings */
1065         {
1066                 bAnimVizSettings *avs = &ob->avs;
1067                 
1068                 RNA_int_set(op->ptr, "start_frame", avs->path_sf);
1069                 RNA_int_set(op->ptr, "end_frame", avs->path_ef);
1070         }
1071         
1072         /* show popup dialog to allow editing of range... */
1073         /* FIXME: hardcoded dimensions here are just arbitrary */
1074         return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
1075 }
1076
1077 /* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
1078 static int object_calculate_paths_exec(bContext *C, wmOperator *op)
1079 {
1080         Scene *scene = CTX_data_scene(C);
1081         int start = RNA_int_get(op->ptr, "start_frame");
1082         int end = RNA_int_get(op->ptr, "end_frame");
1083         
1084         /* set up path data for bones being calculated */
1085         CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
1086         {
1087                 bAnimVizSettings *avs = &ob->avs;
1088                 
1089                 /* grab baking settings from operator settings */
1090                 avs->path_sf = start;
1091                 avs->path_ef = end;
1092                 
1093                 /* verify that the selected object has the appropriate settings */
1094                 animviz_verify_motionpaths(op->reports, scene, ob, NULL);
1095         }
1096         CTX_DATA_END;
1097         
1098         /* calculate the paths for objects that have them (and are tagged to get refreshed) */
1099         ED_objects_recalculate_paths(C, scene);
1100         
1101         /* notifiers for updates */
1102         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1103         
1104         return OPERATOR_FINISHED; 
1105 }
1106
1107 void OBJECT_OT_paths_calculate(wmOperatorType *ot)
1108 {
1109         /* identifiers */
1110         ot->name = "Calculate Object Paths";
1111         ot->idname = "OBJECT_OT_paths_calculate";
1112         ot->description = "Calculate motion paths for the selected objects";
1113         
1114         /* api callbacks */
1115         ot->invoke = object_calculate_paths_invoke;
1116         ot->exec = object_calculate_paths_exec;
1117         ot->poll = ED_operator_object_active_editable;
1118         
1119         /* flags */
1120         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1121         
1122         /* properties */
1123         RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", 
1124                     "First frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0);
1125         RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", 
1126                     "Last frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0);
1127 }
1128
1129 /* --------- */
1130
1131 static int object_update_paths_poll(bContext *C)
1132 {
1133         if (ED_operator_object_active_editable(C)) {
1134                 Object *ob = ED_object_active_context(C);
1135                 return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
1136         }
1137         
1138         return false;
1139 }
1140
1141 static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
1142 {
1143         Scene *scene = CTX_data_scene(C);
1144         
1145         if (scene == NULL)
1146                 return OPERATOR_CANCELLED;
1147                 
1148         /* calculate the paths for objects that have them (and are tagged to get refreshed) */
1149         ED_objects_recalculate_paths(C, scene);
1150         
1151         /* notifiers for updates */
1152         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1153         
1154         return OPERATOR_FINISHED;
1155 }
1156
1157 void OBJECT_OT_paths_update(wmOperatorType *ot)
1158 {
1159         /* identifiers */
1160         ot->name = "Update Object Paths";
1161         ot->idname = "OBJECT_OT_paths_update";
1162         ot->description = "Recalculate paths for selected objects";
1163         
1164         /* api callbakcs */
1165         ot->exec = object_update_paths_exec;
1166         ot->poll = object_update_paths_poll;
1167         
1168         /* flags */
1169         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1170 }
1171
1172 /* --------- */
1173
1174 /* Helper for ED_objects_clear_paths() */
1175 static void object_clear_mpath(Object *ob)
1176 {
1177         if (ob->mpath) {
1178                 animviz_free_motionpath(ob->mpath);
1179                 ob->mpath = NULL;
1180                 ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
1181         }
1182 }
1183
1184 /* Clear motion paths for all objects */
1185 void ED_objects_clear_paths(bContext *C, bool only_selected)
1186 {
1187         if (only_selected) {
1188                 /* loop over all selected + sedtiable objects in scene */
1189                 CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
1190                 {
1191                         object_clear_mpath(ob);
1192                 }
1193                 CTX_DATA_END;
1194         }
1195         else {
1196                 /* loop over all edtiable objects in scene */
1197                 CTX_DATA_BEGIN(C, Object *, ob, editable_objects)
1198                 {
1199                         object_clear_mpath(ob);
1200                 }
1201                 CTX_DATA_END;
1202         }
1203 }
1204
1205 /* operator callback for this */
1206 static int object_clear_paths_exec(bContext *C, wmOperator *op)
1207 {
1208         bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
1209         
1210         /* use the backend function for this */
1211         ED_objects_clear_paths(C, only_selected);
1212         
1213         /* notifiers for updates */
1214         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1215         
1216         return OPERATOR_FINISHED; 
1217 }
1218
1219 /* operator callback/wrapper */
1220 static int object_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
1221 {
1222         if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
1223                 RNA_boolean_set(op->ptr, "only_selected", true);
1224         }
1225         return object_clear_paths_exec(C, op);
1226 }
1227
1228 void OBJECT_OT_paths_clear(wmOperatorType *ot)
1229 {
1230         /* identifiers */
1231         ot->name = "Clear Object Paths";
1232         ot->idname = "OBJECT_OT_paths_clear";
1233         ot->description = "Clear path caches for all objects, hold Shift key for selected objects only";
1234         
1235         /* api callbacks */
1236         ot->invoke = object_clear_paths_invoke;
1237         ot->exec = object_clear_paths_exec;
1238         ot->poll = ED_operator_object_active_editable;
1239         
1240         /* flags */
1241         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1242         
1243         /* properties */
1244         ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected",
1245                                    "Only clear paths from selected objects");
1246         RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
1247 }
1248
1249
1250 /********************** Smooth/Flat *********************/
1251
1252 static int shade_smooth_exec(bContext *C, wmOperator *op)
1253 {
1254         ID *data;
1255         Curve *cu;
1256         Nurb *nu;
1257         int clear = (STREQ(op->idname, "OBJECT_OT_shade_flat"));
1258         bool done = false, linked_data = false;
1259
1260         CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
1261         {
1262                 data = ob->data;
1263
1264                 if (data && ID_IS_LINKED(data)) {
1265                         linked_data = true;
1266                         continue;
1267                 }
1268
1269                 if (ob->type == OB_MESH) {
1270                         BKE_mesh_smooth_flag_set(ob, !clear);
1271
1272                         BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
1273                         DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
1274                         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1275
1276                         done = true;
1277                 }
1278                 else if (ELEM(ob->type, OB_SURF, OB_CURVE)) {
1279                         cu = ob->data;
1280
1281                         for (nu = cu->nurb.first; nu; nu = nu->next) {
1282                                 if (!clear) nu->flag |= ME_SMOOTH;
1283                                 else nu->flag &= ~ME_SMOOTH;
1284                         }
1285
1286                         DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
1287                         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1288
1289                         done = true;
1290                 }
1291         }
1292         CTX_DATA_END;
1293
1294         if (linked_data)
1295                 BKE_report(op->reports, RPT_WARNING, "Can't edit linked mesh or curve data");
1296
1297         return (done) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1298 }
1299
1300 static int shade_poll(bContext *C)
1301 {
1302         return (CTX_data_edit_object(C) == NULL);
1303 }
1304
1305 void OBJECT_OT_shade_flat(wmOperatorType *ot)
1306 {
1307         /* identifiers */
1308         ot->name = "Shade Flat";
1309         ot->description = "Render and display faces uniform, using Face Normals";
1310         ot->idname = "OBJECT_OT_shade_flat";
1311         
1312         /* api callbacks */
1313         ot->poll = shade_poll;
1314         ot->exec = shade_smooth_exec;
1315
1316         /* flags */
1317         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1318 }
1319
1320 void OBJECT_OT_shade_smooth(wmOperatorType *ot)
1321 {
1322         /* identifiers */
1323         ot->name = "Shade Smooth";
1324         ot->description = "Render and display faces smooth, using interpolated Vertex Normals";
1325         ot->idname = "OBJECT_OT_shade_smooth";
1326         
1327         /* api callbacks */
1328         ot->poll = shade_poll;
1329         ot->exec = shade_smooth_exec;
1330         
1331         /* flags */
1332         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1333 }
1334
1335 /* ********************** */
1336
1337 static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *sl)
1338 {
1339         /* all selected objects with an image map: scale in image aspect */
1340         Base *base;
1341         Object *ob;
1342         Material *ma;
1343         Tex *tex;
1344         float x, y, space;
1345         int a, b, done;
1346         
1347         if (scene->obedit) return;  // XXX get from context
1348         if (ID_IS_LINKED(scene)) return;
1349         
1350         for (base = FIRSTBASE(sl); base; base = base->next) {
1351                 if (TESTBASELIB(base)) {
1352                         ob = base->object;
1353                         done = false;
1354                         
1355                         for (a = 1; a <= ob->totcol; a++) {
1356                                 ma = give_current_material(ob, a);
1357                                 if (ma) {
1358                                         for (b = 0; b < MAX_MTEX; b++) {
1359                                                 if (ma->mtex[b] && ma->mtex[b]->tex) {
1360                                                         tex = ma->mtex[b]->tex;
1361                                                         if (tex->type == TEX_IMAGE && tex->ima) {
1362                                                                 ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL);
1363                                                                 
1364                                                                 /* texturespace */
1365                                                                 space = 1.0;
1366                                                                 if (ob->type == OB_MESH) {
1367                                                                         float size[3];
1368                                                                         BKE_mesh_texspace_get(ob->data, NULL, NULL, size);
1369                                                                         space = size[0] / size[1];
1370                                                                 }
1371                                                                 else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
1372                                                                         float size[3];
1373                                                                         BKE_curve_texspace_get(ob->data, NULL, NULL, size);
1374                                                                         space = size[0] / size[1];
1375                                                                 }
1376                                                         
1377                                                                 x = ibuf->x / space;
1378                                                                 y = ibuf->y;
1379                                                                 
1380                                                                 if (x > y) ob->size[0] = ob->size[1] * x / y;
1381                                                                 else ob->size[1] = ob->size[0] * y / x;
1382                                                                 
1383                                                                 done = true;
1384                                                                 DEG_id_tag_update(&ob->id, OB_RECALC_OB);
1385
1386                                                                 BKE_image_release_ibuf(tex->ima, ibuf, NULL);
1387                                                         }
1388                                                 }
1389                                                 if (done) break;
1390                                         }
1391                                 }
1392                                 if (done) break;
1393                         }
1394                 }
1395         }
1396         
1397 }
1398
1399 static const EnumPropertyItem *object_mode_set_itemsf(
1400         bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
1401 {
1402         const EnumPropertyItem *input = rna_enum_object_mode_items;
1403         EnumPropertyItem *item = NULL;
1404         Object *ob;
1405         bGPdata *gpd;
1406         int totitem = 0;
1407
1408         if (!C) /* needed for docs */
1409                 return rna_enum_object_mode_items;
1410
1411         ob = CTX_data_active_object(C);
1412         if (ob) {
1413                 const bool use_mode_particle_edit = (BLI_listbase_is_empty(&ob->particlesystem) == false) ||
1414                                                     (ob->soft != NULL) ||
1415                                                     (modifiers_findByType(ob, eModifierType_Cloth) != NULL);
1416                 while (input->identifier) {
1417                         if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) ||
1418                             (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
1419                             (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) ||
1420                             (ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT,
1421                                    OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
1422                             (input->value == OB_MODE_OBJECT))
1423                         {
1424                                 RNA_enum_item_add(&item, &totitem, input);
1425                         }
1426                         input++;
1427                 }
1428         }
1429         else {
1430                 /* We need at least this one! */
1431                 RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT);
1432         }
1433         
1434         /* On top of all the rest, GPencil Stroke Edit Mode
1435          * is available if there's a valid gp datablock...
1436          */
1437         gpd = CTX_data_gpencil_data(C);
1438         if (gpd) {
1439                 RNA_enum_items_add_value(&item, &totitem, rna_enum_object_mode_items, OB_MODE_GPENCIL);
1440         }
1441
1442         RNA_enum_item_end(&item, &totitem);
1443
1444         *r_free = true;
1445
1446         return item;
1447 }
1448
1449 static const char *object_mode_op_string(int mode)
1450 {
1451         if (mode & OB_MODE_EDIT)
1452                 return "OBJECT_OT_editmode_toggle";
1453         if (mode == OB_MODE_SCULPT)
1454                 return "SCULPT_OT_sculptmode_toggle";
1455         if (mode == OB_MODE_VERTEX_PAINT)
1456                 return "PAINT_OT_vertex_paint_toggle";
1457         if (mode == OB_MODE_WEIGHT_PAINT)
1458                 return "PAINT_OT_weight_paint_toggle";
1459         if (mode == OB_MODE_TEXTURE_PAINT)
1460                 return "PAINT_OT_texture_paint_toggle";
1461         if (mode == OB_MODE_PARTICLE_EDIT)
1462                 return "PARTICLE_OT_particle_edit_toggle";
1463         if (mode == OB_MODE_POSE)
1464                 return "OBJECT_OT_posemode_toggle";
1465         if (mode == OB_MODE_GPENCIL)
1466                 return "GPENCIL_OT_editmode_toggle";
1467         return NULL;
1468 }
1469
1470 /* checks the mode to be set is compatible with the object
1471  * should be made into a generic function
1472  */
1473 static bool object_mode_compat_test(Object *ob, eObjectMode mode)
1474 {
1475         if (ob) {
1476                 if (mode == OB_MODE_OBJECT)
1477                         return true;
1478                 else if (mode == OB_MODE_GPENCIL)
1479                         return true; /* XXX: assume this is the case for now... */
1480
1481                 switch (ob->type) {
1482                         case OB_MESH:
1483                                 if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT |
1484                                             OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT))
1485                                 {
1486                                         return true;
1487                                 }
1488                                 break;
1489                         case OB_CURVE:
1490                         case OB_SURF:
1491                         case OB_FONT:
1492                         case OB_MBALL:
1493                                 if (mode & (OB_MODE_EDIT))
1494                                         return true;
1495                                 break;
1496                         case OB_LATTICE:
1497                                 if (mode & (OB_MODE_EDIT | OB_MODE_WEIGHT_PAINT))
1498                                         return true;
1499                                 break;
1500                         case OB_ARMATURE:
1501                                 if (mode & (OB_MODE_EDIT | OB_MODE_POSE))
1502                                         return true;
1503                                 break;
1504                 }
1505         }
1506
1507         return false;
1508 }
1509
1510 /**
1511  * Sets the mode to a compatible state (use before entering the mode).
1512  *
1513  * This is so each mode's exec function can call
1514  */
1515 bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *reports)
1516 {
1517         bool ok;
1518         if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
1519                 WorkSpace *workspace = CTX_wm_workspace(C);
1520                 const char *opstring = object_mode_op_string(ob->mode);
1521
1522                 WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
1523 #ifdef USE_WORKSPACE_MODE
1524                 BKE_workspace_object_mode_set(workspace, ob->mode);
1525 #else
1526                 UNUSED_VARS(workspace);
1527 #endif
1528                 ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
1529                 if (!ok) {
1530                         wmOperatorType *ot = WM_operatortype_find(opstring, false);
1531                         BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name);
1532                 }
1533         }
1534         else {
1535                 ok = true;
1536         }
1537
1538         return ok;
1539 }
1540
1541 static int object_mode_set_poll(bContext *C)
1542 {
1543         /* Since Grease Pencil editmode is also handled here,
1544          * we have a special exception for allowing this operator
1545          * to still work in that case when there's no active object
1546          * so that users can exit editmode this way as per normal.
1547          */
1548         if (ED_operator_object_active_editable(C))
1549                 return true;
1550         else
1551                 return (CTX_data_gpencil_data(C) != NULL);
1552 }
1553
1554 static int object_mode_set_exec(bContext *C, wmOperator *op)
1555 {
1556         Object *ob = CTX_data_active_object(C);
1557         bGPdata *gpd = CTX_data_gpencil_data(C);
1558         eObjectMode mode = RNA_enum_get(op->ptr, "mode");
1559         eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT;
1560         const bool toggle = RNA_boolean_get(op->ptr, "toggle");
1561         
1562         if (gpd) {
1563                 /* GP Mode is not bound to a specific object. Therefore,
1564                  * we don't want it to be actually saved on any objects,
1565                  * as weirdness can happen if you select other objects,
1566                  * or load old files.
1567                  *
1568                  * Instead, we use the following 2 rules to ensure that
1569                  * the mode selector works as expected:
1570                  *  1) If there's no object, we want to enter editmode.
1571                  *     (i.e. with no object, we're in object mode)
1572                  *  2) Otherwise, exit stroke editmode, so that we can
1573                  *     enter another mode...
1574                  */
1575                 if (!ob || (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
1576                         WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL);
1577                 }
1578         }
1579         
1580         if (!ob || !object_mode_compat_test(ob, mode))
1581                 return OPERATOR_PASS_THROUGH;
1582
1583         if (ob->mode != mode) {
1584                 /* we should be able to remove this call, each operator calls  */
1585                 ED_object_mode_compat_set(C, ob, mode, op->reports);
1586         }
1587
1588         /* Exit current mode if it's not the mode we're setting */
1589         if (mode != OB_MODE_OBJECT && (ob->mode != mode || toggle)) {
1590                 /* Enter new mode */
1591                 ED_object_toggle_modes(C, mode);
1592         }
1593
1594         if (toggle) {
1595                 /* Special case for Object mode! */
1596                 if (mode == OB_MODE_OBJECT && restore_mode == OB_MODE_OBJECT && ob->restore_mode != OB_MODE_OBJECT) {
1597                         ED_object_toggle_modes(C, ob->restore_mode);
1598                 }
1599                 else if (ob->mode == mode) {
1600                         /* For toggling, store old mode so we know what to go back to */
1601                         ob->restore_mode = restore_mode;
1602                 }
1603                 else if (ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) {
1604                         ED_object_toggle_modes(C, ob->restore_mode);
1605                 }
1606         }
1607
1608         return OPERATOR_FINISHED;
1609 }
1610
1611 void OBJECT_OT_mode_set(wmOperatorType *ot)
1612 {
1613         PropertyRNA *prop;
1614         
1615         /* identifiers */
1616         ot->name = "Set Object Mode";
1617         ot->description = "Sets the object interaction mode";
1618         ot->idname = "OBJECT_OT_mode_set";
1619         
1620         /* api callbacks */
1621         ot->exec = object_mode_set_exec;
1622         
1623         ot->poll = object_mode_set_poll; //ED_operator_object_active_editable;
1624         
1625         /* flags */
1626         ot->flag = 0; /* no register/undo here, leave it to operators being called */
1627         
1628         ot->prop = RNA_def_enum(ot->srna, "mode", rna_enum_object_mode_items, OB_MODE_OBJECT, "Mode", "");
1629         RNA_def_enum_funcs(ot->prop, object_mode_set_itemsf);
1630         RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
1631
1632         prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
1633         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1634 }
1635
1636
1637 void ED_object_toggle_modes(bContext *C, int mode)
1638 {
1639         if (mode != OB_MODE_OBJECT) {
1640                 const char *opstring = object_mode_op_string(mode);
1641
1642                 if (opstring) {
1643 #ifdef USE_WORKSPACE_MODE
1644                         WorkSpace *workspace = CTX_wm_workspace(C);
1645 #endif
1646                         WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
1647
1648 #ifdef USE_WORKSPACE_MODE
1649                         Object *ob = CTX_data_active_object(C);
1650                         if (ob) {
1651                                 BKE_workspace_object_mode_set(workspace, ob->mode);
1652                         }
1653 #endif
1654                 }
1655         }
1656 }
1657
1658 /************************ Game Properties ***********************/
1659
1660 static int game_property_new_exec(bContext *C, wmOperator *op)
1661 {
1662         Object *ob = CTX_data_active_object(C);
1663         bProperty *prop;
1664         char name[MAX_NAME];
1665         int type = RNA_enum_get(op->ptr, "type");
1666
1667         prop = BKE_bproperty_new(type);
1668         BLI_addtail(&ob->prop, prop);
1669
1670         RNA_string_get(op->ptr, "name", name);
1671         if (name[0] != '\0') {
1672                 BLI_strncpy(prop->name, name, sizeof(prop->name));
1673         }
1674
1675         BLI_uniquename(&ob->prop, prop, DATA_("Property"), '.', offsetof(bProperty, name), sizeof(prop->name));
1676
1677         WM_event_add_notifier(C, NC_LOGIC, NULL);
1678         return OPERATOR_FINISHED;
1679 }
1680
1681
1682 void OBJECT_OT_game_property_new(wmOperatorType *ot)
1683 {
1684         /* identifiers */
1685         ot->name = "New Game Property";
1686         ot->description = "Create a new property available to the game engine";
1687         ot->idname = "OBJECT_OT_game_property_new";
1688
1689         /* api callbacks */
1690         ot->exec = game_property_new_exec;
1691         ot->poll = ED_operator_object_active_editable;
1692
1693         /* flags */
1694         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1695
1696         RNA_def_enum(ot->srna, "type", rna_enum_gameproperty_type_items, GPROP_FLOAT, "Type", "Type of game property to add");
1697         RNA_def_string(ot->srna, "name", NULL, MAX_NAME, "Name", "Name of the game property to add");
1698 }
1699
1700 static int game_property_remove_exec(bContext *C, wmOperator *op)
1701 {
1702         Object *ob = CTX_data_active_object(C);
1703         bProperty *prop;
1704         int index = RNA_int_get(op->ptr, "index");
1705
1706         if (!ob)
1707                 return OPERATOR_CANCELLED;
1708
1709         prop = BLI_findlink(&ob->prop, index);
1710
1711         if (prop) {
1712                 BLI_remlink(&ob->prop, prop);
1713                 BKE_bproperty_free(prop);
1714
1715                 WM_event_add_notifier(C, NC_LOGIC, NULL);
1716                 return OPERATOR_FINISHED;
1717         }
1718         else {
1719                 return OPERATOR_CANCELLED;
1720         }
1721 }
1722
1723 void OBJECT_OT_game_property_remove(wmOperatorType *ot)
1724 {
1725         /* identifiers */
1726         ot->name = "Remove Game Property";
1727         ot->description = "Remove game property";
1728         ot->idname = "OBJECT_OT_game_property_remove";
1729
1730         /* api callbacks */
1731         ot->exec = game_property_remove_exec;
1732         ot->poll = ED_operator_object_active_editable;
1733
1734         /* flags */
1735         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1736
1737         RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX);
1738 }
1739
1740 #define GAME_PROPERTY_MOVE_UP    1
1741 #define GAME_PROPERTY_MOVE_DOWN -1
1742
1743 static int game_property_move(bContext *C, wmOperator *op)
1744 {
1745         Object *ob = CTX_data_active_object(C);
1746         bProperty *prop;
1747         bProperty *otherprop = NULL;
1748         const int index = RNA_int_get(op->ptr, "index");
1749         const int dir = RNA_enum_get(op->ptr, "direction");
1750
1751         if (ob == NULL)
1752                 return OPERATOR_CANCELLED;
1753
1754         prop = BLI_findlink(&ob->prop, index);
1755         /* invalid index */
1756         if (prop == NULL)
1757                 return OPERATOR_CANCELLED;
1758
1759         if (dir == GAME_PROPERTY_MOVE_UP) {
1760                 otherprop = prop->prev;
1761         }
1762         else if (dir == GAME_PROPERTY_MOVE_DOWN) {
1763                 otherprop = prop->next;
1764         }
1765         else {
1766                 BLI_assert(0);
1767         }
1768
1769         if (prop && otherprop) {
1770                 BLI_listbase_swaplinks(&ob->prop, prop, otherprop);
1771
1772                 WM_event_add_notifier(C, NC_LOGIC, NULL);
1773                 return OPERATOR_FINISHED;
1774         }
1775         else {
1776                 return OPERATOR_CANCELLED;
1777         }
1778 }
1779
1780 void OBJECT_OT_game_property_move(wmOperatorType *ot)
1781 {
1782         static const EnumPropertyItem direction_property_move[] = {
1783                 {GAME_PROPERTY_MOVE_UP,   "UP",   0, "Up",   ""},
1784                 {GAME_PROPERTY_MOVE_DOWN, "DOWN", 0, "Down", ""},
1785                 {0, NULL, 0, NULL, NULL}
1786         };
1787         PropertyRNA *prop;
1788
1789         /* identifiers */
1790         ot->name = "Move Game Property";
1791         ot->description = "Move game property";
1792         ot->idname = "OBJECT_OT_game_property_move";
1793
1794         /* api callbacks */
1795         ot->exec = game_property_move;
1796         ot->poll = ED_operator_object_active_editable;
1797
1798         /* flags */
1799         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1800
1801         /* properties */
1802         prop = RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to move", 0, INT_MAX);
1803         RNA_def_property_flag(prop, PROP_HIDDEN);
1804         RNA_def_enum(ot->srna, "direction", direction_property_move, 0, "Direction",
1805                      "Direction for moving the property");
1806 }
1807
1808 #undef GAME_PROPERTY_MOVE_UP
1809 #undef GAME_PROPERTY_MOVE_DOWN
1810
1811 #define COPY_PROPERTIES_REPLACE 1
1812 #define COPY_PROPERTIES_MERGE   2
1813 #define COPY_PROPERTIES_COPY    3
1814
1815 static const EnumPropertyItem game_properties_copy_operations[] = {
1816         {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""},
1817         {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""},
1818         {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""},
1819         {0, NULL, 0, NULL, NULL}
1820 };
1821
1822 static const EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
1823 {       
1824         Object *ob = ED_object_active_context(C);
1825         EnumPropertyItem tmp = {0, "", 0, "", ""};
1826         EnumPropertyItem *item = NULL;
1827         bProperty *prop;
1828         int a, totitem = 0;
1829         
1830         if (!ob)
1831                 return DummyRNA_NULL_items;
1832
1833         for (a = 1, prop = ob->prop.first; prop; prop = prop->next, a++) {
1834                 tmp.value = a;
1835                 tmp.identifier = prop->name;
1836                 tmp.name = prop->name;
1837                 RNA_enum_item_add(&item, &totitem, &tmp);
1838         }
1839
1840         RNA_enum_item_end(&item, &totitem);
1841         *r_free = true;
1842
1843         return item;
1844 }
1845
1846 static int game_property_copy_exec(bContext *C, wmOperator *op)
1847 {
1848         Object *ob = ED_object_active_context(C);
1849         bProperty *prop;
1850         int type = RNA_enum_get(op->ptr, "operation");
1851         int propid = RNA_enum_get(op->ptr, "property");
1852
1853         if (propid > 0) { /* copy */
1854                 prop = BLI_findlink(&ob->prop, propid - 1);
1855                 
1856                 if (prop) {
1857                         CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
1858                         {
1859                                 if (ob != ob_iter)
1860                                         BKE_bproperty_object_set(ob_iter, prop);
1861                         } CTX_DATA_END;
1862                 }
1863         }
1864
1865         else {
1866                 CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
1867                 {
1868                         if (ob != ob_iter) {
1869                                 if (type == COPY_PROPERTIES_REPLACE) {
1870                                         BKE_bproperty_copy_list(&ob_iter->prop, &ob->prop);
1871                                 }
1872                                 else {
1873                                         /* merge - the default when calling with no argument */
1874                                         for (prop = ob->prop.first; prop; prop = prop->next) {
1875                                                 BKE_bproperty_object_set(ob_iter, prop);
1876                                         }
1877                                 }
1878                         }
1879                 }
1880                 CTX_DATA_END;
1881         }
1882
1883         return OPERATOR_FINISHED;
1884 }
1885
1886 void OBJECT_OT_game_property_copy(wmOperatorType *ot)
1887 {
1888         PropertyRNA *prop;
1889         /* identifiers */
1890         ot->name = "Copy Game Property";
1891         ot->idname = "OBJECT_OT_game_property_copy";
1892         ot->description = "Copy/merge/replace a game property from active object to all selected objects";
1893
1894         /* api callbacks */
1895         ot->exec = game_property_copy_exec;
1896         ot->poll = ED_operator_object_active_editable;
1897
1898         /* flags */
1899         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1900
1901         RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", "");
1902         prop = RNA_def_enum(ot->srna, "property", DummyRNA_NULL_items, 0, "Property", "Properties to copy");
1903         RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_ENUM_NO_TRANSLATE);
1904         RNA_def_enum_funcs(prop, gameprops_itemf);
1905         ot->prop = prop;
1906 }
1907
1908 static int game_property_clear_exec(bContext *C, wmOperator *UNUSED(op))
1909 {
1910         CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
1911         {
1912                 BKE_bproperty_free_list(&ob_iter->prop);
1913         }
1914         CTX_DATA_END;
1915
1916         WM_event_add_notifier(C, NC_LOGIC, NULL);
1917         return OPERATOR_FINISHED;
1918 }
1919 void OBJECT_OT_game_property_clear(wmOperatorType *ot)
1920 {
1921         /* identifiers */
1922         ot->name = "Clear Game Properties";
1923         ot->idname = "OBJECT_OT_game_property_clear";
1924         ot->description = "Remove all game properties from all selected objects";
1925
1926         /* api callbacks */
1927         ot->exec = game_property_clear_exec;
1928         ot->poll = ED_operator_object_active_editable;
1929
1930         /* flags */
1931         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1932 }
1933
1934 /************************ Copy Logic Bricks ***********************/
1935
1936 static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op))
1937 {
1938         Object *ob = ED_object_active_context(C);
1939
1940         CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
1941         {
1942                 if (ob != ob_iter) {
1943                         /* first: free all logic */
1944                         free_sensors(&ob_iter->sensors);
1945                         unlink_controllers(&ob_iter->controllers);
1946                         free_controllers(&ob_iter->controllers);
1947                         unlink_actuators(&ob_iter->actuators);
1948                         free_actuators(&ob_iter->actuators);
1949                 
1950                         /* now copy it, this also works without logicbricks! */
1951                         clear_sca_new_poins_ob(ob);
1952                         copy_sensors(&ob_iter->sensors, &ob->sensors, 0);
1953                         copy_controllers(&ob_iter->controllers, &ob->controllers, 0);
1954                         copy_actuators(&ob_iter->actuators, &ob->actuators, 0);
1955                         set_sca_new_poins_ob(ob_iter);
1956                 
1957                         /* some menu settings */
1958                         ob_iter->scavisflag = ob->scavisflag;
1959                         ob_iter->scaflag = ob->scaflag;
1960                 
1961                         /* set the initial state */
1962                         ob_iter->state = ob->state;
1963                         ob_iter->init_state = ob->init_state;
1964
1965                         if (ob_iter->totcol == ob->totcol) {
1966                                 ob_iter->actcol = ob->actcol;
1967                                 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
1968                         }
1969                 }
1970         }
1971         CTX_DATA_END;
1972
1973         WM_event_add_notifier(C, NC_LOGIC, NULL);
1974
1975         return OPERATOR_FINISHED;
1976 }
1977
1978 void OBJECT_OT_logic_bricks_copy(wmOperatorType *ot)
1979 {
1980         /* identifiers */
1981         ot->name = "Copy Logic Bricks to Selected";
1982         ot->description = "Copy logic bricks to other selected objects";
1983         ot->idname = "OBJECT_OT_logic_bricks_copy";
1984
1985         /* api callbacks */
1986         ot->exec = logicbricks_copy_exec;
1987         ot->poll = ED_operator_object_active_editable;
1988
1989         /* flags */
1990         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1991 }
1992
1993 static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op))
1994 {
1995         Object *ob = ED_object_active_context(C);
1996         
1997         CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
1998         {
1999                 if (ob != ob_iter) {
2000                         ob_iter->gameflag = ob->gameflag;
2001                         ob_iter->gameflag2 = ob->gameflag2;
2002                         ob_iter->inertia = ob->inertia;
2003                         ob_iter->formfactor = ob->formfactor;
2004                         ob_iter->damping = ob->damping;
2005                         ob_iter->rdamping = ob->rdamping;
2006                         ob_iter->min_vel = ob->min_vel;
2007                         ob_iter->max_vel = ob->max_vel;
2008                         ob_iter->min_angvel = ob->min_angvel;
2009                         ob_iter->max_angvel = ob->max_angvel;
2010                         ob_iter->obstacleRad = ob->obstacleRad;
2011                         ob_iter->mass = ob->mass;
2012                         copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction);
2013                         ob_iter->collision_boundtype = ob->collision_boundtype;
2014                         ob_iter->margin = ob->margin;
2015                         ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
2016                         if (ob->restrictflag & OB_RESTRICT_RENDER) 
2017                                 ob_iter->restrictflag |= OB_RESTRICT_RENDER;
2018                         else
2019                                 ob_iter->restrictflag &= ~OB_RESTRICT_RENDER;
2020
2021                         ob_iter->col_group = ob->col_group;
2022                         ob_iter->col_mask = ob->col_mask;
2023                 }
2024         }
2025         CTX_DATA_END;
2026         
2027         return OPERATOR_FINISHED;
2028 }
2029
2030 void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot)
2031 {
2032         /* identifiers */
2033         ot->name = "Copy Game Physics Properties to Selected";
2034         ot->description = "Copy game physics properties to other selected objects";
2035         ot->idname = "OBJECT_OT_game_physics_copy";
2036         
2037         /* api callbacks */
2038         ot->exec = game_physics_copy_exec;
2039         ot->poll = ED_operator_object_active_editable;
2040         
2041         /* flags */
2042         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2043 }
2044
2045 /* generic utility function */
2046
2047 bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_only, float r_center[3])
2048 {
2049         switch (obedit->type) {
2050                 case OB_MESH:
2051                 {
2052                         BMEditMesh *em = BKE_editmesh_from_object(obedit);
2053                         BMEditSelection ese;
2054
2055                         if (BM_select_history_active_get(em->bm, &ese)) {
2056                                 BM_editselection_center(&ese, r_center);
2057                                 return true;
2058                         }
2059                         break;
2060                 }
2061                 case OB_ARMATURE:
2062                 {
2063                         bArmature *arm = obedit->data;
2064                         EditBone *ebo = arm->act_edbone;
2065
2066                         if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) {
2067                                 copy_v3_v3(r_center, ebo->head);
2068                                 return true;
2069                         }
2070
2071                         break;
2072                 }
2073                 case OB_CURVE:
2074                 case OB_SURF:
2075                 {
2076                         Curve *cu = obedit->data;
2077
2078                         if (ED_curve_active_center(cu, r_center)) {
2079                                 return true;
2080                         }
2081                         break;
2082                 }
2083                 case OB_MBALL:
2084                 {
2085                         MetaBall *mb = obedit->data;
2086                         MetaElem *ml_act = mb->lastelem;
2087
2088                         if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
2089                                 copy_v3_v3(r_center, &ml_act->x);
2090                                 return true;
2091                         }
2092                         break;
2093                 }
2094                 case OB_LATTICE:
2095                 {
2096                         BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
2097
2098                         if (actbp) {
2099                                 copy_v3_v3(r_center, actbp->vec);
2100                                 return true;
2101                         }
2102                         break;
2103                 }
2104         }
2105
2106         return false;
2107 }