Blender V2.61 - r43446

object_add.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Blender Foundation, 2002-2008 full recode
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <stdlib.h>
00032 #include <string.h>
00033 
00034 #include "MEM_guardedalloc.h"
00035 
00036 #include "DNA_anim_types.h"
00037 #include "DNA_curve_types.h"
00038 #include "DNA_group_types.h"
00039 #include "DNA_lamp_types.h"
00040 #include "DNA_key_types.h"
00041 #include "DNA_material_types.h"
00042 #include "DNA_mesh_types.h"
00043 #include "DNA_meta_types.h"
00044 #include "DNA_object_fluidsim.h"
00045 #include "DNA_object_force.h"
00046 #include "DNA_scene_types.h"
00047 #include "DNA_speaker_types.h"
00048 #include "DNA_vfont_types.h"
00049 
00050 #include "BLI_ghash.h"
00051 #include "BLI_listbase.h"
00052 #include "BLI_math.h"
00053 #include "BLI_string.h"
00054 #include "BLI_utildefines.h"
00055 
00056 #include "BKE_anim.h"
00057 #include "BKE_animsys.h"
00058 #include "BKE_armature.h"
00059 #include "BKE_camera.h"
00060 #include "BKE_constraint.h"
00061 #include "BKE_context.h"
00062 #include "BKE_curve.h"
00063 #include "BKE_depsgraph.h"
00064 #include "BKE_DerivedMesh.h"
00065 #include "BKE_displist.h"
00066 #include "BKE_effect.h"
00067 #include "BKE_group.h"
00068 #include "BKE_lamp.h"
00069 #include "BKE_lattice.h"
00070 #include "BKE_library.h"
00071 #include "BKE_key.h"
00072 #include "BKE_main.h"
00073 #include "BKE_material.h"
00074 #include "BKE_mball.h"
00075 #include "BKE_mesh.h"
00076 #include "BKE_modifier.h"
00077 #include "BKE_nla.h"
00078 #include "BKE_object.h"
00079 #include "BKE_particle.h"
00080 #include "BKE_report.h"
00081 #include "BKE_sca.h"
00082 #include "BKE_scene.h"
00083 #include "BKE_speaker.h"
00084 #include "BKE_texture.h"
00085 
00086 #include "RNA_access.h"
00087 #include "RNA_define.h"
00088 #include "RNA_enum_types.h"
00089 
00090 #include "WM_api.h"
00091 #include "WM_types.h"
00092 
00093 #include "ED_armature.h"
00094 #include "ED_curve.h"
00095 #include "ED_mball.h"
00096 #include "ED_mesh.h"
00097 #include "ED_node.h"
00098 #include "ED_object.h"
00099 #include "ED_render.h"
00100 #include "ED_screen.h"
00101 #include "ED_transform.h"
00102 #include "ED_view3d.h"
00103 
00104 #include "UI_interface.h"
00105 #include "UI_resources.h"
00106 
00107 #include "object_intern.h"
00108 
00109 /************************** Exported *****************************/
00110 
00111 void ED_object_location_from_view(bContext *C, float *loc)
00112 {
00113     View3D *v3d= CTX_wm_view3d(C);
00114     Scene *scene= CTX_data_scene(C);
00115     float *cursor;
00116     
00117     cursor = give_cursor(scene, v3d);
00118 
00119     copy_v3_v3(loc, cursor);
00120 }
00121 
00122 void ED_object_rotation_from_view(bContext *C, float *rot)
00123 {
00124     RegionView3D *rv3d= CTX_wm_region_view3d(C);
00125     if(rv3d) {
00126         float quat[4];
00127         copy_qt_qt(quat, rv3d->viewquat);
00128         quat[0]= -quat[0];
00129         quat_to_eul(rot, quat);
00130     }
00131     else {
00132         zero_v3(rot);
00133     }
00134 }
00135 
00136 void ED_object_base_init_transform(bContext *C, Base *base, float *loc, float *rot)
00137 {
00138     Object *ob= base->object;
00139     Scene *scene= CTX_data_scene(C);
00140     
00141     if (!scene) return;
00142     
00143     if (loc)
00144         copy_v3_v3(ob->loc, loc);
00145     
00146     if (rot)
00147         copy_v3_v3(ob->rot, rot);
00148     
00149     where_is_object(scene, ob);
00150 }
00151 
00152 /* uses context to figure out transform for primitive */
00153 /* returns standard diameter */
00154 float ED_object_new_primitive_matrix(bContext *C, Object *obedit, float *loc, float *rot, float primmat[][4])
00155 {
00156     View3D *v3d =CTX_wm_view3d(C);
00157     float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3];
00158     
00159     unit_m4(primmat);
00160     
00161     eul_to_mat3(rmat, rot);
00162     invert_m3(rmat);
00163     
00164     /* inverse transform for initial rotation and object */
00165     copy_m3_m4(mat, obedit->obmat);
00166     mul_m3_m3m3(cmat, rmat, mat);
00167     invert_m3_m3(imat, cmat);
00168     copy_m4_m3(primmat, imat);
00169     
00170     /* center */
00171     copy_v3_v3(primmat[3], loc);
00172     sub_v3_v3v3(primmat[3], primmat[3], obedit->obmat[3]);
00173     invert_m3_m3(imat, mat);
00174     mul_m3_v3(imat, primmat[3]);
00175     
00176     if(v3d) return v3d->grid;
00177     return 1.0f;
00178 }
00179 
00180 /********************* Add Object Operator ********************/
00181 
00182 void view_align_update(struct Main *UNUSED(main), struct Scene *UNUSED(scene), struct PointerRNA *ptr)
00183 {
00184     RNA_struct_idprops_unset(ptr, "rotation");
00185 }
00186 
00187 void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode)
00188 {
00189     PropertyRNA *prop;
00190     
00191     /* note: this property gets hidden for add-camera operator */
00192     prop = RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view");
00193     RNA_def_property_update_runtime(prop, view_align_update);
00194 
00195     if(do_editmode) {
00196         prop = RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode",
00197                               "Enter editmode when adding this object");
00198         RNA_def_property_flag(prop, PROP_HIDDEN|PROP_SKIP_SAVE);
00199     }
00200     
00201     prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
00202                                    "Location for the newly added object", -FLT_MAX, FLT_MAX);
00203     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00204     prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation",
00205                                  "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f);
00206     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00207     
00208     prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", "");
00209     RNA_def_property_flag(prop, PROP_HIDDEN|PROP_SKIP_SAVE);
00210 }
00211 
00212 static void object_add_generic_invoke_options(bContext *C, wmOperator *op)
00213 {
00214     if(RNA_struct_find_property(op->ptr, "enter_editmode")) /* optional */
00215         if (!RNA_struct_property_is_set(op->ptr, "enter_editmode"))
00216             RNA_boolean_set(op->ptr, "enter_editmode", U.flag & USER_ADD_EDITMODE);
00217     
00218     if(!RNA_struct_property_is_set(op->ptr, "location")) {
00219         float loc[3];
00220         
00221         ED_object_location_from_view(C, loc);
00222         RNA_float_set_array(op->ptr, "location", loc);
00223     }
00224      
00225     if(!RNA_struct_property_is_set(op->ptr, "layers")) {
00226         View3D *v3d = CTX_wm_view3d(C);
00227         Scene *scene = CTX_data_scene(C);
00228         int a, values[20], layer;
00229 
00230         if(v3d) {
00231             layer = (v3d->scenelock && !v3d->localvd)? scene->layact: v3d->layact;
00232         }
00233         else {
00234             layer = scene->layact;
00235         }
00236 
00237         for (a=0; a<20; a++) {
00238             values[a]= (layer & (1<<a));
00239         }
00240 
00241         RNA_boolean_set_array(op->ptr, "layers", values);
00242     }
00243 }
00244 
00245 int ED_object_add_generic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00246 {
00247     object_add_generic_invoke_options(C, op);
00248     return op->type->exec(C, op);
00249 }
00250 
00251 int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float *loc,
00252     float *rot, int *enter_editmode, unsigned int *layer)
00253 {
00254     View3D *v3d = CTX_wm_view3d(C);
00255     int a, layer_values[20];
00256     int view_align;
00257     
00258     *enter_editmode = FALSE;
00259     if(RNA_struct_find_property(op->ptr, "enter_editmode") && RNA_boolean_get(op->ptr, "enter_editmode")) {
00260         *enter_editmode = TRUE;
00261     }
00262 
00263     if(RNA_struct_property_is_set(op->ptr, "layers")) {
00264         RNA_boolean_get_array(op->ptr, "layers", layer_values);
00265         *layer= 0;
00266         for(a=0; a<20; a++) {
00267             if(layer_values[a])
00268                 *layer |= (1 << a);
00269             else
00270                 *layer &= ~(1 << a);
00271         }
00272     }
00273     else {
00274         /* not set, use the scenes layers */
00275         Scene *scene = CTX_data_scene(C);
00276         *layer = scene->layact;
00277     }
00278 
00279     /* in local view we additionally add local view layers,
00280        not part of operator properties */
00281     if(v3d && v3d->localvd)
00282         *layer |= v3d->lay;
00283 
00284     if(RNA_struct_property_is_set(op->ptr, "rotation"))
00285         view_align = FALSE;
00286     else if (RNA_struct_property_is_set(op->ptr, "view_align"))
00287         view_align = RNA_boolean_get(op->ptr, "view_align");
00288     else {
00289         view_align = U.flag & USER_ADD_VIEWALIGNED;
00290         RNA_boolean_set(op->ptr, "view_align", view_align);
00291     }
00292     
00293     if (view_align) {
00294         ED_object_rotation_from_view(C, rot);
00295         RNA_float_set_array(op->ptr, "rotation", rot);
00296     }
00297     else
00298         RNA_float_get_array(op->ptr, "rotation", rot);
00299     
00300 
00301     RNA_float_get_array(op->ptr, "location", loc);
00302 
00303     if(*layer == 0) {
00304         BKE_report(op->reports, RPT_ERROR, "Property 'layer' has no values set");
00305         return 0;
00306     }
00307 
00308     return 1;
00309 }
00310 
00311 /* for object add primitive operators */
00312 /* do not call undo push in this function (users of this function have to) */
00313 Object *ED_object_add_type(bContext *C, int type, float *loc, float *rot,
00314     int enter_editmode, unsigned int layer)
00315 {
00316     Main *bmain= CTX_data_main(C);
00317     Scene *scene= CTX_data_scene(C);
00318     Object *ob;
00319     
00320     /* for as long scene has editmode... */
00321     if (CTX_data_edit_object(C)) 
00322         ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */
00323     
00324     /* deselects all, sets scene->basact */
00325     ob= add_object(scene, type);
00326     BASACT->lay = ob->lay = layer;
00327     /* editor level activate, notifiers */
00328     ED_base_object_activate(C, BASACT);
00329 
00330     /* more editor stuff */
00331     ED_object_base_init_transform(C, BASACT, loc, rot);
00332 
00333     DAG_id_type_tag(bmain, ID_OB);
00334     DAG_scene_sort(bmain, scene);
00335     if (ob->data) {
00336         ED_render_id_flush_update(bmain, ob->data);
00337     }
00338 
00339     if(enter_editmode)
00340         ED_object_enter_editmode(C, EM_IGNORE_LAYER);
00341 
00342     WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene);
00343 
00344     return ob;
00345 }
00346 
00347 /* for object add operator */
00348 static int object_add_exec(bContext *C, wmOperator *op)
00349 {
00350     int enter_editmode;
00351     unsigned int layer;
00352     float loc[3], rot[3];
00353     
00354     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00355         return OPERATOR_CANCELLED;
00356 
00357     ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer);
00358     
00359     return OPERATOR_FINISHED;
00360 }
00361 
00362 void OBJECT_OT_add(wmOperatorType *ot)
00363 {
00364     /* identifiers */
00365     ot->name= "Add Object";
00366     ot->description = "Add an object to the scene";
00367     ot->idname= "OBJECT_OT_add";
00368     
00369     /* api callbacks */
00370     ot->invoke= ED_object_add_generic_invoke;
00371     ot->exec= object_add_exec;
00372     
00373     ot->poll= ED_operator_objectmode;
00374     
00375     /* flags */
00376     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00377     
00378     RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", "");
00379 
00380     ED_object_add_generic_props(ot, TRUE);
00381 }
00382 
00383 /********************* Add Effector Operator ********************/
00384 /* copy from rna_object_force.c*/
00385 static EnumPropertyItem field_type_items[] = {
00386     {PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", ""},
00387     {PFIELD_WIND, "WIND", ICON_FORCE_WIND, "Wind", ""},
00388     {PFIELD_VORTEX, "VORTEX", ICON_FORCE_VORTEX, "Vortex", ""},
00389     {PFIELD_MAGNET, "MAGNET", ICON_FORCE_MAGNETIC, "Magnetic", ""},
00390     {PFIELD_HARMONIC, "HARMONIC", ICON_FORCE_HARMONIC, "Harmonic", ""},
00391     {PFIELD_CHARGE, "CHARGE", ICON_FORCE_CHARGE, "Charge", ""},
00392     {PFIELD_LENNARDJ, "LENNARDJ", ICON_FORCE_LENNARDJONES, "Lennard-Jones", ""},
00393     {PFIELD_TEXTURE, "TEXTURE", ICON_FORCE_TEXTURE, "Texture", ""},
00394     {PFIELD_GUIDE, "GUIDE", ICON_FORCE_CURVE, "Curve Guide", ""},
00395     {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""},
00396     {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""},
00397     {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""},
00398     {0, NULL, 0, NULL, NULL}};
00399 
00400 /* for effector add primitive operators */
00401 static Object *effector_add_type(bContext *C, wmOperator *op, int type)
00402 {
00403     Object *ob;
00404     int enter_editmode;
00405     unsigned int layer;
00406     float loc[3], rot[3];
00407     float mat[4][4];
00408     
00409     object_add_generic_invoke_options(C, op);
00410 
00411     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00412         return NULL;
00413 
00414     if(type==PFIELD_GUIDE) {
00415         ob= ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer);
00416         rename_id(&ob->id, "CurveGuide");
00417 
00418         ((Curve*)ob->data)->flag |= CU_PATH|CU_3D;
00419         ED_object_enter_editmode(C, 0);
00420         ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
00421         BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, mat, CU_NURBS|CU_PRIM_PATH, 1));
00422 
00423         if(!enter_editmode)
00424             ED_object_exit_editmode(C, EM_FREEDATA);
00425     }
00426     else {
00427         ob= ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer);
00428         rename_id(&ob->id, "Field");
00429 
00430         switch(type) {
00431             case PFIELD_WIND:
00432             case PFIELD_VORTEX:
00433                 ob->empty_drawtype = OB_SINGLE_ARROW;
00434                 break;
00435         }
00436     }
00437 
00438     ob->pd= object_add_collision_fields(type);
00439 
00440     DAG_scene_sort(CTX_data_main(C), CTX_data_scene(C));
00441 
00442     return ob;
00443 }
00444 
00445 /* for object add operator */
00446 static int effector_add_exec(bContext *C, wmOperator *op)
00447 {
00448     if(effector_add_type(C, op, RNA_enum_get(op->ptr, "type")) == NULL)
00449         return OPERATOR_CANCELLED;
00450 
00451     return OPERATOR_FINISHED;
00452 }
00453 
00454 void OBJECT_OT_effector_add(wmOperatorType *ot)
00455 {
00456     /* identifiers */
00457     ot->name= "Add Effector";
00458     ot->description = "Add an empty object with a physics effector to the scene";
00459     ot->idname= "OBJECT_OT_effector_add";
00460     
00461     /* api callbacks */
00462     ot->invoke= WM_menu_invoke;
00463     ot->exec= effector_add_exec;
00464     
00465     ot->poll= ED_operator_objectmode;
00466     
00467     /* flags */
00468     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00469     
00470     ot->prop= RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", "");
00471 
00472     ED_object_add_generic_props(ot, TRUE);
00473 }
00474 
00475 /* ***************** Add Camera *************** */
00476 
00477 static int object_camera_add_exec(bContext *C, wmOperator *op)
00478 {
00479     View3D *v3d = CTX_wm_view3d(C);
00480     Scene *scene= CTX_data_scene(C);
00481     Object *ob;
00482     int enter_editmode;
00483     unsigned int layer;
00484     float loc[3], rot[3];
00485     
00486     /* force view align for cameras */
00487     RNA_boolean_set(op->ptr, "view_align", TRUE);
00488     
00489     object_add_generic_invoke_options(C, op);
00490 
00491     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00492         return OPERATOR_CANCELLED;
00493 
00494     ob= ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer);
00495     
00496     if (v3d) {
00497         if (v3d->camera == NULL)
00498             v3d->camera = ob;
00499         if (v3d->scenelock && scene->camera==NULL) {
00500             scene->camera = ob;
00501         }
00502     }
00503 
00504     return OPERATOR_FINISHED;
00505 }
00506 
00507 void OBJECT_OT_camera_add(wmOperatorType *ot)
00508 {
00509     PropertyRNA *prop;
00510     
00511     /* identifiers */
00512     ot->name= "Add Camera";
00513     ot->description = "Add a camera object to the scene";
00514     ot->idname= "OBJECT_OT_camera_add";
00515     
00516     /* api callbacks */
00517     ot->exec= object_camera_add_exec;
00518     ot->poll= ED_operator_objectmode;
00519     
00520     /* flags */
00521     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00522         
00523     ED_object_add_generic_props(ot, TRUE);
00524     
00525     /* hide this for cameras, default */
00526     prop= RNA_struct_type_find_property(ot->srna, "view_align");
00527     RNA_def_property_flag(prop, PROP_HIDDEN);
00528 
00529 }
00530 
00531 
00532 /* ***************** add primitives *************** */
00533 static int object_metaball_add_exec(bContext *C, wmOperator *op)
00534 {
00535     Object *obedit= CTX_data_edit_object(C);
00536     /*MetaElem *elem;*/ /*UNUSED*/
00537     int newob= 0;
00538     int enter_editmode;
00539     unsigned int layer;
00540     float loc[3], rot[3];
00541     float mat[4][4];
00542     
00543     object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
00544 
00545     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00546         return OPERATOR_CANCELLED;
00547     
00548     if(obedit==NULL || obedit->type!=OB_MBALL) {
00549         obedit= ED_object_add_type(C, OB_MBALL, loc, rot, TRUE, layer);
00550         newob = 1;
00551     }
00552     else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
00553     
00554     ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
00555     
00556     /* elem= (MetaElem *) */ add_metaball_primitive(C, mat, RNA_enum_get(op->ptr, "type"), newob);
00557 
00558     /* userdef */
00559     if (newob && !enter_editmode) {
00560         ED_object_exit_editmode(C, EM_FREEDATA);
00561     }
00562     
00563     WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
00564     
00565     return OPERATOR_FINISHED;
00566 }
00567 
00568 static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00569 {
00570     Object *obedit= CTX_data_edit_object(C);
00571     uiPopupMenu *pup;
00572     uiLayout *layout;
00573 
00574     object_add_generic_invoke_options(C, op);
00575 
00576     pup= uiPupMenuBegin(C, op->type->name, ICON_NONE);
00577     layout= uiPupMenuLayout(pup);
00578     if(!obedit || obedit->type == OB_MBALL)
00579         uiItemsEnumO(layout, op->type->idname, "type");
00580     else
00581         uiItemsEnumO(layout, "OBJECT_OT_metaball_add", "type");
00582     uiPupMenuEnd(C, pup);
00583 
00584     return OPERATOR_CANCELLED;
00585 }
00586 
00587 void OBJECT_OT_metaball_add(wmOperatorType *ot)
00588 {
00589     /* identifiers */
00590     ot->name= "Add Metaball";
00591     ot->description= "Add an metaball object to the scene";
00592     ot->idname= "OBJECT_OT_metaball_add";
00593 
00594     /* api callbacks */
00595     ot->invoke= object_metaball_add_invoke;
00596     ot->exec= object_metaball_add_exec;
00597     ot->poll= ED_operator_scene_editable;
00598 
00599     /* flags */
00600     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00601     
00602     RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", "");
00603     ED_object_add_generic_props(ot, TRUE);
00604 }
00605 
00606 static int object_add_text_exec(bContext *C, wmOperator *op)
00607 {
00608     Object *obedit= CTX_data_edit_object(C);
00609     int enter_editmode;
00610     unsigned int layer;
00611     float loc[3], rot[3];
00612     
00613     object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
00614     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00615         return OPERATOR_CANCELLED;
00616     
00617     if(obedit && obedit->type==OB_FONT)
00618         return OPERATOR_CANCELLED;
00619 
00620     obedit= ED_object_add_type(C, OB_FONT, loc, rot, enter_editmode, layer);
00621     
00622     WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
00623     
00624     return OPERATOR_FINISHED;
00625 }
00626 
00627 void OBJECT_OT_text_add(wmOperatorType *ot)
00628 {
00629     /* identifiers */
00630     ot->name= "Add Text";
00631     ot->description = "Add a text object to the scene";
00632     ot->idname= "OBJECT_OT_text_add";
00633     
00634     /* api callbacks */
00635     ot->invoke= ED_object_add_generic_invoke;
00636     ot->exec= object_add_text_exec;
00637     ot->poll= ED_operator_objectmode;
00638     
00639     /* flags */
00640     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00641     ED_object_add_generic_props(ot, TRUE);
00642 }
00643 
00644 static int object_armature_add_exec(bContext *C, wmOperator *op)
00645 {
00646     Object *obedit= CTX_data_edit_object(C);
00647     View3D *v3d= CTX_wm_view3d(C);
00648     RegionView3D *rv3d= CTX_wm_region_view3d(C);
00649     int newob= 0;
00650     int enter_editmode;
00651     unsigned int layer;
00652     float loc[3], rot[3];
00653     
00654     object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
00655     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00656         return OPERATOR_CANCELLED;
00657     
00658     if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) {
00659         obedit= ED_object_add_type(C, OB_ARMATURE, loc, rot, TRUE, layer);
00660         ED_object_enter_editmode(C, 0);
00661         newob = 1;
00662     }
00663     else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
00664     
00665     if(obedit==NULL) {
00666         BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature");
00667         return OPERATOR_CANCELLED;
00668     }
00669     
00670     /* v3d and rv3d are allowed to be NULL */
00671     add_primitive_bone(CTX_data_scene(C), v3d, rv3d);
00672 
00673     /* userdef */
00674     if (newob && !enter_editmode)
00675         ED_object_exit_editmode(C, EM_FREEDATA);
00676     
00677     WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
00678     
00679     return OPERATOR_FINISHED;
00680 }
00681 
00682 void OBJECT_OT_armature_add(wmOperatorType *ot)
00683 {   
00684     /* identifiers */
00685     ot->name= "Add Armature";
00686     ot->description = "Add an armature object to the scene";
00687     ot->idname= "OBJECT_OT_armature_add";
00688     
00689     /* api callbacks */
00690     ot->invoke= ED_object_add_generic_invoke;
00691     ot->exec= object_armature_add_exec;
00692     ot->poll= ED_operator_objectmode;
00693     
00694     /* flags */
00695     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00696     ED_object_add_generic_props(ot, TRUE);
00697 }
00698 
00699 static const char *get_lamp_defname(int type)
00700 {
00701     switch (type) {
00702         case LA_LOCAL: return "Point";
00703         case LA_SUN: return "Sun";
00704         case LA_SPOT: return "Spot";
00705         case LA_HEMI: return "Hemi";
00706         case LA_AREA: return "Area";
00707         default:
00708             return "Lamp";
00709     }
00710 }
00711 
00712 static int object_lamp_add_exec(bContext *C, wmOperator *op)
00713 {
00714     Scene *scene= CTX_data_scene(C);
00715     Object *ob;
00716     Lamp *la;
00717     int type= RNA_enum_get(op->ptr, "type");
00718     int enter_editmode;
00719     unsigned int layer;
00720     float loc[3], rot[3];
00721     
00722     object_add_generic_invoke_options(C, op);
00723     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00724         return OPERATOR_CANCELLED;
00725 
00726     ob= ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer);
00727     la= (Lamp*)ob->data;
00728 
00729     la->type= type;
00730     rename_id(&ob->id, get_lamp_defname(type));
00731     rename_id(&la->id, get_lamp_defname(type));
00732 
00733     if(scene_use_new_shading_nodes(scene)) {
00734         ED_node_shader_default(scene, &la->id);
00735         la->use_nodes= 1;
00736     }
00737     
00738     return OPERATOR_FINISHED;
00739 }
00740 
00741 void OBJECT_OT_lamp_add(wmOperatorType *ot)
00742 {   
00743     static EnumPropertyItem lamp_type_items[] = {
00744         {LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source"},
00745         {LA_SUN, "SUN", ICON_LAMP_SUN, "Sun", "Constant direction parallel ray light source"},
00746         {LA_SPOT, "SPOT", ICON_LAMP_SPOT, "Spot", "Directional cone light source"},
00747         {LA_HEMI, "HEMI", ICON_LAMP_HEMI, "Hemi", "180 degree constant light source"},
00748         {LA_AREA, "AREA", ICON_LAMP_AREA, "Area", "Directional area light source"},
00749         {0, NULL, 0, NULL, NULL}};
00750 
00751     /* identifiers */
00752     ot->name= "Add Lamp";
00753     ot->description = "Add a lamp object to the scene";
00754     ot->idname= "OBJECT_OT_lamp_add";
00755     
00756     /* api callbacks */
00757     ot->invoke= WM_menu_invoke;
00758     ot->exec= object_lamp_add_exec;
00759     ot->poll= ED_operator_objectmode;
00760     
00761     /* flags */
00762     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00763 
00764     /* properties */
00765     ot->prop= RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", "");
00766 
00767     ED_object_add_generic_props(ot, FALSE);
00768 }
00769 
00770 static int group_instance_add_exec(bContext *C, wmOperator *op)
00771 {
00772     Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
00773 
00774     int enter_editmode;
00775     unsigned int layer;
00776     float loc[3], rot[3];
00777     
00778     object_add_generic_invoke_options(C, op);
00779     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00780         return OPERATOR_CANCELLED;
00781 
00782     if(group) {
00783         Main *bmain= CTX_data_main(C);
00784         Scene *scene= CTX_data_scene(C);
00785         Object *ob= ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer);
00786         rename_id(&ob->id, group->id.name+2);
00787         ob->dup_group= group;
00788         ob->transflag |= OB_DUPLIGROUP;
00789         id_lib_extern(&group->id);
00790 
00791         /* works without this except if you try render right after, see: 22027 */
00792         DAG_scene_sort(bmain, scene);
00793 
00794         WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C));
00795 
00796         return OPERATOR_FINISHED;
00797     }
00798 
00799     return OPERATOR_CANCELLED;
00800 }
00801 
00802 static int object_speaker_add_exec(bContext *C, wmOperator *op)
00803 {
00804     Object *ob;
00805     int enter_editmode;
00806     unsigned int layer;
00807     float loc[3], rot[3];
00808     Scene *scene = CTX_data_scene(C);
00809 
00810     object_add_generic_invoke_options(C, op);
00811     if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
00812         return OPERATOR_CANCELLED;
00813 
00814     ob= ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer);
00815     
00816     /* to make it easier to start using this immediately in NLA, a default sound clip is created
00817      * ready to be moved around to retime the sound and/or make new sound clips
00818      */
00819     {
00820         /* create new data for NLA hierarchy */
00821         AnimData *adt = BKE_id_add_animdata(&ob->id);
00822         NlaTrack *nlt = add_nlatrack(adt, NULL);
00823         NlaStrip *strip = add_nla_soundstrip(CTX_data_scene(C), ob->data);
00824         strip->start = CFRA;
00825         strip->end += strip->start;
00826         
00827         /* hook them up */
00828         BKE_nlatrack_add_strip(nlt, strip);
00829         
00830         /* auto-name the strip, and give the track an interesting name  */
00831         strcpy(nlt->name, "SoundTrack");
00832         BKE_nlastrip_validate_name(adt, strip);
00833         
00834         WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_EDITED, NULL);
00835     }
00836 
00837     return OPERATOR_FINISHED;
00838 }
00839 
00840 void OBJECT_OT_speaker_add(wmOperatorType *ot)
00841 {
00842     /* identifiers */
00843     ot->name= "Add Speaker";
00844     ot->description = "Add a speaker object to the scene";
00845     ot->idname= "OBJECT_OT_speaker_add";
00846 
00847     /* api callbacks */
00848     ot->exec= object_speaker_add_exec;
00849     ot->poll= ED_operator_objectmode;
00850 
00851     /* flags */
00852     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00853 
00854     ED_object_add_generic_props(ot, TRUE);
00855 }
00856 
00857 /* only used as menu */
00858 void OBJECT_OT_group_instance_add(wmOperatorType *ot)
00859 {
00860     PropertyRNA *prop;
00861 
00862     /* identifiers */
00863     ot->name= "Add Group Instance";
00864     ot->description = "Add a dupligroup instance";
00865     ot->idname= "OBJECT_OT_group_instance_add";
00866 
00867     /* api callbacks */
00868     ot->invoke= WM_enum_search_invoke;
00869     ot->exec= group_instance_add_exec;
00870 
00871     ot->poll= ED_operator_objectmode;
00872 
00873     /* flags */
00874     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00875 
00876     /* properties */
00877     prop= RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
00878     RNA_def_enum_funcs(prop, RNA_group_itemf);
00879     ot->prop= prop;
00880     ED_object_add_generic_props(ot, FALSE);
00881 }
00882 
00883 /**************************** Delete Object *************************/
00884 
00885 /* remove base from a specific scene */
00886 /* note: now unlinks constraints as well */
00887 void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
00888 {
00889     DAG_id_type_tag(bmain, ID_OB);
00890     BLI_remlink(&scene->base, base);
00891     free_libblock_us(&bmain->object, base->object);
00892     if(scene->basact==base) scene->basact= NULL;
00893     MEM_freeN(base);
00894 }
00895 
00896 static int object_delete_exec(bContext *C, wmOperator *op)
00897 {
00898     Main *bmain= CTX_data_main(C);
00899     Scene *scene= CTX_data_scene(C);
00900     const short use_global= RNA_boolean_get(op->ptr, "use_global");
00901     /* int islamp= 0; */ /* UNUSED */
00902     
00903     if(CTX_data_edit_object(C)) 
00904         return OPERATOR_CANCELLED;
00905     
00906     CTX_DATA_BEGIN(C, Base*, base, selected_bases) {
00907 
00908         /* if(base->object->type==OB_LAMP) islamp= 1; */
00909 
00910         /* deselect object -- it could be used in other scenes */
00911         base->object->flag &= ~SELECT;
00912 
00913         /* remove from current scene only */
00914         ED_base_object_free_and_unlink(bmain, scene, base);
00915 
00916         if (use_global) {
00917             Scene *scene_iter;
00918             Base *base_other;
00919 
00920             for (scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
00921                 if (scene_iter != scene && !(scene_iter->id.lib)) {
00922                     base_other= object_in_scene(base->object, scene_iter);
00923                     if (base_other) {
00924                         ED_base_object_free_and_unlink(bmain, scene_iter, base_other);
00925                     }
00926                 }
00927             }
00928         }
00929         /* end global */
00930 
00931     }
00932     CTX_DATA_END;
00933 
00934     DAG_scene_sort(bmain, scene);
00935     DAG_ids_flush_update(bmain, 0);
00936     
00937     WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
00938     WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene);
00939     
00940     return OPERATOR_FINISHED;
00941 }
00942 
00943 void OBJECT_OT_delete(wmOperatorType *ot)
00944 {
00945     /* identifiers */
00946     ot->name= "Delete";
00947     ot->description = "Delete selected objects";
00948     ot->idname= "OBJECT_OT_delete";
00949     
00950     /* api callbacks */
00951     ot->invoke= WM_operator_confirm;
00952     ot->exec= object_delete_exec;
00953     ot->poll= ED_operator_objectmode;
00954     
00955     /* flags */
00956     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00957 
00958     RNA_def_boolean(ot->srna, "use_global", 0, "Delete Globally", "Remove object from all scenes");
00959 }
00960 
00961 /**************************** Copy Utilities ******************************/
00962 
00963 /* after copying objects, copied data should get new pointers */
00964 static void copy_object_set_idnew(bContext *C, int dupflag)
00965 {
00966     Main *bmain= CTX_data_main(C);
00967     Material *ma, *mao;
00968     ID *id;
00969     int a;
00970     
00971     /* XXX check object pointers */
00972     CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
00973         object_relink(ob);
00974     }
00975     CTX_DATA_END;
00976     
00977     /* materials */
00978     if( dupflag & USER_DUP_MAT) {
00979         mao= bmain->mat.first;
00980         while(mao) {
00981             if(mao->id.newid) {
00982                 
00983                 ma= (Material *)mao->id.newid;
00984                 
00985                 if(dupflag & USER_DUP_TEX) {
00986                     for(a=0; a<MAX_MTEX; a++) {
00987                         if(ma->mtex[a]) {
00988                             id= (ID *)ma->mtex[a]->tex;
00989                             if(id) {
00990                                 ID_NEW_US(ma->mtex[a]->tex)
00991                                 else ma->mtex[a]->tex= copy_texture(ma->mtex[a]->tex);
00992                                 id->us--;
00993                             }
00994                         }
00995                     }
00996                 }
00997 #if 0 // XXX old animation system
00998                 id= (ID *)ma->ipo;
00999                 if(id) {
01000                     ID_NEW_US(ma->ipo)
01001                     else ma->ipo= copy_ipo(ma->ipo);
01002                     id->us--;
01003                 }
01004 #endif // XXX old animation system
01005             }
01006             mao= mao->id.next;
01007         }
01008     }
01009     
01010 #if 0 // XXX old animation system
01011     /* lamps */
01012     if( dupflag & USER_DUP_IPO) {
01013         Lamp *la= bmain->lamp.first;
01014         while(la) {
01015             if(la->id.newid) {
01016                 Lamp *lan= (Lamp *)la->id.newid;
01017                 id= (ID *)lan->ipo;
01018                 if(id) {
01019                     ID_NEW_US(lan->ipo)
01020                     else lan->ipo= copy_ipo(lan->ipo);
01021                     id->us--;
01022                 }
01023             }
01024             la= la->id.next;
01025         }
01026     }
01027     
01028     /* ipos */
01029     ipo= bmain->ipo.first;
01030     while(ipo) {
01031         if(ipo->id.lib==NULL && ipo->id.newid) {
01032             Ipo *ipon= (Ipo *)ipo->id.newid;
01033             IpoCurve *icu;
01034             for(icu= ipon->curve.first; icu; icu= icu->next) {
01035                 if(icu->driver) {
01036                     ID_NEW(icu->driver->ob);
01037                 }
01038             }
01039         }
01040         ipo= ipo->id.next;
01041     }
01042 #endif // XXX old animation system
01043     
01044     set_sca_new_poins();
01045     
01046     clear_id_newpoins();
01047 }
01048 
01049 /********************* Make Duplicates Real ************************/
01050 
01051 static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
01052                                        const short use_base_parent,
01053                                        const short use_hierarchy)
01054 {
01055     ListBase *lb;
01056     DupliObject *dob;
01057     GHash *dupli_gh= NULL, *parent_gh= NULL;
01058     
01059     if(!(base->object->transflag & OB_DUPLI))
01060         return;
01061     
01062     lb= object_duplilist(scene, base->object);
01063 
01064     if(use_hierarchy || use_base_parent) {
01065         dupli_gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_object_duplilist_real dupli_gh");
01066         parent_gh= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "make_object_duplilist_real parent_gh");
01067     }
01068     
01069     for(dob= lb->first; dob; dob= dob->next) {
01070         Base *basen;
01071         Object *ob= copy_object(dob->ob);
01072         /* font duplis can have a totcol without material, we get them from parent
01073         * should be implemented better...
01074         */
01075         if(ob->mat==NULL) ob->totcol= 0;
01076         
01077         basen= MEM_dupallocN(base);
01078         basen->flag &= ~(OB_FROMDUPLI|OB_FROMGROUP);
01079         ob->flag= basen->flag;
01080         basen->lay= base->lay;
01081         BLI_addhead(&scene->base, basen);   /* addhead: othwise eternal loop */
01082         basen->object= ob;
01083         
01084         /* make sure apply works */
01085         BKE_free_animdata(&ob->id); 
01086         ob->adt = NULL;
01087         
01088         ob->parent= NULL;
01089         ob->constraints.first= ob->constraints.last= NULL;
01090         ob->disp.first= ob->disp.last= NULL;
01091         ob->transflag &= ~OB_DUPLI; 
01092         ob->lay= base->lay;
01093         
01094         copy_m4_m4(ob->obmat, dob->mat);
01095         object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
01096 
01097         if(dupli_gh)
01098             BLI_ghash_insert(dupli_gh, dob, ob);
01099         if(parent_gh)
01100             BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, dob->index), ob);
01101     }
01102     
01103     if (use_hierarchy) {
01104         for(dob= lb->first; dob; dob= dob->next) {
01105             /* original parents */
01106             Object *ob_src=     dob->ob;
01107             Object *ob_src_par= ob_src->parent;
01108 
01109             Object *ob_dst=     BLI_ghash_lookup(dupli_gh, dob);
01110             Object *ob_dst_par= NULL;
01111 
01112             /* find parent that was also made real */
01113             if(ob_src_par) {
01114                 GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, dob->index);
01115                 ob_dst_par = BLI_ghash_lookup(parent_gh, pair);
01116                 BLI_ghashutil_pairfree(pair);
01117             }
01118 
01119             if (ob_dst_par) {
01120                 /* allow for all possible parent types */
01121                 ob_dst->partype= ob_src->partype;
01122                 BLI_strncpy(ob_dst->parsubstr, ob_src->parsubstr, sizeof(ob_dst->parsubstr));
01123                 ob_dst->par1= ob_src->par1;
01124                 ob_dst->par2= ob_src->par2;
01125                 ob_dst->par3= ob_src->par3;
01126 
01127                 copy_m4_m4(ob_dst->parentinv, ob_src->parentinv);
01128 
01129                 ob_dst->parent= ob_dst_par;
01130             }
01131             else if (use_base_parent) {
01132                 ob_dst->parent= base->object;
01133                 ob_dst->partype= PAROBJECT;
01134             }
01135 
01136             if (ob_dst->parent) {
01137                 invert_m4_m4(ob_dst->parentinv, dob->mat);
01138 
01139                 /* note, this may be the parent of other objects, but it should
01140                  * still work out ok */
01141                 object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE);
01142 
01143                 /* to set ob_dst->orig and incase theres any other discrepicies */
01144                 DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
01145             }
01146         }
01147     }
01148     else if (use_base_parent) {
01149         /* since we are ignoring the internal hierarchy - parent all to the
01150          * base object */
01151         for(dob= lb->first; dob; dob= dob->next) {
01152             /* original parents */
01153             Object *ob_dst= BLI_ghash_lookup(dupli_gh, dob);
01154 
01155             ob_dst->parent= base->object;
01156             ob_dst->partype= PAROBJECT;
01157 
01158             /* similer to the code above, see comments */
01159             invert_m4_m4(ob_dst->parentinv, dob->mat);
01160             object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE);
01161             DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
01162 
01163 
01164         }
01165     }
01166 
01167     if(dupli_gh)
01168         BLI_ghash_free(dupli_gh, NULL, NULL);
01169     if(parent_gh)
01170         BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL);
01171 
01172     copy_object_set_idnew(C, 0);
01173     
01174     free_object_duplilist(lb);
01175     
01176     base->object->transflag &= ~OB_DUPLI;
01177 }
01178 
01179 static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
01180 {
01181     Main *bmain= CTX_data_main(C);
01182     Scene *scene= CTX_data_scene(C);
01183 
01184     const short use_base_parent= RNA_boolean_get(op->ptr, "use_base_parent");
01185     const short use_hierarchy= RNA_boolean_get(op->ptr, "use_hierarchy");
01186     
01187     clear_id_newpoins();
01188         
01189     CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
01190         make_object_duplilist_real(C, scene, base, use_base_parent, use_hierarchy);
01191 
01192         /* dependencies were changed */
01193         WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, base->object);
01194     }
01195     CTX_DATA_END;
01196 
01197     DAG_scene_sort(bmain, scene);
01198     DAG_ids_flush_update(bmain, 0);
01199     WM_event_add_notifier(C, NC_SCENE, scene);
01200     WM_main_add_notifier(NC_OBJECT|ND_DRAW, NULL);
01201     
01202     return OPERATOR_FINISHED;
01203 }
01204 
01205 void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
01206 {
01207     
01208     /* identifiers */
01209     ot->name= "Make Duplicates Real";
01210     ot->description = "Make dupli objects attached to this object real";
01211     ot->idname= "OBJECT_OT_duplicates_make_real";
01212     
01213     /* api callbacks */
01214     ot->exec= object_duplicates_make_real_exec;
01215     
01216     ot->poll= ED_operator_objectmode;
01217     
01218     /* flags */
01219     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01220 
01221     RNA_def_boolean(ot->srna, "use_base_parent", 0, "Parent", "Parent newly created objects to the original duplicator");
01222     RNA_def_boolean(ot->srna, "use_hierarchy", 0, "Keep Hierarchy", "Maintain parent child relationships");
01223 }
01224 
01225 /**************************** Convert **************************/
01226 
01227 static EnumPropertyItem convert_target_items[]= {
01228     {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""},
01229     {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text", ""},
01230     {0, NULL, 0, NULL, NULL}};
01231 
01232 static void curvetomesh(Scene *scene, Object *ob) 
01233 {
01234     if(ob->disp.first == NULL)
01235         makeDispListCurveTypes(scene, ob, 0); /* force creation */
01236 
01237     nurbs_to_mesh(ob); /* also does users */
01238 
01239     if(ob->type == OB_MESH)
01240         object_free_modifiers(ob);
01241 }
01242 
01243 static int convert_poll(bContext *C)
01244 {
01245     Object *obact= CTX_data_active_object(C);
01246     Scene *scene= CTX_data_scene(C);
01247 
01248     return (!scene->id.lib && obact && scene->obedit != obact && (obact->flag & SELECT) && !(obact->id.lib));
01249 }
01250 
01251 /* Helper for convert_exec */
01252 static Base *duplibase_for_convert(Scene *scene, Base *base, Object *ob)
01253 {
01254     Object *obn;
01255     Base *basen;
01256 
01257     if (ob == NULL) {
01258         ob= base->object;
01259     }
01260 
01261     obn= copy_object(ob);
01262     obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
01263 
01264     basen= MEM_mallocN(sizeof(Base), "duplibase");
01265     *basen= *base;
01266     BLI_addhead(&scene->base, basen);   /* addhead: otherwise eternal loop */
01267     basen->object= obn;
01268     basen->flag |= SELECT;
01269     obn->flag |= SELECT;
01270     base->flag &= ~SELECT;
01271     ob->flag &= ~SELECT;
01272 
01273     return basen;
01274 }
01275 
01276 static int convert_exec(bContext *C, wmOperator *op)
01277 {
01278     Main *bmain= CTX_data_main(C);
01279     Scene *scene= CTX_data_scene(C);
01280     Base *basen=NULL, *basact=NULL, *basedel=NULL;
01281     Object *ob, *ob1, *newob, *obact= CTX_data_active_object(C);
01282     DerivedMesh *dm;
01283     Curve *cu;
01284     Nurb *nu;
01285     MetaBall *mb;
01286     Mesh *me;
01287     const short target= RNA_enum_get(op->ptr, "target");
01288     const short keep_original= RNA_boolean_get(op->ptr, "keep_original");
01289     int a, mballConverted= 0;
01290 
01291     /* don't forget multiple users! */
01292 
01293     /* reset flags */
01294     CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
01295         ob= base->object;
01296         ob->flag &= ~OB_DONE;
01297 
01298         /* flag data thats not been edited (only needed for !keep_original) */
01299         if(ob->data) {
01300             ((ID *)ob->data)->flag |= LIB_DOIT;
01301         }
01302     }
01303     CTX_DATA_END;
01304 
01305     CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
01306         ob= base->object;
01307 
01308         if(ob->flag & OB_DONE || !IS_TAGGED(ob->data)) {
01309             if (ob->type != target) {
01310                 base->flag &= ~SELECT;
01311                 ob->flag &= ~SELECT;
01312             }
01313 
01314             /* obdata already modified */
01315             if(!IS_TAGGED(ob->data)) {
01316                 /* When 2 objects with linked data are selected, converting both
01317                  * would keep modifiers on all but the converted object [#26003] */
01318                 if(ob->type == OB_MESH) {
01319                     object_free_modifiers(ob);  /* after derivedmesh calls! */
01320                 }
01321             }
01322         }
01323         else if (ob->type==OB_MESH && target == OB_CURVE) {
01324             ob->flag |= OB_DONE;
01325 
01326             if (keep_original) {
01327                 basen= duplibase_for_convert(scene, base, NULL);
01328                 newob= basen->object;
01329 
01330                 /* decrement original mesh's usage count  */
01331                 me= newob->data;
01332                 me->id.us--;
01333 
01334                 /* make a new copy of the mesh */
01335                 newob->data= copy_mesh(me);
01336             } else {
01337                 newob = ob;
01338             }
01339 
01340             mesh_to_curve(scene, newob);
01341 
01342             if(newob->type==OB_CURVE)
01343                 object_free_modifiers(newob);   /* after derivedmesh calls! */
01344         }
01345         else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */
01346             ob->flag |= OB_DONE;
01347 
01348             if (keep_original) {
01349                 basen= duplibase_for_convert(scene, base, NULL);
01350                 newob= basen->object;
01351 
01352                 /* decrement original mesh's usage count  */
01353                 me= newob->data;
01354                 me->id.us--;
01355 
01356                 /* make a new copy of the mesh */
01357                 newob->data= copy_mesh(me);
01358             } else {
01359                 newob = ob;
01360                 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
01361             }
01362 
01363             /* make new mesh data from the original copy */
01364             /* note: get the mesh from the original, not from the copy in some
01365              * cases this doesnt give correct results (when MDEF is used for eg)
01366              */
01367             dm= mesh_get_derived_final(scene, newob, CD_MASK_MESH);
01368             /* dm= mesh_create_derived_no_deform(ob1, NULL);    this was called original (instead of get_derived). man o man why! (ton) */
01369 
01370             DM_to_mesh(dm, newob->data);
01371 
01372             dm->release(dm);
01373             object_free_modifiers(newob);   /* after derivedmesh calls! */
01374         }
01375         else if(ob->type==OB_FONT) {
01376             ob->flag |= OB_DONE;
01377 
01378             if (keep_original) {
01379                 basen= duplibase_for_convert(scene, base, NULL);
01380                 newob= basen->object;
01381 
01382                 /* decrement original curve's usage count  */
01383                 ((Curve *)newob->data)->id.us--;
01384 
01385                 /* make a new copy of the curve */
01386                 newob->data= copy_curve(ob->data);
01387             } else {
01388                 newob= ob;
01389             }
01390 
01391             cu= newob->data;
01392 
01393             if (!newob->disp.first)
01394                 makeDispListCurveTypes(scene, newob, 0);
01395 
01396             newob->type= OB_CURVE;
01397             cu->type= OB_CURVE;
01398 
01399             if(cu->vfont) {
01400                 cu->vfont->id.us--;
01401                 cu->vfont= NULL;
01402             }
01403             if(cu->vfontb) {
01404                 cu->vfontb->id.us--;
01405                 cu->vfontb= NULL;
01406             }
01407             if(cu->vfonti) {
01408                 cu->vfonti->id.us--;
01409                 cu->vfonti= NULL;
01410             }
01411             if(cu->vfontbi) {
01412                 cu->vfontbi->id.us--;
01413                 cu->vfontbi= NULL;
01414             }
01415 
01416             if (!keep_original) {
01417                 /* other users */
01418                 if(cu->id.us>1) {
01419                     for(ob1= bmain->object.first; ob1; ob1=ob1->id.next) {
01420                         if(ob1->data==ob->data) {
01421                             ob1->type= OB_CURVE;
01422                             ob1->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
01423                         }
01424                     }
01425                 }
01426             }
01427 
01428             for(nu=cu->nurb.first; nu; nu=nu->next)
01429                 nu->charidx= 0;
01430 
01431             if(target == OB_MESH) {
01432                 curvetomesh(scene, newob);
01433 
01434                 /* meshes doesn't use displist */
01435                 freedisplist(&newob->disp);
01436             }
01437         }
01438         else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
01439             ob->flag |= OB_DONE;
01440 
01441             if(target == OB_MESH) {
01442                 if (keep_original) {
01443                     basen= duplibase_for_convert(scene, base, NULL);
01444                     newob= basen->object;
01445 
01446                     /* decrement original curve's usage count  */
01447                     ((Curve *)newob->data)->id.us--;
01448 
01449                     /* make a new copy of the curve */
01450                     newob->data= copy_curve(ob->data);
01451                 } else {
01452                     newob= ob;
01453 
01454                     /* meshes doesn't use displist */
01455                     freedisplist(&newob->disp);
01456                 }
01457 
01458                 curvetomesh(scene, newob);
01459             }
01460         }
01461         else if(ob->type==OB_MBALL && target == OB_MESH) {
01462             Object *baseob;
01463 
01464             base->flag &= ~SELECT;
01465             ob->flag &= ~SELECT;
01466 
01467             baseob= find_basis_mball(scene, ob);
01468 
01469             if (ob != baseob) {
01470                 /* if motherball is converting it would be marked as done later */
01471                 ob->flag |= OB_DONE;
01472             }
01473 
01474             if (!baseob->disp.first) {
01475                 makeDispListMBall(scene, baseob);
01476             }
01477 
01478             if(!(baseob->flag & OB_DONE)) {
01479                 baseob->flag |= OB_DONE;
01480 
01481                 basen= duplibase_for_convert(scene, base, baseob);
01482                 newob= basen->object;
01483 
01484                 mb= newob->data;
01485                 mb->id.us--;
01486 
01487                 newob->data= add_mesh("Mesh");
01488                 newob->type= OB_MESH;
01489 
01490                 me= newob->data;
01491                 me->totcol= mb->totcol;
01492                 if(newob->totcol) {
01493                     me->mat= MEM_dupallocN(mb->mat);
01494                     for(a=0; a<newob->totcol; a++) id_us_plus((ID *)me->mat[a]);
01495                 }
01496 
01497                 mball_to_mesh(&baseob->disp, newob->data);
01498 
01499                 if (obact->type == OB_MBALL) {
01500                     basact= basen;
01501                 }
01502 
01503                 mballConverted= 1;
01504             }
01505         }
01506         else {
01507             continue;
01508         }
01509 
01510         /* tag obdata if it was been changed */
01511 
01512         /* If the original object is active then make this object active */
01513         if(basen) {
01514             if(ob == obact) {
01515                 /* store new active base to update BASACT */
01516                 basact= basen;
01517             }
01518 
01519             basen= NULL;
01520         }
01521 
01522         if (!keep_original && (ob->flag & OB_DONE)) {
01523             DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01524             ((ID *)ob->data)->flag &= ~LIB_DOIT; /* flag not to convert this datablock again */
01525         }
01526 
01527         /* delete original if needed */
01528         if(basedel) {
01529             if(!keep_original)
01530                 ED_base_object_free_and_unlink(bmain, scene, basedel);  
01531 
01532             basedel = NULL;
01533         }
01534     }
01535     CTX_DATA_END;
01536 
01537     if(!keep_original) {
01538         if (mballConverted) {
01539             Base *base= scene->base.first, *tmpbase;
01540             while (base) {
01541                 ob= base->object;
01542                 tmpbase= base;
01543                 base= base->next;
01544 
01545                 if (ob->type == OB_MBALL) {
01546                     ED_base_object_free_and_unlink(bmain, scene, tmpbase);
01547                 }
01548             }
01549         }
01550 
01551         /* delete object should renew depsgraph */
01552         DAG_scene_sort(bmain, scene);
01553     }
01554 
01555 // XXX  ED_object_enter_editmode(C, 0);
01556 // XXX  exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
01557 
01558     if (basact) {
01559         /* active base was changed */
01560         ED_base_object_activate(C, basact);
01561         BASACT= basact;
01562     } else if (BASACT->object->flag & OB_DONE) {
01563         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, BASACT->object);
01564         WM_event_add_notifier(C, NC_OBJECT|ND_DATA, BASACT->object);
01565     }
01566 
01567     DAG_scene_sort(bmain, scene);
01568     WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, scene);
01569     WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
01570 
01571     return OPERATOR_FINISHED;
01572 }
01573 
01574 
01575 void OBJECT_OT_convert(wmOperatorType *ot)
01576 {
01577     /* identifiers */
01578     ot->name= "Convert to";
01579     ot->description = "Convert selected objects to another type";
01580     ot->idname= "OBJECT_OT_convert";
01581     
01582     /* api callbacks */
01583     ot->invoke= WM_menu_invoke;
01584     ot->exec= convert_exec;
01585     ot->poll= convert_poll;
01586     
01587     /* flags */
01588     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01589 
01590     /* properties */
01591     ot->prop= RNA_def_enum(ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to");
01592     RNA_def_boolean(ot->srna, "keep_original", 0, "Keep Original", "Keep original objects instead of replacing them");
01593 }
01594 
01595 /**************************** Duplicate ************************/
01596 
01597 /* 
01598     dupflag: a flag made from constants declared in DNA_userdef_types.h
01599     The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data.
01600     U.dupflag for default operations or you can construct a flag as python does
01601     if the dupflag is 0 then no data will be copied (linked duplicate) */
01602 
01603 /* used below, assumes id.new is correct */
01604 /* leaves selection of base/object unaltered */
01605 static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
01606 {
01607     Base *basen= NULL;
01608     Material ***matarar;
01609     Object *ob, *obn;
01610     ID *id;
01611     int a, didit;
01612 
01613     ob= base->object;
01614     if(ob->mode & OB_MODE_POSE) {
01615         ; /* nothing? */
01616     }
01617     else {
01618         obn= copy_object(ob);
01619         obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
01620         
01621         basen= MEM_mallocN(sizeof(Base), "duplibase");
01622         *basen= *base;
01623         BLI_addhead(&scene->base, basen);   /* addhead: prevent eternal loop */
01624         basen->object= obn;
01625         
01626         if(basen->flag & OB_FROMGROUP) {
01627             Group *group;
01628             for(group= bmain->group.first; group; group= group->id.next) {
01629                 if(object_in_group(ob, group))
01630                     add_to_group(group, obn, scene, basen);
01631             }
01632         }
01633         
01634         /* duplicates using userflags */
01635         if(dupflag & USER_DUP_ACT) {
01636             BKE_copy_animdata_id_action(&obn->id);
01637         }
01638         
01639         if(dupflag & USER_DUP_MAT) {
01640             for(a=0; a<obn->totcol; a++) {
01641                 id= (ID *)obn->mat[a];
01642                 if(id) {
01643                     ID_NEW_US(obn->mat[a])
01644                     else obn->mat[a]= copy_material(obn->mat[a]);
01645                     id->us--;
01646                     
01647                     if(dupflag & USER_DUP_ACT) {
01648                         BKE_copy_animdata_id_action(&obn->mat[a]->id);
01649                     }
01650                 }
01651             }
01652         }
01653         if(dupflag & USER_DUP_PSYS) {
01654             ParticleSystem *psys;
01655             for(psys=obn->particlesystem.first; psys; psys=psys->next) {
01656                 id= (ID*) psys->part;
01657                 if(id) {
01658                     ID_NEW_US(psys->part)
01659                     else psys->part= psys_copy_settings(psys->part);
01660                     
01661                     if(dupflag & USER_DUP_ACT) {
01662                         BKE_copy_animdata_id_action(&psys->part->id);
01663                     }
01664 
01665                     id->us--;
01666                 }
01667             }
01668         }
01669         
01670         id= obn->data;
01671         didit= 0;
01672         
01673         switch(obn->type) {
01674             case OB_MESH:
01675                 if(dupflag & USER_DUP_MESH) {
01676                     ID_NEW_US2( obn->data )
01677                     else {
01678                         obn->data= copy_mesh(obn->data);
01679                         
01680                         if(obn->fluidsimSettings) {
01681                             obn->fluidsimSettings->orgMesh = (Mesh *)obn->data;
01682                         }
01683                         
01684                         didit= 1;
01685                     }
01686                     id->us--;
01687                 }
01688                 break;
01689             case OB_CURVE:
01690                 if(dupflag & USER_DUP_CURVE) {
01691                     ID_NEW_US2(obn->data )
01692                     else {
01693                         obn->data= copy_curve(obn->data);
01694                         didit= 1;
01695                     }
01696                     id->us--;
01697                 }
01698                 break;
01699             case OB_SURF:
01700                 if(dupflag & USER_DUP_SURF) {
01701                     ID_NEW_US2( obn->data )
01702                     else {
01703                         obn->data= copy_curve(obn->data);
01704                         didit= 1;
01705                     }
01706                     id->us--;
01707                 }
01708                 break;
01709             case OB_FONT:
01710                 if(dupflag & USER_DUP_FONT) {
01711                     ID_NEW_US2( obn->data )
01712                     else {
01713                         obn->data= copy_curve(obn->data);
01714                         didit= 1;
01715                     }
01716                     id->us--;
01717                 }
01718                 break;
01719             case OB_MBALL:
01720                 if(dupflag & USER_DUP_MBALL) {
01721                     ID_NEW_US2(obn->data )
01722                     else {
01723                         obn->data= copy_mball(obn->data);
01724                         didit= 1;
01725                     }
01726                     id->us--;
01727                 }
01728                 break;
01729             case OB_LAMP:
01730                 if(dupflag & USER_DUP_LAMP) {
01731                     ID_NEW_US2(obn->data )
01732                     else {
01733                         obn->data= copy_lamp(obn->data);
01734                         didit= 1;
01735                     }
01736                     id->us--;
01737                 }
01738                 break;
01739                 
01740             case OB_ARMATURE:
01741                 obn->recalc |= OB_RECALC_DATA;
01742                 if(obn->pose) obn->pose->flag |= POSE_RECALC;
01743                     
01744                     if(dupflag & USER_DUP_ARM) {
01745                         ID_NEW_US2(obn->data )
01746                         else {
01747                             obn->data= copy_armature(obn->data);
01748                             armature_rebuild_pose(obn, obn->data);
01749                             didit= 1;
01750                         }
01751                         id->us--;
01752                     }
01753                         
01754                         break;
01755                 
01756             case OB_LATTICE:
01757                 if(dupflag!=0) {
01758                     ID_NEW_US2(obn->data )
01759                     else {
01760                         obn->data= copy_lattice(obn->data);
01761                         didit= 1;
01762                     }
01763                     id->us--;
01764                 }
01765                 break;
01766             case OB_CAMERA:
01767                 if(dupflag!=0) {
01768                     ID_NEW_US2(obn->data )
01769                     else {
01770                         obn->data= copy_camera(obn->data);
01771                         didit= 1;
01772                     }
01773                     id->us--;
01774                 }
01775                 break;
01776             case OB_SPEAKER:
01777                 if(dupflag!=0) {
01778                     ID_NEW_US2(obn->data )
01779                     else {
01780                         obn->data= copy_speaker(obn->data);
01781                         didit= 1;
01782                     }
01783                     id->us--;
01784                 }
01785                 break;
01786 
01787         }
01788 
01789         /* check if obdata is copied */
01790         if(didit) {
01791             Key *key = ob_get_key(obn);
01792             
01793             if(dupflag & USER_DUP_ACT) {
01794                 BKE_copy_animdata_id_action((ID *)obn->data);
01795                 if(key) BKE_copy_animdata_id_action((ID*)key);
01796             }
01797             
01798             if(dupflag & USER_DUP_MAT) {
01799                 matarar= give_matarar(obn);
01800                 if(matarar) {
01801                     for(a=0; a<obn->totcol; a++) {
01802                         id= (ID *)(*matarar)[a];
01803                         if(id) {
01804                             ID_NEW_US( (*matarar)[a] )
01805                             else (*matarar)[a]= copy_material((*matarar)[a]);
01806                             
01807                             id->us--;
01808                         }
01809                     }
01810                 }
01811             }
01812         }
01813     }
01814     return basen;
01815 }
01816 
01817 /* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
01818 /* leaves selection of base/object unaltered.
01819  * note: don't call this within a loop since clear_* funcs loop over the entire database. */
01820 Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
01821 {
01822     Base *basen;
01823     Object *ob;
01824 
01825     clear_id_newpoins();
01826     clear_sca_new_poins();  /* sensor/contr/act */
01827 
01828     basen= object_add_duplicate_internal(bmain, scene, base, dupflag);
01829     if (basen == NULL) {
01830         return NULL;
01831     }
01832 
01833     ob= basen->object;
01834 
01835     /* link own references to the newly duplicated data [#26816] */
01836     object_relink(ob);
01837     set_sca_new_poins_ob(ob);
01838 
01839     DAG_scene_sort(bmain, scene);
01840     if (ob->data) {
01841         ED_render_id_flush_update(bmain, ob->data);
01842     }
01843 
01844     return basen;
01845 }
01846 
01847 /* contextual operator dupli */
01848 static int duplicate_exec(bContext *C, wmOperator *op)
01849 {
01850     Main *bmain= CTX_data_main(C);
01851     Scene *scene= CTX_data_scene(C);
01852     int linked= RNA_boolean_get(op->ptr, "linked");
01853     int dupflag= (linked)? 0: U.dupflag;
01854     
01855     clear_id_newpoins();
01856     clear_sca_new_poins();  /* sensor/contr/act */
01857     
01858     CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
01859         Base *basen= object_add_duplicate_internal(bmain, scene, base, dupflag);
01860         
01861         /* note that this is safe to do with this context iterator,
01862            the list is made in advance */
01863         ED_base_object_select(base, BA_DESELECT);
01864 
01865         if (basen == NULL) {
01866             continue;
01867         }
01868 
01869         /* new object becomes active */
01870         if(BASACT==base)
01871             ED_base_object_activate(C, basen);
01872 
01873         if(basen->object->data) {
01874             DAG_id_tag_update(basen->object->data, 0);
01875         }
01876     }
01877     CTX_DATA_END;
01878 
01879     copy_object_set_idnew(C, dupflag);
01880 
01881     DAG_scene_sort(bmain, scene);
01882     DAG_ids_flush_update(bmain, 0);
01883 
01884     WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
01885 
01886     return OPERATOR_FINISHED;
01887 }
01888 
01889 void OBJECT_OT_duplicate(wmOperatorType *ot)
01890 {
01891     PropertyRNA *prop;
01892     
01893     /* identifiers */
01894     ot->name= "Duplicate Objects";
01895     ot->description = "Duplicate selected objects";
01896     ot->idname= "OBJECT_OT_duplicate";
01897     
01898     /* api callbacks */
01899     ot->exec= duplicate_exec;
01900     ot->poll= ED_operator_objectmode;
01901     
01902     /* flags */
01903     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01904     
01905     /* to give to transform */
01906     RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data");
01907     prop= RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
01908     RNA_def_property_flag(prop, PROP_HIDDEN);
01909 }
01910 
01911 /* **************** add named object, for dragdrop ************* */
01912 
01913 
01914 static int add_named_exec(bContext *C, wmOperator *op)
01915 {
01916     Main *bmain= CTX_data_main(C);
01917     Scene *scene= CTX_data_scene(C);
01918     Base *basen, *base;
01919     Object *ob;
01920     int linked= RNA_boolean_get(op->ptr, "linked");
01921     int dupflag= (linked)? 0: U.dupflag;
01922     char name[MAX_ID_NAME-2];
01923 
01924     /* find object, create fake base */
01925     RNA_string_get(op->ptr, "name", name);
01926     ob= (Object *)find_id("OB", name);
01927     if(ob==NULL) 
01928         return OPERATOR_CANCELLED;
01929 
01930     base= MEM_callocN(sizeof(Base), "duplibase");
01931     base->object= ob;
01932     base->flag= ob->flag;
01933 
01934     /* prepare dupli */
01935     clear_id_newpoins();
01936     clear_sca_new_poins();  /* sensor/contr/act */
01937 
01938     basen= object_add_duplicate_internal(bmain, scene, base, dupflag);
01939 
01940     if (basen == NULL) {
01941         MEM_freeN(base);
01942         return OPERATOR_CANCELLED;
01943     }
01944 
01945     basen->lay= basen->object->lay= scene->lay;
01946 
01947     ED_object_location_from_view(C, basen->object->loc);
01948     ED_base_object_activate(C, basen);
01949 
01950     copy_object_set_idnew(C, dupflag);
01951 
01952     DAG_scene_sort(bmain, scene);
01953     DAG_ids_flush_update(bmain, 0);
01954 
01955     MEM_freeN(base);
01956 
01957     WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
01958 
01959     return OPERATOR_FINISHED;
01960 }
01961 
01962 void OBJECT_OT_add_named(wmOperatorType *ot)
01963 {
01964     /* identifiers */
01965     ot->name= "Add Named Object";
01966     ot->description = "Add named object";
01967     ot->idname= "OBJECT_OT_add_named";
01968     
01969     /* api callbacks */
01970     ot->exec= add_named_exec;
01971     ot->poll= ED_operator_objectmode;
01972     
01973     /* flags */
01974     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01975     
01976     RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data");
01977     RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME-2, "Name", "Object name to add");
01978 }
01979 
01980 
01981 
01982 /**************************** Join *************************/
01983 static int join_poll(bContext *C)
01984 {
01985     Object *ob= CTX_data_active_object(C);
01986     
01987     if (!ob || ob->id.lib) return 0;
01988     
01989     if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE))
01990         return ED_operator_screenactive(C);
01991     else
01992         return 0;
01993 }
01994 
01995 
01996 static int join_exec(bContext *C, wmOperator *op)
01997 {
01998     Scene *scene= CTX_data_scene(C);
01999     Object *ob= CTX_data_active_object(C);
02000 
02001     if(scene->obedit) {
02002         BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode");
02003         return OPERATOR_CANCELLED;
02004     }
02005     else if(object_data_is_libdata(ob)) {
02006         BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
02007         return OPERATOR_CANCELLED;
02008     }
02009 
02010     if(ob->type == OB_MESH)
02011         return join_mesh_exec(C, op);
02012     else if(ELEM(ob->type, OB_CURVE, OB_SURF))
02013         return join_curve_exec(C, op);
02014     else if(ob->type == OB_ARMATURE)
02015         return join_armature_exec(C, op);
02016     
02017     return OPERATOR_CANCELLED;
02018 }
02019 
02020 void OBJECT_OT_join(wmOperatorType *ot)
02021 {
02022     /* identifiers */
02023     ot->name= "Join";
02024     ot->description = "Join selected objects into active object";
02025     ot->idname= "OBJECT_OT_join";
02026     
02027     /* api callbacks */
02028     ot->exec= join_exec;
02029     ot->poll= join_poll;
02030     
02031     /* flags */
02032     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02033 }
02034 
02035 /**************************** Join as Shape Key*************************/
02036 static int join_shapes_poll(bContext *C)
02037 {
02038     Object *ob= CTX_data_active_object(C);
02039     
02040     if (!ob || ob->id.lib) return 0;
02041     
02042     /* only meshes supported at the moment */
02043     if (ob->type == OB_MESH)
02044         return ED_operator_screenactive(C);
02045     else
02046         return 0;
02047 }
02048 
02049 static int join_shapes_exec(bContext *C, wmOperator *op)
02050 {
02051     Scene *scene= CTX_data_scene(C);
02052     Object *ob= CTX_data_active_object(C);
02053     
02054     if(scene->obedit) {
02055         BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode");
02056         return OPERATOR_CANCELLED;
02057     }
02058     else if(object_data_is_libdata(ob)) {
02059         BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
02060         return OPERATOR_CANCELLED;
02061     }
02062     
02063     if(ob->type == OB_MESH)
02064         return join_mesh_shapes_exec(C, op);
02065     
02066     return OPERATOR_CANCELLED;
02067 }
02068 
02069 void OBJECT_OT_join_shapes(wmOperatorType *ot)
02070 {
02071     /* identifiers */
02072     ot->name= "Join as Shapes";
02073     ot->description = "Merge selected objects to shapes of active object";
02074     ot->idname= "OBJECT_OT_join_shapes";
02075     
02076     /* api callbacks */
02077     ot->exec= join_shapes_exec;
02078     ot->poll= join_shapes_poll;
02079     
02080     /* flags */
02081     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02082 }