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