Blender V2.61 - r43446
|
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 }