committing working copy
[blender.git] / source / blender / editors / object / object_relations.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2002-2008 full recode
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_anim_types.h"
35 #include "DNA_constraint_types.h"
36 #include "DNA_group_types.h"
37 #include "DNA_lamp_types.h"
38 #include "DNA_lattice_types.h"
39 #include "DNA_material_types.h"
40 #include "DNA_meta_types.h"
41 #include "DNA_particle_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_world_types.h"
44
45 #include "BLI_math.h"
46 #include "BLI_editVert.h"
47 #include "BLI_listbase.h"
48 #include "BLI_string.h"
49
50 #include "BKE_action.h"
51 #include "BKE_animsys.h"
52 #include "BKE_armature.h"
53 #include "BKE_context.h"
54 #include "BKE_constraint.h"
55 #include "BKE_curve.h"
56 #include "BKE_depsgraph.h"
57 #include "BKE_displist.h"
58 #include "BKE_global.h"
59 #include "BKE_lattice.h"
60 #include "BKE_library.h"
61 #include "BKE_main.h"
62 #include "BKE_material.h"
63 #include "BKE_mball.h"
64 #include "BKE_mesh.h"
65 #include "BKE_modifier.h"
66 #include "BKE_object.h"
67 #include "BKE_report.h"
68 #include "BKE_sca.h"
69 #include "BKE_scene.h"
70 #include "BKE_texture.h"
71 #include "BKE_utildefines.h"
72 #include "BKE_tessmesh.h"
73
74 #include "WM_api.h"
75 #include "WM_types.h"
76
77 #include "UI_interface.h"
78 #include "UI_resources.h"
79
80 #include "RNA_access.h"
81 #include "RNA_define.h"
82 #include "RNA_enum_types.h"
83
84 #include "ED_armature.h"
85 #include "ED_curve.h"
86 #include "ED_object.h"
87 #include "ED_screen.h"
88 #include "ED_view3d.h"
89
90 #include "object_intern.h"
91
92 /*********************** Make Vertex Parent Operator ************************/
93
94 static int vertex_parent_set_poll(bContext *C)
95 {
96         return ED_operator_editmesh(C) || ED_operator_editsurfcurve(C) || ED_operator_editlattice(C);
97 }
98
99 static int vertex_parent_set_exec(bContext *C, wmOperator *op)
100 {
101         Scene *scene= CTX_data_scene(C);
102         Object *obedit= CTX_data_edit_object(C);
103         BMVert *eve;
104         BMIter iter;
105         Curve *cu;
106         Nurb *nu;
107         BezTriple *bezt;
108         BPoint *bp;
109         Object *par;
110         int a, v1=0, v2=0, v3=0, v4=0, nr=1;
111         
112         /* we need 1 to 3 selected vertices */
113         
114         if(obedit->type==OB_MESH) {
115                 Mesh *me= obedit->data;
116                 BMEditMesh *em = me->edit_btmesh;
117
118                 BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
119                         if (BM_TestHFlag(eve, BM_SELECT)) {
120                                 if(v1==0) v1= nr;
121                                 else if(v2==0) v2= nr;
122                                 else if(v3==0) v3= nr;
123                                 else if(v4==0) v4= nr;
124                                 else break;
125                         }
126                 }
127         }
128         else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) {
129                 ListBase *editnurb= curve_get_editcurve(obedit);
130                 
131                 cu= obedit->data;
132
133                 nu= editnurb->first;
134                 while(nu) {
135                         if(nu->type == CU_BEZIER) {
136                                 bezt= nu->bezt;
137                                 a= nu->pntsu;
138                                 while(a--) {
139                                         if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
140                                                 if(v1==0) v1= nr;
141                                                 else if(v2==0) v2= nr;
142                                                 else if(v3==0) v3= nr;
143                                                 else if(v4==0) v4= nr;
144                                                 else break;
145                                         }
146                                         nr++;
147                                         bezt++;
148                                 }
149                         }
150                         else {
151                                 bp= nu->bp;
152                                 a= nu->pntsu*nu->pntsv;
153                                 while(a--) {
154                                         if(bp->f1 & SELECT) {
155                                                 if(v1==0) v1= nr;
156                                                 else if(v2==0) v2= nr;
157                                                 else if(v3==0) v3= nr;
158                                                 else if(v4==0) v4= nr;
159                                                 else break;
160                                         }
161                                         nr++;
162                                         bp++;
163                                 }
164                         }
165                         nu= nu->next;
166                 }
167         }
168         else if(obedit->type==OB_LATTICE) {
169                 Lattice *lt= obedit->data;
170                 
171                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
172                 bp= lt->editlatt->def;
173                 while(a--) {
174                         if(bp->f1 & SELECT) {
175                                 if(v1==0) v1= nr;
176                                 else if(v2==0) v2= nr;
177                                 else if(v3==0) v3= nr;
178                                 else if(v4==0) v4= nr;
179                                 else break;
180                         }
181                         nr++;
182                         bp++;
183                 }
184         }
185         
186         if(v4 || !((v1 && v2==0 && v3==0) || (v1 && v2 && v3)) ) {
187                 BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to");
188                 return OPERATOR_CANCELLED;
189         }
190         
191         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
192                 if(ob != obedit) {
193                         ob->recalc |= OB_RECALC_ALL;
194                         par= obedit->parent;
195                         
196                         while(par) {
197                                 if(par==ob) break;
198                                 par= par->parent;
199                         }
200                         if(par) {
201                                 BKE_report(op->reports, RPT_ERROR, "Loop in parents");
202                         }
203                         else {
204                                 Object workob;
205                                 
206                                 ob->parent= BASACT->object;
207                                 if(v3) {
208                                         ob->partype= PARVERT3;
209                                         ob->par1= v1-1;
210                                         ob->par2= v2-1;
211                                         ob->par3= v3-1;
212
213                                         /* inverse parent matrix */
214                                         what_does_parent(scene, ob, &workob);
215                                         invert_m4_m4(ob->parentinv, workob.obmat);
216                                 }
217                                 else {
218                                         ob->partype= PARVERT1;
219                                         ob->par1= v1-1;
220
221                                         /* inverse parent matrix */
222                                         what_does_parent(scene, ob, &workob);
223                                         invert_m4_m4(ob->parentinv, workob.obmat);
224                                 }
225                         }
226                 }
227         }
228         CTX_DATA_END;
229         
230         DAG_scene_sort(scene);
231
232         WM_event_add_notifier(C, NC_OBJECT, NULL);
233
234         return OPERATOR_FINISHED;
235 }
236
237 void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
238 {
239         /* identifiers */
240         ot->name= "Make Vertex Parent";
241         ot->description = "Parent selected objects to the selected vertices";
242         ot->idname= "OBJECT_OT_vertex_parent_set";
243         
244         /* api callbacks */
245         ot->invoke= WM_operator_confirm;
246         ot->poll= vertex_parent_set_poll;
247         ot->exec= vertex_parent_set_exec;
248         
249         /* flags */
250         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
251 }
252
253 /********************** Make Proxy Operator *************************/
254
255 /* set the object to proxify */
256 static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
257 {
258         Scene *scene= CTX_data_scene(C);
259         Object *ob= CTX_data_active_object(C);
260         
261         /* sanity checks */
262         if (!scene || scene->id.lib || !ob)
263                 return OPERATOR_CANCELLED;
264                 
265         /* Get object to work on - use a menu if we need to... */
266         if (ob->dup_group && ob->dup_group->id.lib) {
267                 /* gives menu with list of objects in group */
268                 //proxy_group_objects_menu(C, op, ob, ob->dup_group);
269                 WM_enum_search_invoke(C, op, evt);
270                 return OPERATOR_CANCELLED;
271
272         }
273         else if (ob->id.lib) {
274                 uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION);
275                 uiLayout *layout= uiPupMenuLayout(pup);
276                 PointerRNA props_ptr;
277                 
278                 /* create operator menu item with relevant properties filled in */
279                 props_ptr= uiItemFullO(layout, op->idname, op->type->name, 0, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
280                 
281                 /* present the menu and be done... */
282                 uiPupMenuEnd(C, pup);
283         }
284         else {
285                 /* error.. cannot continue */
286                 BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group");
287         }
288         
289         /* this invoke just calls another instance of this operator... */
290         return OPERATOR_CANCELLED;
291 }
292
293 static int make_proxy_exec (bContext *C, wmOperator *op)
294 {
295         Object *ob, *gob= CTX_data_active_object(C);
296         GroupObject *go;
297         Scene *scene= CTX_data_scene(C);
298
299         if (gob->dup_group != NULL)
300         {
301                 go= BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "type"));
302                 ob= go->ob;
303         }
304         else
305         {
306                 ob= gob;
307                 gob = NULL;
308         }
309         
310         if (ob) {
311                 Object *newob;
312                 Base *newbase, *oldbase= BASACT;
313                 char name[32];
314                 
315                 /* Add new object for the proxy */
316                 newob= add_object(scene, OB_EMPTY);
317                 if (gob)
318                         strcpy(name, gob->id.name+2);
319                 else
320                         strcpy(name, ob->id.name+2);
321                 strcat(name, "_proxy");
322                 rename_id(&newob->id, name);
323                 
324                 /* set layers OK */
325                 newbase= BASACT;        /* add_object sets active... */
326                 newbase->lay= oldbase->lay;
327                 newob->lay= newbase->lay;
328                 
329                 /* remove base, leave user count of object, it gets linked in object_make_proxy */
330                 if (gob==NULL) {
331                         BLI_remlink(&scene->base, oldbase);
332                         MEM_freeN(oldbase);
333                 }
334                 
335                 object_make_proxy(newob, ob, gob);
336                 
337                 /* depsgraph flushes are needed for the new data */
338                 DAG_scene_sort(scene);
339                 DAG_id_flush_update(&newob->id, OB_RECALC_ALL);
340                 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, newob);
341         }
342         else {
343                 BKE_report(op->reports, RPT_ERROR, "No object to make proxy for");
344                 return OPERATOR_CANCELLED;
345         }
346         
347         return OPERATOR_FINISHED;
348 }
349
350 /* Generic itemf's for operators that take library args */
351 static EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA *ptr, int *free)
352 {
353         EnumPropertyItem *item= NULL, item_tmp;
354         int totitem= 0;
355         int i= 0;
356         Object *ob= CTX_data_active_object(C);
357         GroupObject *go;
358
359         if(!ob || !ob->dup_group)
360                 return DummyRNA_DEFAULT_items;
361
362         memset(&item_tmp, 0, sizeof(item_tmp));
363
364         /* find the object to affect */
365         for (go= ob->dup_group->gobject.first; go; go= go->next) {
366                 item_tmp.identifier= item_tmp.name= go->ob->id.name+2;
367                 item_tmp.value= i++;
368                 RNA_enum_item_add(&item, &totitem, &item_tmp);
369         }
370
371         RNA_enum_item_end(&item, &totitem);
372         *free= 1;
373
374         return item;
375 }
376
377 void OBJECT_OT_proxy_make (wmOperatorType *ot)
378 {
379         PropertyRNA *prop;
380
381         /* identifiers */
382         ot->name= "Make Proxy";
383         ot->idname= "OBJECT_OT_proxy_make";
384         ot->description= "Add empty object to become local replacement data of a library-linked object";
385         
386         /* callbacks */
387         ot->invoke= make_proxy_invoke;
388         ot->exec= make_proxy_exec;
389         ot->poll= ED_operator_object_active;
390         
391         /* flags */
392         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
393         
394         /* properties */
395         RNA_def_string(ot->srna, "object", "", 19, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for.");
396         prop= RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Type", "Group object"); /* XXX, relies on hard coded ID at the moment */
397         RNA_def_enum_funcs(prop, proxy_group_object_itemf);
398         ot->prop= prop;
399 }
400
401 /********************** Clear Parent Operator ******************* */
402
403 static EnumPropertyItem prop_clear_parent_types[] = {
404         {0, "CLEAR", 0, "Clear Parent", ""},
405         {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""},
406         {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""},
407         {0, NULL, 0, NULL, NULL}
408 };
409
410 /* note, poll should check for editable scene */
411 static int parent_clear_exec(bContext *C, wmOperator *op)
412 {
413         int type= RNA_enum_get(op->ptr, "type");
414         
415         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
416
417                 if(type == 0) {
418                         ob->parent= NULL;
419                 }                       
420                 else if(type == 1) {
421                         ob->parent= NULL;
422                         object_apply_mat4(ob, ob->obmat);
423                 }
424                 else if(type == 2)
425                         unit_m4(ob->parentinv);
426
427                 ob->recalc |= OB_RECALC_ALL;
428         }
429         CTX_DATA_END;
430         
431         DAG_scene_sort(CTX_data_scene(C));
432         DAG_ids_flush_update(0);
433         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
434
435         return OPERATOR_FINISHED;
436 }
437
438 void OBJECT_OT_parent_clear(wmOperatorType *ot)
439 {
440         /* identifiers */
441         ot->name= "Clear Parent";
442         ot->description = "Clear the object's parenting";
443         ot->idname= "OBJECT_OT_parent_clear";
444         
445         /* api callbacks */
446         ot->invoke= WM_menu_invoke;
447         ot->exec= parent_clear_exec;
448         
449         ot->poll= ED_operator_object_active_editable;
450         
451         /* flags */
452         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
453         
454         ot->prop= RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
455 }
456
457 /* ******************** Make Parent Operator *********************** */
458
459 #define PAR_OBJECT                              0
460 #define PAR_ARMATURE                    1
461 #define PAR_ARMATURE_NAME               2
462 #define PAR_ARMATURE_ENVELOPE   3
463 #define PAR_ARMATURE_AUTO               4
464 #define PAR_BONE                                5
465 #define PAR_CURVE                               6
466 #define PAR_FOLLOW                              7
467 #define PAR_PATH_CONST                  8
468 #define PAR_LATTICE                             9
469 #define PAR_VERTEX                              10
470 #define PAR_TRIA                                11
471
472 static EnumPropertyItem prop_make_parent_types[] = {
473         {PAR_OBJECT, "OBJECT", 0, "Object", ""},
474         {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""},
475         {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, "   With Empty Groups", ""},
476         {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, "   With Automatic Weights", ""},
477         {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, "   With Envelope Weights", ""},
478         {PAR_BONE, "BONE", 0, "Bone", ""},
479         {PAR_CURVE, "CURVE", 0, "Curve Deform", ""},
480         {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""},
481         {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""},
482         {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""},
483         {PAR_VERTEX, "VERTEX", 0, "Vertex", ""},
484         {PAR_TRIA, "TRIA", 0, "Triangle", ""},
485         {0, NULL, 0, NULL, NULL}
486 };
487
488 static int test_parent_loop(Object *par, Object *ob)
489 {
490         /* test if 'ob' is a parent somewhere in par's parents */
491         
492         if(par == NULL) return 0;
493         if(ob == par) return 1;
494         
495         return test_parent_loop(par->parent, ob);
496 }
497
498 void ED_object_parent(Object *ob, Object *par, int type, const char *substr)
499 {
500         if(!par || test_parent_loop(par, ob)) {
501                 ob->parent= NULL;
502                 ob->partype= PAROBJECT;
503                 ob->parsubstr[0]= 0;
504                 return;
505         }
506
507         /* this could use some more checks */
508
509         ob->parent= par;
510         ob->partype &= ~PARTYPE;
511         ob->partype |= type;
512         BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr));
513 }
514
515 static int parent_set_exec(bContext *C, wmOperator *op)
516 {
517         Scene *scene= CTX_data_scene(C);
518         Object *par= CTX_data_active_object(C);
519         bPoseChannel *pchan= NULL;
520         int partype= RNA_enum_get(op->ptr, "type");
521         int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO);
522         
523         par->recalc |= OB_RECALC_OB;
524         
525         /* preconditions */
526         if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) {
527                 if(par->type!=OB_CURVE)
528                         return OPERATOR_CANCELLED;
529                 else {
530                         Curve *cu= par->data;
531                         
532                         if((cu->flag & CU_PATH)==0) {
533                                 cu->flag |= CU_PATH|CU_FOLLOW;
534                                 makeDispListCurveTypes(scene, par, 0);  /* force creation of path data */
535                         }
536                         else cu->flag |= CU_FOLLOW;
537                         
538                         /* fall back on regular parenting now (for follow only) */
539                         if(partype == PAR_FOLLOW)
540                                 partype= PAR_OBJECT;
541                 }               
542         }
543         else if(partype==PAR_BONE) {
544                 pchan= get_active_posechannel(par);
545                 
546                 if(pchan==NULL) {
547                         BKE_report(op->reports, RPT_ERROR, "No active Bone");
548                         return OPERATOR_CANCELLED;
549                 }
550         }
551         
552         /* context itterator */
553         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
554                 
555                 if(ob!=par) {
556                         
557                         if( test_parent_loop(par, ob) ) {
558                                 BKE_report(op->reports, RPT_ERROR, "Loop in parents");
559                         }
560                         else {
561                                 Object workob;
562                                 
563                                 /* apply transformation of previous parenting */
564                                 object_apply_mat4(ob, ob->obmat);
565                                 
566                                 /* set the parent (except for follow-path constraint option) */
567                                 if(partype != PAR_PATH_CONST)
568                                         ob->parent= par;
569                                 
570                                 /* handle types */
571                                 if (pchan)
572                                         strcpy(ob->parsubstr, pchan->name);
573                                 else
574                                         ob->parsubstr[0]= 0;
575                                         
576                                 if(partype == PAR_PATH_CONST)
577                                         ; /* don't do anything here, since this is not technically "parenting" */
578                                 else if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm )
579                                 {
580                                         /* partype is now set to PAROBJECT so that invisible 'virtual' modifiers don't need to be created
581                                          * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, creating the virtual modifiers
582                                          */
583                                         ob->partype= PAROBJECT; /* note, dna define, not operator property */
584                                         //ob->partype= PARSKEL; /* note, dna define, not operator property */
585                                         
586                                         /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */
587                                         // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet
588                                         if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) 
589                                         {
590                                                 ModifierData *md;
591
592                                                 switch (partype) {
593                                                 case PAR_CURVE: /* curve deform */
594                                                         md= ED_object_modifier_add(op->reports, scene, ob, NULL, eModifierType_Curve);
595                                                         ((CurveModifierData *)md)->object= par;
596                                                         break;
597                                                 case PAR_LATTICE: /* lattice deform */
598                                                         md= ED_object_modifier_add(op->reports, scene, ob, NULL, eModifierType_Lattice);
599                                                         ((LatticeModifierData *)md)->object= par;
600                                                         break;
601                                                 default: /* armature deform */
602                                                         md= ED_object_modifier_add(op->reports, scene, ob, NULL, eModifierType_Armature);
603                                                         ((ArmatureModifierData *)md)->object= par;
604                                                         break;
605                                                 }
606                                         }
607                                 }
608                                 else if (partype == PAR_BONE)
609                                         ob->partype= PARBONE; /* note, dna define, not operator property */
610                                 else
611                                         ob->partype= PAROBJECT; /* note, dna define, not operator property */
612                                 
613                                 /* constraint */
614                                 if(partype == PAR_PATH_CONST) {
615                                         bConstraint *con;
616                                         bFollowPathConstraint *data;
617                                         float cmat[4][4], vec[3];
618                                         
619                                         con = add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
620                                         
621                                         data = con->data;
622                                         data->tar = par;
623                                         
624                                         get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob));
625                                         sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
626                                         
627                                         ob->loc[0] = vec[0];
628                                         ob->loc[1] = vec[1];
629                                         ob->loc[2] = vec[2];
630                                 }
631                                 else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) {
632                                         if(partype == PAR_ARMATURE_NAME)
633                                                 create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_NAME, 0);
634                                         else if(partype == PAR_ARMATURE_ENVELOPE)
635                                                 create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_ENVELOPE, 0);
636                                         else if(partype == PAR_ARMATURE_AUTO)
637                                                 create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_AUTO, 0);
638                                         
639                                         /* get corrected inverse */
640                                         ob->partype= PAROBJECT;
641                                         what_does_parent(scene, ob, &workob);
642                                         
643                                         invert_m4_m4(ob->parentinv, workob.obmat);
644                                 }
645                                 else {
646                                         /* calculate inverse parent matrix */
647                                         what_does_parent(scene, ob, &workob);
648                                         invert_m4_m4(ob->parentinv, workob.obmat);
649                                 }
650                                 
651                                 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
652                         }
653                 }
654         }
655         CTX_DATA_END;
656         
657         DAG_scene_sort(scene);
658         DAG_ids_flush_update(0);
659         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
660         
661         return OPERATOR_FINISHED;
662 }
663
664 static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
665 {
666         Object *ob= CTX_data_active_object(C);
667         uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", 0);
668         uiLayout *layout= uiPupMenuLayout(pup);
669         
670         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
671         uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_OBJECT);
672         
673         /* ob becomes parent, make the associated menus */
674         if(ob->type==OB_ARMATURE) {
675                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE);
676                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_NAME);
677                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_ENVELOPE);
678                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_AUTO);
679                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_BONE);
680         }
681         else if(ob->type==OB_CURVE) {
682                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_CURVE);
683                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_FOLLOW);
684                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_PATH_CONST);
685         }
686         else if(ob->type == OB_LATTICE) {
687                 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_LATTICE);
688         }
689         
690         uiPupMenuEnd(C, pup);
691         
692         return OPERATOR_CANCELLED;
693 }
694
695
696 void OBJECT_OT_parent_set(wmOperatorType *ot)
697 {
698         /* identifiers */
699         ot->name= "Make Parent";
700         ot->description = "Set the object's parenting";
701         ot->idname= "OBJECT_OT_parent_set";
702         
703         /* api callbacks */
704         ot->invoke= parent_set_invoke;
705         ot->exec= parent_set_exec;
706         
707         ot->poll= ED_operator_object_active_editable;
708         
709         /* flags */
710         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
711         
712         RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
713 }
714
715 /* ************ Make Parent Without Inverse Operator ******************* */
716
717 static int parent_noinv_set_exec(bContext *C, wmOperator *op)
718 {
719         Object *par= CTX_data_active_object(C);
720         
721         par->recalc |= OB_RECALC_OB;
722         
723         /* context itterator */
724         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
725                 if (ob != par) {
726                         if (test_parent_loop(par, ob)) {
727                                 BKE_report(op->reports, RPT_ERROR, "Loop in parents");
728                         }
729                         else {
730                                 /* clear inverse matrix and also the object location */
731                                 unit_m4(ob->parentinv);
732                                 memset(ob->loc, 0, 3*sizeof(float));
733                                 
734                                 /* set recalc flags */
735                                 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
736                                 
737                                 /* set parenting type for object - object only... */
738                                 ob->parent= par;
739                                 ob->partype= PAROBJECT; /* note, dna define, not operator property */
740                         }
741                 }
742         }
743         CTX_DATA_END;
744         
745         DAG_scene_sort(CTX_data_scene(C));
746         DAG_ids_flush_update(0);
747         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
748         
749         return OPERATOR_FINISHED;
750 }
751
752 void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
753 {
754         /* identifiers */
755         ot->name= "Make Parent without Inverse";
756         ot->description = "Set the object's parenting without setting the inverse parent correction";
757         ot->idname= "OBJECT_OT_parent_no_inverse_set";
758         
759         /* api callbacks */
760         ot->invoke= WM_operator_confirm;
761         ot->exec= parent_noinv_set_exec;
762         ot->poll= ED_operator_object_active_editable;
763         
764         /* flags */
765         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
766 }
767
768 /************************ Clear Slow Parent Operator *********************/
769
770 static int object_slow_parent_clear_exec(bContext *C, wmOperator *op)
771 {
772         Scene *scene= CTX_data_scene(C);
773
774         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
775                 if(ob->parent) {
776                         if(ob->partype & PARSLOW) {
777                                 ob->partype -= PARSLOW;
778                                 where_is_object(scene, ob);
779                                 ob->partype |= PARSLOW;
780                                 ob->recalc |= OB_RECALC_OB;
781                         }
782                 }
783         }
784         CTX_DATA_END;
785
786         DAG_ids_flush_update(0);
787         WM_event_add_notifier(C, NC_SCENE, scene);
788         
789         return OPERATOR_FINISHED;
790 }
791
792 void OBJECT_OT_slow_parent_clear(wmOperatorType *ot)
793 {
794         
795         /* identifiers */
796         ot->name= "Clear Slow Parent";
797         ot->description = "Clear the object's slow parent";
798         ot->idname= "OBJECT_OT_slow_parent_clear";
799         
800         /* api callbacks */
801         ot->invoke= WM_operator_confirm;
802         ot->exec= object_slow_parent_clear_exec;
803         ot->poll= ED_operator_view3d_active;
804         
805         /* flags */
806         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
807 }
808
809 /********************** Make Slow Parent Operator *********************/
810
811 static int object_slow_parent_set_exec(bContext *C, wmOperator *op)
812 {
813         Scene *scene= CTX_data_scene(C);
814
815         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
816                 if(ob->parent)
817                         ob->partype |= PARSLOW;
818
819                 ob->recalc |= OB_RECALC_OB;
820                 
821         }
822         CTX_DATA_END;
823
824         DAG_ids_flush_update(0);
825         WM_event_add_notifier(C, NC_SCENE, scene);
826         
827         return OPERATOR_FINISHED;
828 }
829
830 void OBJECT_OT_slow_parent_set(wmOperatorType *ot)
831 {
832         
833         /* identifiers */
834         ot->name= "Set Slow Parent";
835         ot->description = "Set the object's slow parent";
836         ot->idname= "OBJECT_OT_slow_parent_set";
837         
838         /* api callbacks */
839         ot->invoke= WM_operator_confirm;
840         ot->exec= object_slow_parent_set_exec;
841         ot->poll= ED_operator_view3d_active;
842         
843         /* flags */
844         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
845 }
846
847 /* ******************** Clear Track Operator ******************* */
848
849 static EnumPropertyItem prop_clear_track_types[] = {
850         {0, "CLEAR", 0, "Clear Track", ""},
851         {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""},
852         {0, NULL, 0, NULL, NULL}
853 };
854
855 /* note, poll should check for editable scene */
856 static int object_track_clear_exec(bContext *C, wmOperator *op)
857 {
858         int type= RNA_enum_get(op->ptr, "type");
859
860         if(CTX_data_edit_object(C)) {
861                 BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode");
862                 return OPERATOR_CANCELLED;
863         }
864         CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
865                 bConstraint *con, *pcon;
866                 
867                 /* remove track-object for old track */
868                 ob->track= NULL;
869                 ob->recalc |= OB_RECALC_ALL;
870                 
871                 /* also remove all tracking constraints */
872                 for (con= ob->constraints.last; con; con= pcon) {
873                         pcon= con->prev;
874                         if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK))
875                                 remove_constraint(&ob->constraints, con);
876                 }
877                 
878                 if(type == 1)
879                         object_apply_mat4(ob, ob->obmat);
880         }
881         CTX_DATA_END;
882
883         DAG_ids_flush_update(0);
884         DAG_scene_sort(CTX_data_scene(C));
885         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
886
887         return OPERATOR_FINISHED;
888 }
889
890 void OBJECT_OT_track_clear(wmOperatorType *ot)
891 {
892         /* identifiers */
893         ot->name= "Clear track";
894         ot->description = "Clear tracking constraint or flag from object";
895         ot->idname= "OBJECT_OT_track_clear";
896         
897         /* api callbacks */
898         ot->invoke= WM_menu_invoke;
899         ot->exec= object_track_clear_exec;
900         
901         ot->poll= ED_operator_scene_editable;
902         
903         /* flags */
904         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
905         
906         ot->prop= RNA_def_enum(ot->srna, "type", prop_clear_track_types, 0, "Type", "");
907 }
908
909 /************************** Make Track Operator *****************************/
910
911 static EnumPropertyItem prop_make_track_types[] = {
912         {1, "DAMPTRACK", 0, "Damped Track Constraint", ""},
913         {2, "TRACKTO", 0, "Track To Constraint", ""},
914         {3, "LOCKTRACK", 0, "Lock Track Constraint", ""},
915         {0, NULL, 0, NULL, NULL}
916 };
917
918 static int track_set_exec(bContext *C, wmOperator *op)
919 {
920         Scene *scene= CTX_data_scene(C);
921         Object *obact= CTX_data_active_object(C); 
922         
923         int type= RNA_enum_get(op->ptr, "type");
924                 
925         if(type == 1) {
926                 bConstraint *con;
927                 bDampTrackConstraint *data;
928
929                 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
930                         if(ob!=obact) {
931                                 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
932
933                                 data = con->data;
934                                 data->tar = obact;
935                                 ob->recalc |= OB_RECALC_ALL;
936                                 
937                                 /* Lamp and Camera track differently by default */
938                                 if (ob->type == OB_LAMP || ob->type == OB_CAMERA)
939                                         data->trackflag = TRACK_nZ;
940                         }
941                 }
942                 CTX_DATA_END;
943         }
944         else if(type == 2) {
945                 bConstraint *con;
946                 bTrackToConstraint *data;
947
948                 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
949                         if(ob!=obact) {
950                                 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
951
952                                 data = con->data;
953                                 data->tar = obact;
954                                 ob->recalc |= OB_RECALC_ALL;
955                                 
956                                 /* Lamp and Camera track differently by default */
957                                 if (ob->type == OB_LAMP || ob->type == OB_CAMERA) {
958                                         data->reserved1 = TRACK_nZ;
959                                         data->reserved2 = UP_Y;
960                                 }
961                         }
962                 }
963                 CTX_DATA_END;
964         }
965         else if(type == 3) {
966                 bConstraint *con;
967                 bLockTrackConstraint *data;
968
969                 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
970                         if(ob!=obact) {
971                                 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
972
973                                 data = con->data;
974                                 data->tar = obact;
975                                 ob->recalc |= OB_RECALC_ALL;
976                                 
977                                 /* Lamp and Camera track differently by default */
978                                 if (ob->type == OB_LAMP || ob->type == OB_CAMERA) {
979                                         data->trackflag = TRACK_nZ;
980                                         data->lockflag = LOCK_Y;
981                                 }
982                         }
983                 }
984                 CTX_DATA_END;
985         }
986         
987         DAG_scene_sort(scene);
988         DAG_ids_flush_update(0);
989         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
990         
991         return OPERATOR_FINISHED;
992 }
993
994 void OBJECT_OT_track_set(wmOperatorType *ot)
995 {
996         /* identifiers */
997         ot->name= "Make Track";
998         ot->description = "Make the object track another object, either by constraint or old way or locked track";
999         ot->idname= "OBJECT_OT_track_set";
1000         
1001         /* api callbacks */
1002         ot->invoke= WM_menu_invoke;
1003         ot->exec= track_set_exec;
1004         
1005         ot->poll= ED_operator_scene_editable;
1006         
1007         /* flags */
1008         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1009         
1010         /* properties */
1011         ot->prop= RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", "");
1012 }
1013
1014 /************************** Move to Layer Operator *****************************/
1015
1016 static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
1017 {
1018         int values[20], a;
1019         unsigned int lay= 0;
1020
1021         if(!RNA_property_is_set(op->ptr, "layer")) {
1022                 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1023                         lay |= base->lay;
1024                 }
1025                 CTX_DATA_END;
1026
1027                 for(a=0; a<20; a++)
1028                         values[a]= (lay & (1<<a));
1029                 
1030                 RNA_boolean_set_array(op->ptr, "layer", values);
1031         }
1032         else {
1033                 RNA_boolean_get_array(op->ptr, "layer", values);
1034
1035                 for(a=0; a<20; a++)
1036                         if(values[a])
1037                                 lay |= (1 << a);
1038         }
1039
1040         return lay;
1041 }
1042
1043 static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
1044 {
1045         View3D *v3d= CTX_wm_view3d(C);
1046         if(v3d && v3d->localvd) {
1047                 return WM_operator_confirm_message(C, op, "Move from localview");
1048         }
1049         else {
1050                 move_to_layer_init(C, op);
1051                 return WM_operator_props_popup(C, op, event);
1052         }
1053 }
1054
1055 static int move_to_layer_exec(bContext *C, wmOperator *op)
1056 {
1057         Scene *scene= CTX_data_scene(C);
1058         View3D *v3d= CTX_wm_view3d(C);
1059         unsigned int lay, local;
1060         int islamp= 0;
1061         
1062         lay= move_to_layer_init(C, op);
1063         lay &= 0xFFFFFF;
1064
1065         if(lay==0) return OPERATOR_CANCELLED;
1066         
1067         if(v3d && v3d->localvd) {
1068                 /* now we can move out of localview. */
1069                 // XXX if (!okee("Move from localview")) return;
1070                 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1071                         lay= base->lay & ~v3d->lay;
1072                         base->lay= lay;
1073                         base->object->lay= lay;
1074                         base->object->flag &= ~SELECT;
1075                         base->flag &= ~SELECT;
1076                         if(base->object->type==OB_LAMP) islamp= 1;
1077                 }
1078                 CTX_DATA_END;
1079         }
1080         else {
1081                 /* normal non localview operation */
1082                 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1083                         /* upper byte is used for local view */
1084                         local= base->lay & 0xFF000000;  
1085                         base->lay= lay + local;
1086                         base->object->lay= lay;
1087                         if(base->object->type==OB_LAMP) islamp= 1;
1088                 }
1089                 CTX_DATA_END;
1090         }
1091
1092         if(islamp) reshadeall_displist(scene);  /* only frees */
1093         
1094         /* warning, active object may be hidden now */
1095         
1096         WM_event_add_notifier(C, NC_SCENE|NC_OBJECT|ND_DRAW, scene); /* is NC_SCENE needed ? */
1097         DAG_scene_sort(scene);
1098
1099         return OPERATOR_FINISHED;
1100 }
1101
1102 void OBJECT_OT_move_to_layer(wmOperatorType *ot)
1103 {
1104         /* identifiers */
1105         ot->name= "Move to Layer";
1106         ot->description = "Move the object to different layers";
1107         ot->idname= "OBJECT_OT_move_to_layer";
1108         
1109         /* api callbacks */
1110         ot->invoke= move_to_layer_invoke;
1111         ot->exec= move_to_layer_exec;
1112         ot->poll= ED_operator_scene_editable;
1113         
1114         /* flags */
1115         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1116         
1117         /* properties */
1118         RNA_def_boolean_layer_member(ot->srna, "layer", 20, NULL, "Layer", "");
1119 }
1120
1121 /************************** Link to Scene Operator *****************************/
1122
1123 void link_to_scene(unsigned short nr)
1124 {
1125 #if 0
1126         Scene *sce= (Scene*) BLI_findlink(&G.main->scene, G.curscreen->scenenr-1);
1127         Base *base, *nbase;
1128         
1129         if(sce==0) return;
1130         if(sce->id.lib) return;
1131         
1132         for(base= FIRSTBASE; base; base= base->next) {
1133                 if(TESTBASE(v3d, base)) {
1134                         
1135                         nbase= MEM_mallocN( sizeof(Base), "newbase");
1136                         *nbase= *base;
1137                         BLI_addhead( &(sce->base), nbase);
1138                         id_us_plus((ID *)base->object);
1139                 }
1140         }
1141 #endif
1142 }
1143
1144 static int make_links_scene_exec(bContext *C, wmOperator *op)
1145 {
1146         Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
1147
1148         if(scene_to==NULL) {
1149                 BKE_report(op->reports, RPT_ERROR, "Scene not found");
1150                 return OPERATOR_CANCELLED;
1151         }
1152
1153         if(scene_to == CTX_data_scene(C)) {
1154                 BKE_report(op->reports, RPT_ERROR, "Can't link objects into the same scene");
1155                 return OPERATOR_CANCELLED;
1156                 }
1157
1158         if(scene_to->id.lib) {
1159                 BKE_report(op->reports, RPT_ERROR, "Can't link objects into a linked scene");
1160                 return OPERATOR_CANCELLED;
1161         }
1162
1163         CTX_DATA_BEGIN(C, Base*, base, selected_bases)
1164         {
1165                 if(!object_in_scene(base->object, scene_to)) {
1166                         Base *nbase= MEM_mallocN( sizeof(Base), "newbase");
1167                                         *nbase= *base;
1168                         BLI_addhead( &(scene_to->base), nbase);
1169                                         id_us_plus((ID *)base->object);
1170                                 }
1171                         }
1172         CTX_DATA_END;
1173
1174         DAG_ids_flush_update(0);
1175
1176         /* one day multiple scenes will be visible, then we should have some update function for them */
1177         return OPERATOR_FINISHED;
1178 }
1179
1180 enum {
1181         MAKE_LINKS_OBDATA = 1,
1182         MAKE_LINKS_MATERIALS,
1183         MAKE_LINKS_ANIMDATA,
1184         MAKE_LINKS_DUPLIGROUP,
1185         MAKE_LINKS_MODIFIERS
1186 };
1187
1188 /* Return 1 if make link data is allow, zero otherwise */
1189 static int allow_make_links_data(int ev, Object *ob, Object *obt)
1190 {
1191         switch(ev) {
1192                 case MAKE_LINKS_OBDATA:
1193                         if (ob->type == obt->type && ob->type != OB_EMPTY)
1194                                 return 1;
1195                         break;
1196                 case MAKE_LINKS_MATERIALS:
1197                         if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL) &&
1198                                 ELEM5(obt->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL))
1199                                 return 1;
1200                         break;
1201                 case MAKE_LINKS_ANIMDATA:
1202                 case MAKE_LINKS_DUPLIGROUP:
1203                         return 1;
1204                 case MAKE_LINKS_MODIFIERS:
1205                         if (ob->type != OB_EMPTY && obt->type != OB_EMPTY)
1206                                 return 1;
1207                         break;
1208         }
1209         return 0;
1210 }
1211
1212 static int make_links_data_exec(bContext *C, wmOperator *op)
1213 {
1214         int event = RNA_int_get(op->ptr, "type");
1215         Object *ob;
1216         ID *id;
1217         int a;
1218
1219         ob= CTX_data_active_object(C);
1220
1221         CTX_DATA_BEGIN(C, Object*, obt, selected_editable_objects) {
1222                 if(ob != obt) {
1223                         if (allow_make_links_data(event, ob, obt)) {
1224                                 switch(event) {
1225                                 case MAKE_LINKS_OBDATA: /* obdata */
1226                                         id= obt->data;
1227                                         id->us--;
1228
1229                                         id= ob->data;
1230                                         id_us_plus(id);
1231                                         obt->data= id;
1232
1233                                         /* if amount of material indices changed: */
1234                                         test_object_materials(obt->data);
1235
1236                                         obt->recalc |= OB_RECALC_DATA;
1237                                         break;
1238                                 case MAKE_LINKS_MATERIALS:
1239                                         /* new approach, using functions from kernel */
1240                                         for(a=0; a<ob->totcol; a++) {
1241                                                 Material *ma= give_current_material(ob, a+1);
1242                                                 assign_material(obt, ma, a+1);  /* also works with ma==NULL */
1243                                         }
1244                                         break;
1245                                 case MAKE_LINKS_ANIMDATA:
1246                                         BKE_copy_animdata_id((ID *)obt, (ID *)ob);
1247                                         BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data);
1248                                         break;
1249                                 case MAKE_LINKS_DUPLIGROUP:
1250                                         obt->dup_group= ob->dup_group;
1251                                         if(obt->dup_group) {
1252                                                 id_lib_extern(&obt->dup_group->id);
1253                                                 obt->transflag |= OB_DUPLIGROUP;
1254                                         }
1255                                         break;
1256                                 case MAKE_LINKS_MODIFIERS:
1257                                         object_link_modifiers(obt, ob);
1258                                         obt->recalc |= OB_RECALC_ALL;
1259                                         break;
1260                                                 }
1261                         }
1262                 }
1263         }
1264         CTX_DATA_END;
1265
1266         DAG_ids_flush_update(0);
1267         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
1268         return OPERATOR_FINISHED;
1269 }
1270
1271
1272 void OBJECT_OT_make_links_scene(wmOperatorType *ot)
1273 {
1274         PropertyRNA *prop;
1275
1276         /* identifiers */
1277         ot->name= "Link Objects to Scene";
1278         ot->description = "Make linked data local to each object";
1279         ot->idname= "OBJECT_OT_make_links_scene";
1280
1281         /* api callbacks */
1282         ot->exec= make_links_scene_exec;
1283         /* better not run the poll check */
1284
1285         /* flags */
1286         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1287
1288         /* properties */
1289         prop= RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
1290         RNA_def_enum_funcs(prop, RNA_scene_local_itemf);
1291         ot->prop= prop;
1292 }
1293
1294 void OBJECT_OT_make_links_data(wmOperatorType *ot)
1295 {
1296         static EnumPropertyItem make_links_items[]= {
1297                 {MAKE_LINKS_OBDATA,             "OBDATA", 0, "Object Data", ""},
1298                 {MAKE_LINKS_MATERIALS,  "MATERIAL", 0, "Materials", ""},
1299                 {MAKE_LINKS_ANIMDATA,   "ANIMATION", 0, "Animation Data", ""},
1300                 {MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""},
1301                 {MAKE_LINKS_MODIFIERS,  "MODIFIERS", 0, "Modifiers", ""},
1302                 {0, NULL, 0, NULL, NULL}};
1303
1304         PropertyRNA *prop;
1305
1306         /* identifiers */
1307         ot->name= "Link Data";
1308         ot->description = "Make links from the active object to other selected objects";
1309         ot->idname= "OBJECT_OT_make_links_data";
1310
1311         /* api callbacks */
1312         ot->exec= make_links_data_exec;
1313         ot->poll= ED_operator_scene_editable;
1314
1315         /* flags */
1316         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1317
1318         /* properties */
1319         prop= RNA_def_enum(ot->srna, "type", make_links_items, 0, "Type", "");
1320 }
1321
1322
1323 /**************************** Make Single User ********************************/
1324
1325 static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
1326 {
1327         ID_NEW(*obpoin);
1328 }
1329
1330 void single_object_users(Scene *scene, View3D *v3d, int flag)   
1331 {
1332         Base *base;
1333         Object *ob, *obn;
1334         
1335         clear_sca_new_poins();  /* sensor/contr/act */
1336
1337         /* duplicate (must set newid) */
1338         for(base= FIRSTBASE; base; base= base->next) {
1339                 ob= base->object;
1340                 
1341                 if( (base->flag & flag)==flag ) {
1342                         if(ob->id.lib==NULL && ob->id.us>1) {
1343                                 /* base gets copy of object */
1344                                 obn= copy_object(ob);
1345                                 base->object= obn;
1346                                 ob->id.us--;
1347                         }
1348                 }
1349         }
1350         
1351         ID_NEW(scene->camera);
1352         if(v3d) ID_NEW(v3d->camera);
1353         
1354         /* object pointers */
1355         for(base= FIRSTBASE; base; base= base->next) {
1356                 ob= base->object;
1357                 if(ob->id.lib==NULL) {
1358                         relink_constraints(&base->object->constraints);
1359                         if (base->object->pose){
1360                                 bPoseChannel *chan;
1361                                 for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){
1362                                         relink_constraints(&chan->constraints);
1363                                 }
1364                         }
1365                         modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL);
1366                         
1367                         ID_NEW(ob->parent);
1368                 }
1369         }
1370
1371         set_sca_new_poins();
1372 }
1373
1374 void new_id_matar(Material **matar, int totcol)
1375 {
1376         ID *id;
1377         int a;
1378         
1379         for(a=0; a<totcol; a++) {
1380                 id= (ID *)matar[a];
1381                 if(id && id->lib==0) {
1382                         if(id->newid) {
1383                                 matar[a]= (Material *)id->newid;
1384                                 id_us_plus(id->newid);
1385                                 id->us--;
1386                         }
1387                         else if(id->us>1) {
1388                                 matar[a]= copy_material(matar[a]);
1389                                 id->us--;
1390                                 id->newid= (ID *)matar[a];
1391                         }
1392                 }
1393         }
1394 }
1395
1396 void single_obdata_users(Scene *scene, int flag)
1397 {
1398         Object *ob;
1399         Lamp *la;
1400         Curve *cu;
1401         //Camera *cam;
1402         Base *base;
1403         Mesh *me;
1404         ID *id;
1405         int a;
1406
1407         for(base= FIRSTBASE; base; base= base->next) {
1408                 ob= base->object;
1409                 if(ob->id.lib==NULL && (base->flag & flag)==flag ) {
1410                         id= ob->data;
1411                         
1412                         if(id && id->us>1 && id->lib==0) {
1413                                 ob->recalc= OB_RECALC_DATA;
1414                                 
1415                                 switch(ob->type) {
1416                                 case OB_LAMP:
1417                                         if(id && id->us>1 && id->lib==NULL) {
1418                                                 ob->data= la= copy_lamp(ob->data);
1419                                                 for(a=0; a<MAX_MTEX; a++) {
1420                                                         if(la->mtex[a]) {
1421                                                                 ID_NEW(la->mtex[a]->object);
1422                                                         }
1423                                                 }
1424                                         }
1425                                         break;
1426                                 case OB_CAMERA:
1427                                         ob->data= copy_camera(ob->data);
1428                                         break;
1429                                 case OB_MESH:
1430                                         me= ob->data= copy_mesh(ob->data);
1431                                         //if(me && me->key)
1432                                         //      ipo_idnew(me->key->ipo);        /* drivers */
1433                                         break;
1434                                 case OB_MBALL:
1435                                         ob->data= copy_mball(ob->data);
1436                                         break;
1437                                 case OB_CURVE:
1438                                 case OB_SURF:
1439                                 case OB_FONT:
1440                                         ob->data= cu= copy_curve(ob->data);
1441                                         ID_NEW(cu->bevobj);
1442                                         ID_NEW(cu->taperobj);
1443                                         break;
1444                                 case OB_LATTICE:
1445                                         ob->data= copy_lattice(ob->data);
1446                                         break;
1447                                 case OB_ARMATURE:
1448                                         ob->recalc |= OB_RECALC_DATA;
1449                                         ob->data= copy_armature(ob->data);
1450                                         armature_rebuild_pose(ob, ob->data);
1451                                         break;
1452                                 default:
1453                                         if (G.f & G_DEBUG)
1454                                                 printf("ERROR single_obdata_users: can't copy %s\n", id->name);
1455                                         return;
1456                                 }
1457                                 
1458                                 id->us--;
1459                                 id->newid= ob->data;
1460                                 
1461                         }
1462                         
1463 #if 0 // XXX old animation system
1464                         id= (ID *)ob->action;
1465                         if (id && id->us>1 && id->lib==NULL){
1466                                 if(id->newid){
1467                                         ob->action= (bAction *)id->newid;
1468                                         id_us_plus(id->newid);
1469                                 }
1470                                 else {
1471                                         ob->action= copy_action(ob->action);
1472                                         id->us--;
1473                                         id->newid=(ID *)ob->action;
1474                                 }
1475                         }
1476                         id= (ID *)ob->ipo;
1477                         if(id && id->us>1 && id->lib==NULL) {
1478                                 if(id->newid) {
1479                                         ob->ipo= (Ipo *)id->newid;
1480                                         id_us_plus(id->newid);
1481                                 }
1482                                 else {
1483                                         ob->ipo= copy_ipo(ob->ipo);
1484                                         id->us--;
1485                                         id->newid= (ID *)ob->ipo;
1486                                 }
1487                                 ipo_idnew(ob->ipo);     /* drivers */
1488                         }
1489                         /* other ipos */
1490                         switch(ob->type) {
1491                         case OB_LAMP:
1492                                 la= ob->data;
1493                                 if(la->ipo && la->ipo->id.us>1) {
1494                                         la->ipo->id.us--;
1495                                         la->ipo= copy_ipo(la->ipo);
1496                                         ipo_idnew(la->ipo);     /* drivers */
1497                                 }
1498                                 break;
1499                         case OB_CAMERA:
1500                                 cam= ob->data;
1501                                 if(cam->ipo && cam->ipo->id.us>1) {
1502                                         cam->ipo->id.us--;
1503                                         cam->ipo= copy_ipo(cam->ipo);
1504                                         ipo_idnew(cam->ipo);    /* drivers */
1505                                 }
1506                                 break;
1507                         }
1508 #endif // XXX old animation system
1509                 }
1510         }
1511         
1512         me= G.main->mesh.first;
1513         while(me) {
1514                 ID_NEW(me->texcomesh);
1515                 me= me->id.next;
1516         }
1517 }
1518
1519 void single_ipo_users(Scene *scene, int flag)
1520 {
1521 #if 0 // XXX old animation system
1522         Object *ob;
1523         Base *base;
1524         ID *id;
1525         
1526         for(base= FIRSTBASE; base; base= base->next) {
1527                 ob= base->object;
1528                 if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) {
1529                         ob->recalc= OB_RECALC_DATA;
1530                         
1531                         id= (ID *)ob->ipo;
1532                         if(id && id->us>1 && id->lib==NULL) {
1533                                 ob->ipo= copy_ipo(ob->ipo);
1534                                 id->us--;
1535                                 ipo_idnew(ob->ipo);     /* drivers */
1536                         }
1537                 }
1538         }
1539 #endif // XXX old animation system
1540 }
1541
1542 static void single_mat_users(Scene *scene, int flag, int do_textures)
1543 {
1544         Object *ob;
1545         Base *base;
1546         Material *ma, *man;
1547         Tex *tex;
1548         int a, b;
1549         
1550         for(base= FIRSTBASE; base; base= base->next) {
1551                 ob= base->object;
1552                 if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) {
1553         
1554                         for(a=1; a<=ob->totcol; a++) {
1555                                 ma= give_current_material(ob, a);
1556                                 if(ma) {
1557                                         /* do not test for LIB_NEW: this functions guaranteed delivers single_users! */
1558                                         
1559                                         if(ma->id.us>1) {
1560                                                 man= copy_material(ma);
1561                                         
1562                                                 man->id.us= 0;
1563                                                 assign_material(ob, man, a);
1564         
1565 #if 0 // XXX old animation system                                               
1566                                                 if(ma->ipo) {
1567                                                         man->ipo= copy_ipo(ma->ipo);
1568                                                         ma->ipo->id.us--;
1569                                                         ipo_idnew(ma->ipo);     /* drivers */
1570                                                 }
1571 #endif // XXX old animation system
1572                                                 if(do_textures) {
1573                                                         for(b=0; b<MAX_MTEX; b++) {
1574                                                                 if(ma->mtex[b] && ma->mtex[b]->tex) {
1575                                                                         tex= ma->mtex[b]->tex;
1576                                                                         if(tex->id.us>1) {
1577                                                                                 ma->mtex[b]->tex= copy_texture(tex);
1578                                                                                 tex->id.us--;
1579                                                                         }
1580                                                                 }
1581                                                         }
1582                                                 }
1583                                         }
1584                                 }
1585                         }
1586                 }
1587         }
1588 }
1589
1590 void do_single_tex_user(Tex **from)
1591 {
1592         Tex *tex, *texn;
1593         
1594         tex= *from;
1595         if(tex==0) return;
1596         
1597         if(tex->id.newid) {
1598                 *from= (Tex *)tex->id.newid;
1599                 id_us_plus(tex->id.newid);
1600                 tex->id.us--;
1601         }
1602         else if(tex->id.us>1) {
1603                 texn= copy_texture(tex);
1604                 tex->id.newid= (ID *)texn;
1605                 tex->id.us--;
1606                 *from= texn;
1607         }
1608 }
1609
1610 void single_tex_users_expand()
1611 {
1612         /* only when 'parent' blocks are LIB_NEW */
1613         Main *bmain= G.main;
1614         Material *ma;
1615         Lamp *la;
1616         World *wo;
1617         int b;
1618                 
1619         for(ma= bmain->mat.first; ma; ma=ma->id.next) {
1620                 if(ma->id.flag & LIB_NEW) {
1621                         for(b=0; b<MAX_MTEX; b++) {
1622                                 if(ma->mtex[b] && ma->mtex[b]->tex) {
1623                                         do_single_tex_user( &(ma->mtex[b]->tex) );
1624                                 }
1625                         }
1626                 }
1627         }
1628
1629         for(la= bmain->lamp.first; la; la=la->id.next) {
1630                 if(la->id.flag & LIB_NEW) {
1631                         for(b=0; b<MAX_MTEX; b++) {
1632                                 if(la->mtex[b] && la->mtex[b]->tex) {
1633                                         do_single_tex_user( &(la->mtex[b]->tex) );
1634                                 }
1635                         }
1636                 }
1637         }
1638
1639         for(wo= bmain->world.first; wo; wo=wo->id.next) {
1640                 if(wo->id.flag & LIB_NEW) {
1641                         for(b=0; b<MAX_MTEX; b++) {
1642                                 if(wo->mtex[b] && wo->mtex[b]->tex) {
1643                                         do_single_tex_user( &(wo->mtex[b]->tex) );
1644                                 }
1645                         }
1646                 }
1647         }
1648 }
1649
1650 static void single_mat_users_expand(void)
1651 {
1652         /* only when 'parent' blocks are LIB_NEW */
1653         Main *bmain= G.main;
1654         Object *ob;
1655         Mesh *me;
1656         Curve *cu;
1657         MetaBall *mb;
1658         Material *ma;
1659         int a;
1660         
1661         for(ob=bmain->object.first; ob; ob=ob->id.next)
1662                 if(ob->id.flag & LIB_NEW)
1663                         new_id_matar(ob->mat, ob->totcol);
1664
1665         for(me=bmain->mesh.first; me; me=me->id.next)
1666                 if(me->id.flag & LIB_NEW)
1667                         new_id_matar(me->mat, me->totcol);
1668
1669         for(cu=bmain->curve.first; cu; cu=cu->id.next)
1670                 if(cu->id.flag & LIB_NEW)
1671                         new_id_matar(cu->mat, cu->totcol);
1672
1673         for(mb=bmain->mball.first; mb; mb=mb->id.next)
1674                 if(mb->id.flag & LIB_NEW)
1675                         new_id_matar(mb->mat, mb->totcol);
1676
1677         /* material imats  */
1678         for(ma=bmain->mat.first; ma; ma=ma->id.next)
1679                 if(ma->id.flag & LIB_NEW)
1680                         for(a=0; a<MAX_MTEX; a++)
1681                                 if(ma->mtex[a])
1682                                         ID_NEW(ma->mtex[a]->object);
1683 }
1684
1685 /* used for copying scenes */
1686 void ED_object_single_users(Scene *scene, int full)
1687 {
1688         single_object_users(scene, NULL, 0);
1689
1690         if(full) {
1691                 single_obdata_users(scene, 0);
1692                 single_mat_users_expand();
1693                 single_tex_users_expand();
1694         }
1695
1696         clear_id_newpoins();
1697 }
1698
1699 /******************************* Make Local ***********************************/
1700
1701 /* helper for below, ma was checked to be not NULL */
1702 static void make_local_makelocalmaterial(Material *ma)
1703 {
1704         AnimData *adt;
1705         int b;
1706         
1707         id_make_local(&ma->id, 0);
1708         
1709         for(b=0; b<MAX_MTEX; b++)
1710                 if(ma->mtex[b] && ma->mtex[b]->tex)
1711                         id_make_local(&ma->mtex[b]->tex->id, 0);
1712         
1713         adt= BKE_animdata_from_id(&ma->id);
1714         if(adt) BKE_animdata_make_local(adt);
1715
1716         /* nodetree? XXX */
1717 }
1718
1719 static int make_local_exec(bContext *C, wmOperator *op)
1720 {
1721         AnimData *adt;
1722         ParticleSystem *psys;
1723         Material *ma, ***matarar;
1724         Lamp *la;
1725         ID *id;
1726         int a, b, mode= RNA_enum_get(op->ptr, "type");;
1727         
1728         if(mode==3) {
1729                 all_local(NULL, 0);     /* NULL is all libs */
1730                 WM_event_add_notifier(C, NC_WINDOW, NULL);
1731                 return OPERATOR_FINISHED;
1732         }
1733
1734         clear_id_newpoins();
1735         
1736         CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
1737                 if(ob->id.lib)
1738                         id_make_local(&ob->id, 0);
1739         }
1740         CTX_DATA_END;
1741         
1742         /* maybe object pointers */
1743         CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
1744                 if(ob->id.lib==NULL) {
1745                         ID_NEW(ob->parent);
1746                 }
1747         }
1748         CTX_DATA_END;
1749
1750         CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
1751                 id= ob->data;
1752                         
1753                 if(id && mode>1) {
1754                         id_make_local(id, 0);
1755                         adt= BKE_animdata_from_id(id);
1756                         if(adt) BKE_animdata_make_local(adt);
1757                 }
1758
1759                 for(psys=ob->particlesystem.first; psys; psys=psys->next)
1760                         id_make_local(&psys->part->id, 0);
1761
1762                 adt= BKE_animdata_from_id(&ob->id);
1763                 if(adt) BKE_animdata_make_local(adt);
1764         }
1765         CTX_DATA_END;
1766
1767         if(mode>1) {
1768                 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
1769                         if(ob->type==OB_LAMP) {
1770                                 la= ob->data;
1771
1772                                 for(b=0; b<MAX_MTEX; b++)
1773                                         if(la->mtex[b] && la->mtex[b]->tex)
1774                                                 id_make_local(&la->mtex[b]->tex->id, 0);
1775                         }
1776                         else {
1777                                 for(a=0; a<ob->totcol; a++) {
1778                                         ma= ob->mat[a];
1779                                         if(ma)
1780                                                 make_local_makelocalmaterial(ma);
1781                                 }
1782                                 
1783                                 matarar= (Material ***)give_matarar(ob);
1784                                 if(matarar) {
1785                                         for(a=0; a<ob->totcol; a++) {
1786                                                 ma= (*matarar)[a];
1787                                                 if(ma)
1788                                                         make_local_makelocalmaterial(ma);
1789                                         }
1790                                 }
1791                         }
1792                 }
1793                 CTX_DATA_END;
1794         }
1795
1796         WM_event_add_notifier(C, NC_WINDOW, NULL);
1797
1798         return OPERATOR_FINISHED;
1799 }
1800
1801 void OBJECT_OT_make_local(wmOperatorType *ot)
1802 {
1803         static EnumPropertyItem type_items[]= {
1804                 {1, "SELECTED_OBJECTS", 0, "Selected Objects", ""},
1805                 {2, "SELECTED_OBJECTS_DATA", 0, "Selected Objects and Data", ""},
1806                 {3, "ALL", 0, "All", ""},
1807                 {0, NULL, 0, NULL, NULL}};
1808
1809         /* identifiers */
1810         ot->name= "Make Local";
1811         ot->description = "Make library linked datablocks local to this file";
1812         ot->idname= "OBJECT_OT_make_local";
1813         
1814         /* api callbacks */
1815         ot->invoke= WM_menu_invoke;
1816         ot->exec= make_local_exec;
1817         ot->poll= ED_operator_scene_editable;
1818         
1819         /* flags */
1820         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1821         
1822         /* properties */
1823         ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
1824 }
1825
1826 static int make_single_user_exec(bContext *C, wmOperator *op)
1827 {
1828         Scene *scene= CTX_data_scene(C);
1829         View3D *v3d= CTX_wm_view3d(C); /* ok if this is NULL */
1830         int flag= RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */
1831
1832         if(RNA_boolean_get(op->ptr, "object"))
1833                 single_object_users(scene, v3d, flag);
1834
1835         if(RNA_boolean_get(op->ptr, "obdata"))
1836                 single_obdata_users(scene, flag);
1837
1838         if(RNA_boolean_get(op->ptr, "material"))
1839                 single_mat_users(scene, flag, FALSE);
1840
1841         if(RNA_boolean_get(op->ptr, "texture"))
1842                 single_mat_users(scene, flag, TRUE);
1843
1844         if(RNA_boolean_get(op->ptr, "animation"))
1845                 single_ipo_users(scene, flag);
1846
1847         clear_id_newpoins();
1848
1849         WM_event_add_notifier(C, NC_WINDOW, NULL);
1850         return OPERATOR_FINISHED;
1851 }
1852
1853 void OBJECT_OT_make_single_user(wmOperatorType *ot)
1854 {
1855         static EnumPropertyItem type_items[]= {
1856                 {SELECT, "SELECTED_OBJECTS", 0, "Selected Objects", ""},
1857                 {0, "ALL", 0, "All", ""},
1858                 {0, NULL, 0, NULL, NULL}};
1859
1860         /* identifiers */
1861         ot->name= "Make Single User";
1862         ot->description = "Make linked data local to each object";
1863         ot->idname= "OBJECT_OT_make_single_user";
1864
1865         /* api callbacks */
1866         ot->invoke= WM_menu_invoke;
1867         ot->exec= make_single_user_exec;
1868         ot->poll= ED_operator_scene_editable;
1869
1870         /* flags */
1871         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1872
1873         /* properties */
1874         ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
1875
1876         RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects");
1877         RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data");
1878         RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each datablock");
1879         RNA_def_boolean(ot->srna, "texture", 0, "Textures", "Make textures local to each material");
1880         RNA_def_boolean(ot->srna, "animation", 0, "Animation Data", "Make animation data local to each object");
1881 }
1882
1883 static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event)
1884 {
1885         Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
1886         Material *ma;
1887         char name[32];
1888         
1889         RNA_string_get(op->ptr, "name", name);
1890         ma= (Material *)find_id("MA", name);
1891         if(base==NULL || ma==NULL) 
1892                 return OPERATOR_CANCELLED;
1893         
1894         assign_material(base->object, ma, 1);
1895         
1896         DAG_ids_flush_update(0);
1897         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
1898         
1899         return OPERATOR_FINISHED;
1900 }
1901
1902 /* used for dropbox */
1903 /* assigns to object under cursor, only first material slot */
1904 void OBJECT_OT_drop_named_material(wmOperatorType *ot)
1905 {
1906
1907         /* identifiers */
1908         ot->name= "Drop Named Material on Object";
1909         ot->description = "";
1910         ot->idname= "OBJECT_OT_drop_named_material";
1911         
1912         /* api callbacks */
1913         ot->invoke= drop_named_material_invoke;
1914         ot->poll= ED_operator_scene_editable;
1915         
1916         /* flags */
1917         ot->flag= OPTYPE_UNDO;
1918         
1919         /* properties */
1920         RNA_def_string(ot->srna, "name", "Material", 24, "Name", "Material name to assign.");
1921 }