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