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