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 <stdio.h> 00032 #include <stdlib.h> 00033 #include <string.h> 00034 00035 #include "MEM_guardedalloc.h" 00036 00037 #include "DNA_anim_types.h" 00038 #include "DNA_constraint_types.h" 00039 #include "DNA_group_types.h" 00040 #include "DNA_lamp_types.h" 00041 #include "DNA_lattice_types.h" 00042 #include "DNA_material_types.h" 00043 #include "DNA_meta_types.h" 00044 #include "DNA_particle_types.h" 00045 #include "DNA_scene_types.h" 00046 #include "DNA_speaker_types.h" 00047 #include "DNA_world_types.h" 00048 #include "DNA_object_types.h" 00049 00050 #include "BLI_math.h" 00051 #include "BLI_editVert.h" 00052 #include "BLI_listbase.h" 00053 #include "BLI_string.h" 00054 #include "BLI_utildefines.h" 00055 00056 #include "BKE_action.h" 00057 #include "BKE_animsys.h" 00058 #include "BKE_armature.h" 00059 #include "BKE_camera.h" 00060 #include "BKE_context.h" 00061 #include "BKE_constraint.h" 00062 #include "BKE_curve.h" 00063 #include "BKE_depsgraph.h" 00064 #include "BKE_DerivedMesh.h" 00065 #include "BKE_displist.h" 00066 #include "BKE_global.h" 00067 #include "BKE_fcurve.h" 00068 #include "BKE_lamp.h" 00069 #include "BKE_lattice.h" 00070 #include "BKE_library.h" 00071 #include "BKE_main.h" 00072 #include "BKE_material.h" 00073 #include "BKE_mball.h" 00074 #include "BKE_mesh.h" 00075 #include "BKE_modifier.h" 00076 #include "BKE_object.h" 00077 #include "BKE_report.h" 00078 #include "BKE_sca.h" 00079 #include "BKE_scene.h" 00080 #include "BKE_speaker.h" 00081 #include "BKE_texture.h" 00082 00083 #include "WM_api.h" 00084 #include "WM_types.h" 00085 00086 #include "UI_interface.h" 00087 #include "UI_resources.h" 00088 00089 #include "RNA_access.h" 00090 #include "RNA_define.h" 00091 #include "RNA_enum_types.h" 00092 00093 #include "ED_armature.h" 00094 #include "ED_curve.h" 00095 #include "ED_keyframing.h" 00096 #include "ED_object.h" 00097 #include "ED_screen.h" 00098 #include "ED_view3d.h" 00099 #include "ED_mesh.h" 00100 00101 #include "object_intern.h" 00102 00103 /*********************** Make Vertex Parent Operator ************************/ 00104 00105 static int vertex_parent_set_poll(bContext *C) 00106 { 00107 return ED_operator_editmesh(C) || ED_operator_editsurfcurve(C) || ED_operator_editlattice(C); 00108 } 00109 00110 static int vertex_parent_set_exec(bContext *C, wmOperator *op) 00111 { 00112 Main *bmain= CTX_data_main(C); 00113 Scene *scene= CTX_data_scene(C); 00114 Object *obedit= CTX_data_edit_object(C); 00115 EditVert *eve; 00116 Curve *cu; 00117 Nurb *nu; 00118 BezTriple *bezt; 00119 BPoint *bp; 00120 Object *par; 00121 int a, v1=0, v2=0, v3=0, v4=0, nr=1; 00122 00123 /* we need 1 to 3 selected vertices */ 00124 00125 if(obedit->type==OB_MESH) { 00126 Mesh *me= obedit->data; 00127 EditMesh *em; 00128 00129 load_editMesh(scene, obedit); 00130 make_editMesh(scene, obedit); 00131 00132 em= BKE_mesh_get_editmesh(me); 00133 00134 /* derivedMesh might be needed for solving parenting, 00135 so re-create it here */ 00136 makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH); 00137 00138 eve= em->verts.first; 00139 while(eve) { 00140 if(eve->f & 1) { 00141 if(v1==0) v1= nr; 00142 else if(v2==0) v2= nr; 00143 else if(v3==0) v3= nr; 00144 else if(v4==0) v4= nr; 00145 else break; 00146 } 00147 nr++; 00148 eve= eve->next; 00149 } 00150 00151 BKE_mesh_end_editmesh(me, em); 00152 } 00153 else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) { 00154 ListBase *editnurb= object_editcurve_get(obedit); 00155 00156 cu= obedit->data; 00157 00158 nu= editnurb->first; 00159 while(nu) { 00160 if(nu->type == CU_BEZIER) { 00161 bezt= nu->bezt; 00162 a= nu->pntsu; 00163 while(a--) { 00164 if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) { 00165 if(v1==0) v1= nr; 00166 else if(v2==0) v2= nr; 00167 else if(v3==0) v3= nr; 00168 else if(v4==0) v4= nr; 00169 else break; 00170 } 00171 nr++; 00172 bezt++; 00173 } 00174 } 00175 else { 00176 bp= nu->bp; 00177 a= nu->pntsu*nu->pntsv; 00178 while(a--) { 00179 if(bp->f1 & SELECT) { 00180 if(v1==0) v1= nr; 00181 else if(v2==0) v2= nr; 00182 else if(v3==0) v3= nr; 00183 else if(v4==0) v4= nr; 00184 else break; 00185 } 00186 nr++; 00187 bp++; 00188 } 00189 } 00190 nu= nu->next; 00191 } 00192 } 00193 else if(obedit->type==OB_LATTICE) { 00194 Lattice *lt= obedit->data; 00195 00196 a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; 00197 bp= lt->editlatt->latt->def; 00198 while(a--) { 00199 if(bp->f1 & SELECT) { 00200 if(v1==0) v1= nr; 00201 else if(v2==0) v2= nr; 00202 else if(v3==0) v3= nr; 00203 else if(v4==0) v4= nr; 00204 else break; 00205 } 00206 nr++; 00207 bp++; 00208 } 00209 } 00210 00211 if(v4 || !((v1 && v2==0 && v3==0) || (v1 && v2 && v3)) ) { 00212 BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to"); 00213 return OPERATOR_CANCELLED; 00214 } 00215 00216 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00217 if(ob != obedit) { 00218 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00219 par= obedit->parent; 00220 00221 while(par) { 00222 if(par==ob) break; 00223 par= par->parent; 00224 } 00225 if(par) { 00226 BKE_report(op->reports, RPT_ERROR, "Loop in parents"); 00227 } 00228 else { 00229 Object workob; 00230 00231 ob->parent= BASACT->object; 00232 if(v3) { 00233 ob->partype= PARVERT3; 00234 ob->par1= v1-1; 00235 ob->par2= v2-1; 00236 ob->par3= v3-1; 00237 00238 /* inverse parent matrix */ 00239 what_does_parent(scene, ob, &workob); 00240 invert_m4_m4(ob->parentinv, workob.obmat); 00241 } 00242 else { 00243 ob->partype= PARVERT1; 00244 ob->par1= v1-1; 00245 00246 /* inverse parent matrix */ 00247 what_does_parent(scene, ob, &workob); 00248 invert_m4_m4(ob->parentinv, workob.obmat); 00249 } 00250 } 00251 } 00252 } 00253 CTX_DATA_END; 00254 00255 DAG_scene_sort(bmain, scene); 00256 00257 WM_event_add_notifier(C, NC_OBJECT, NULL); 00258 00259 return OPERATOR_FINISHED; 00260 } 00261 00262 void OBJECT_OT_vertex_parent_set(wmOperatorType *ot) 00263 { 00264 /* identifiers */ 00265 ot->name= "Make Vertex Parent"; 00266 ot->description = "Parent selected objects to the selected vertices"; 00267 ot->idname= "OBJECT_OT_vertex_parent_set"; 00268 00269 /* api callbacks */ 00270 ot->invoke= WM_operator_confirm; 00271 ot->poll= vertex_parent_set_poll; 00272 ot->exec= vertex_parent_set_exec; 00273 00274 /* flags */ 00275 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00276 } 00277 00278 /********************** Make Proxy Operator *************************/ 00279 00280 /* set the object to proxify */ 00281 static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) 00282 { 00283 Scene *scene= CTX_data_scene(C); 00284 Object *ob= ED_object_active_context(C); 00285 00286 /* sanity checks */ 00287 if (!scene || scene->id.lib || !ob) 00288 return OPERATOR_CANCELLED; 00289 00290 /* Get object to work on - use a menu if we need to... */ 00291 if (ob->dup_group && ob->dup_group->id.lib) { 00292 /* gives menu with list of objects in group */ 00293 //proxy_group_objects_menu(C, op, ob, ob->dup_group); 00294 WM_enum_search_invoke(C, op, evt); 00295 return OPERATOR_CANCELLED; 00296 00297 } 00298 else if (ob->id.lib) { 00299 uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); 00300 uiLayout *layout= uiPupMenuLayout(pup); 00301 00302 /* create operator menu item with relevant properties filled in */ 00303 uiItemFullO(layout, op->idname, op->type->name, ICON_NONE, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); 00304 00305 /* present the menu and be done... */ 00306 uiPupMenuEnd(C, pup); 00307 } 00308 else { 00309 /* error.. cannot continue */ 00310 BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); 00311 } 00312 00313 /* this invoke just calls another instance of this operator... */ 00314 return OPERATOR_CANCELLED; 00315 } 00316 00317 static int make_proxy_exec (bContext *C, wmOperator *op) 00318 { 00319 Main *bmain= CTX_data_main(C); 00320 Object *ob, *gob= ED_object_active_context(C); 00321 GroupObject *go; 00322 Scene *scene= CTX_data_scene(C); 00323 00324 if (gob->dup_group != NULL) 00325 { 00326 go= BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "type")); 00327 ob= go->ob; 00328 } 00329 else 00330 { 00331 ob= gob; 00332 gob = NULL; 00333 } 00334 00335 if (ob) { 00336 Object *newob; 00337 Base *newbase, *oldbase= BASACT; 00338 char name[MAX_ID_NAME+4]; 00339 00340 /* Add new object for the proxy */ 00341 newob= add_object(scene, OB_EMPTY); 00342 00343 BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name+2); 00344 00345 rename_id(&newob->id, name); 00346 00347 /* set layers OK */ 00348 newbase= BASACT; /* add_object sets active... */ 00349 newbase->lay= oldbase->lay; 00350 newob->lay= newbase->lay; 00351 00352 /* remove base, leave user count of object, it gets linked in object_make_proxy */ 00353 if (gob==NULL) { 00354 BLI_remlink(&scene->base, oldbase); 00355 MEM_freeN(oldbase); 00356 } 00357 00358 object_make_proxy(newob, ob, gob); 00359 00360 /* depsgraph flushes are needed for the new data */ 00361 DAG_scene_sort(bmain, scene); 00362 DAG_id_tag_update(&newob->id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); 00363 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, newob); 00364 } 00365 else { 00366 BKE_report(op->reports, RPT_ERROR, "No object to make proxy for"); 00367 return OPERATOR_CANCELLED; 00368 } 00369 00370 return OPERATOR_FINISHED; 00371 } 00372 00373 /* Generic itemf's for operators that take library args */ 00374 static EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) 00375 { 00376 EnumPropertyItem item_tmp= {0}, *item= NULL; 00377 int totitem= 0; 00378 int i= 0; 00379 Object *ob= ED_object_active_context(C); 00380 GroupObject *go; 00381 00382 if(!ob || !ob->dup_group) 00383 return DummyRNA_DEFAULT_items; 00384 00385 /* find the object to affect */ 00386 for (go= ob->dup_group->gobject.first; go; go= go->next) { 00387 item_tmp.identifier= item_tmp.name= go->ob->id.name+2; 00388 item_tmp.value= i++; 00389 RNA_enum_item_add(&item, &totitem, &item_tmp); 00390 } 00391 00392 RNA_enum_item_end(&item, &totitem); 00393 *free= 1; 00394 00395 return item; 00396 } 00397 00398 void OBJECT_OT_proxy_make (wmOperatorType *ot) 00399 { 00400 PropertyRNA *prop; 00401 00402 /* identifiers */ 00403 ot->name= "Make Proxy"; 00404 ot->idname= "OBJECT_OT_proxy_make"; 00405 ot->description= "Add empty object to become local replacement data of a library-linked object"; 00406 00407 /* callbacks */ 00408 ot->invoke= make_proxy_invoke; 00409 ot->exec= make_proxy_exec; 00410 ot->poll= ED_operator_object_active; 00411 00412 /* flags */ 00413 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00414 00415 /* properties */ 00416 RNA_def_string(ot->srna, "object", "", MAX_ID_NAME-2, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for"); 00417 prop= RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Type", "Group object"); /* XXX, relies on hard coded ID at the moment */ 00418 RNA_def_enum_funcs(prop, proxy_group_object_itemf); 00419 ot->prop= prop; 00420 } 00421 00422 /********************** Clear Parent Operator ******************* */ 00423 00424 static EnumPropertyItem prop_clear_parent_types[] = { 00425 {0, "CLEAR", 0, "Clear Parent", ""}, 00426 {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, 00427 {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, 00428 {0, NULL, 0, NULL, NULL} 00429 }; 00430 00431 /* note, poll should check for editable scene */ 00432 static int parent_clear_exec(bContext *C, wmOperator *op) 00433 { 00434 Main *bmain= CTX_data_main(C); 00435 Scene *scene= CTX_data_scene(C); 00436 int type= RNA_enum_get(op->ptr, "type"); 00437 00438 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00439 00440 if(ob->parent == NULL) 00441 continue; 00442 00443 if(type == 0) { 00444 ob->parent= NULL; 00445 } 00446 else if(type == 1) { 00447 ob->parent= NULL; 00448 object_apply_mat4(ob, ob->obmat, TRUE, FALSE); 00449 } 00450 else if(type == 2) 00451 unit_m4(ob->parentinv); 00452 00453 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00454 } 00455 CTX_DATA_END; 00456 00457 DAG_scene_sort(bmain, scene); 00458 DAG_ids_flush_update(bmain, 0); 00459 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00460 WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); 00461 00462 return OPERATOR_FINISHED; 00463 } 00464 00465 void OBJECT_OT_parent_clear(wmOperatorType *ot) 00466 { 00467 /* identifiers */ 00468 ot->name= "Clear Parent"; 00469 ot->description = "Clear the object's parenting"; 00470 ot->idname= "OBJECT_OT_parent_clear"; 00471 00472 /* api callbacks */ 00473 ot->invoke= WM_menu_invoke; 00474 ot->exec= parent_clear_exec; 00475 00476 ot->poll= ED_operator_object_active_editable; 00477 00478 /* flags */ 00479 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00480 00481 ot->prop= RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); 00482 } 00483 00484 /* ******************** Make Parent Operator *********************** */ 00485 00486 #define PAR_OBJECT 0 00487 #define PAR_ARMATURE 1 00488 #define PAR_ARMATURE_NAME 2 00489 #define PAR_ARMATURE_ENVELOPE 3 00490 #define PAR_ARMATURE_AUTO 4 00491 #define PAR_BONE 5 00492 #define PAR_CURVE 6 00493 #define PAR_FOLLOW 7 00494 #define PAR_PATH_CONST 8 00495 #define PAR_LATTICE 9 00496 #define PAR_VERTEX 10 00497 #define PAR_TRIA 11 00498 00499 static EnumPropertyItem prop_make_parent_types[] = { 00500 {PAR_OBJECT, "OBJECT", 0, "Object", ""}, 00501 {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""}, 00502 {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""}, 00503 {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""}, 00504 {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""}, 00505 {PAR_BONE, "BONE", 0, "Bone", ""}, 00506 {PAR_CURVE, "CURVE", 0, "Curve Deform", ""}, 00507 {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""}, 00508 {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""}, 00509 {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""}, 00510 {PAR_VERTEX, "VERTEX", 0, "Vertex", ""}, 00511 {PAR_TRIA, "TRIA", 0, "Triangle", ""}, 00512 {0, NULL, 0, NULL, NULL} 00513 }; 00514 00515 void ED_object_parent(Object *ob, Object *par, int type, const char *substr) 00516 { 00517 if (!par || BKE_object_parent_loop_check(par, ob)) { 00518 ob->parent= NULL; 00519 ob->partype= PAROBJECT; 00520 ob->parsubstr[0]= 0; 00521 return; 00522 } 00523 00524 /* this could use some more checks */ 00525 00526 ob->parent= par; 00527 ob->partype &= ~PARTYPE; 00528 ob->partype |= type; 00529 BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr)); 00530 } 00531 00532 static int parent_set_exec(bContext *C, wmOperator *op) 00533 { 00534 Main *bmain= CTX_data_main(C); 00535 Scene *scene= CTX_data_scene(C); 00536 Object *par= ED_object_active_context(C); 00537 bPoseChannel *pchan= NULL; 00538 int partype= RNA_enum_get(op->ptr, "type"); 00539 int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); 00540 00541 par->recalc |= OB_RECALC_OB; 00542 00543 /* preconditions */ 00544 if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) { 00545 if(par->type!=OB_CURVE) 00546 return OPERATOR_CANCELLED; 00547 else { 00548 Curve *cu= par->data; 00549 00550 if((cu->flag & CU_PATH)==0) { 00551 cu->flag |= CU_PATH|CU_FOLLOW; 00552 makeDispListCurveTypes(scene, par, 0); /* force creation of path data */ 00553 } 00554 else cu->flag |= CU_FOLLOW; 00555 00556 /* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */ 00557 if(partype == PAR_FOLLOW) { 00558 /* get or create F-Curve */ 00559 bAction *act = verify_adt_action(&cu->id, 1); 00560 FCurve *fcu = verify_fcurve(act, NULL, "eval_time", 0, 1); 00561 00562 /* setup dummy 'generator' modifier here to get 1-1 correspondance still working */ 00563 if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) 00564 add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); 00565 } 00566 00567 /* fall back on regular parenting now (for follow only) */ 00568 if(partype == PAR_FOLLOW) 00569 partype= PAR_OBJECT; 00570 } 00571 } 00572 else if(partype==PAR_BONE) { 00573 pchan= get_active_posechannel(par); 00574 00575 if(pchan==NULL) { 00576 BKE_report(op->reports, RPT_ERROR, "No active Bone"); 00577 return OPERATOR_CANCELLED; 00578 } 00579 } 00580 00581 /* context iterator */ 00582 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00583 00584 if(ob!=par) { 00585 00586 if (BKE_object_parent_loop_check(par, ob)) { 00587 BKE_report(op->reports, RPT_ERROR, "Loop in parents"); 00588 } 00589 else { 00590 Object workob; 00591 00592 /* apply transformation of previous parenting */ 00593 /* object_apply_mat4(ob, ob->obmat); */ /* removed because of bug [#23577] */ 00594 00595 /* set the parent (except for follow-path constraint option) */ 00596 if(partype != PAR_PATH_CONST) 00597 ob->parent= par; 00598 00599 /* handle types */ 00600 if (pchan) 00601 BLI_strncpy(ob->parsubstr, pchan->name, sizeof(ob->parsubstr)); 00602 else 00603 ob->parsubstr[0]= 0; 00604 00605 if(partype == PAR_PATH_CONST) 00606 ; /* don't do anything here, since this is not technically "parenting" */ 00607 else if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) 00608 { 00609 /* partype is now set to PAROBJECT so that invisible 'virtual' modifiers don't need to be created 00610 * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL, creating the virtual modifiers 00611 */ 00612 ob->partype= PAROBJECT; /* note, dna define, not operator property */ 00613 //ob->partype= PARSKEL; /* note, dna define, not operator property */ 00614 00615 /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ 00616 // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet 00617 if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) 00618 { 00619 ModifierData *md; 00620 00621 switch (partype) { 00622 case PAR_CURVE: /* curve deform */ 00623 md= ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, eModifierType_Curve); 00624 ((CurveModifierData *)md)->object= par; 00625 break; 00626 case PAR_LATTICE: /* lattice deform */ 00627 md= ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, eModifierType_Lattice); 00628 ((LatticeModifierData *)md)->object= par; 00629 break; 00630 default: /* armature deform */ 00631 md= ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, eModifierType_Armature); 00632 ((ArmatureModifierData *)md)->object= par; 00633 break; 00634 } 00635 } 00636 } 00637 else if (partype == PAR_BONE) 00638 ob->partype= PARBONE; /* note, dna define, not operator property */ 00639 else 00640 ob->partype= PAROBJECT; /* note, dna define, not operator property */ 00641 00642 /* constraint */ 00643 if(partype == PAR_PATH_CONST) { 00644 bConstraint *con; 00645 bFollowPathConstraint *data; 00646 float cmat[4][4], vec[3]; 00647 00648 con = add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH); 00649 00650 data = con->data; 00651 data->tar = par; 00652 00653 get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); 00654 sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); 00655 00656 ob->loc[0] = vec[0]; 00657 ob->loc[1] = vec[1]; 00658 ob->loc[2] = vec[2]; 00659 } 00660 else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) { 00661 if(partype == PAR_ARMATURE_NAME) 00662 create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_NAME, 0); 00663 else if(partype == PAR_ARMATURE_ENVELOPE) 00664 create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_ENVELOPE, 0); 00665 else if(partype == PAR_ARMATURE_AUTO) { 00666 WM_cursor_wait(1); 00667 create_vgroups_from_armature(op->reports, scene, ob, par, ARM_GROUPS_AUTO, 0); 00668 WM_cursor_wait(0); 00669 } 00670 /* get corrected inverse */ 00671 ob->partype= PAROBJECT; 00672 what_does_parent(scene, ob, &workob); 00673 00674 invert_m4_m4(ob->parentinv, workob.obmat); 00675 } 00676 else { 00677 /* calculate inverse parent matrix */ 00678 what_does_parent(scene, ob, &workob); 00679 invert_m4_m4(ob->parentinv, workob.obmat); 00680 } 00681 00682 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; 00683 } 00684 } 00685 } 00686 CTX_DATA_END; 00687 00688 DAG_scene_sort(bmain, scene); 00689 DAG_ids_flush_update(bmain, 0); 00690 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00691 WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, NULL); 00692 00693 return OPERATOR_FINISHED; 00694 } 00695 00696 static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) 00697 { 00698 Object *ob= ED_object_active_context(C); 00699 uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", ICON_NONE); 00700 uiLayout *layout= uiPupMenuLayout(pup); 00701 00702 uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); 00703 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_OBJECT); 00704 00705 /* ob becomes parent, make the associated menus */ 00706 if(ob->type==OB_ARMATURE) { 00707 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE); 00708 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_NAME); 00709 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_ENVELOPE); 00710 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_AUTO); 00711 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_BONE); 00712 } 00713 else if(ob->type==OB_CURVE) { 00714 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_CURVE); 00715 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_FOLLOW); 00716 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_PATH_CONST); 00717 } 00718 else if(ob->type == OB_LATTICE) { 00719 uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_LATTICE); 00720 } 00721 00722 uiPupMenuEnd(C, pup); 00723 00724 return OPERATOR_CANCELLED; 00725 } 00726 00727 00728 void OBJECT_OT_parent_set(wmOperatorType *ot) 00729 { 00730 /* identifiers */ 00731 ot->name= "Make Parent"; 00732 ot->description = "Set the object's parenting"; 00733 ot->idname= "OBJECT_OT_parent_set"; 00734 00735 /* api callbacks */ 00736 ot->invoke= parent_set_invoke; 00737 ot->exec= parent_set_exec; 00738 00739 ot->poll= ED_operator_object_active; 00740 00741 /* flags */ 00742 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00743 00744 RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); 00745 } 00746 00747 /* ************ Make Parent Without Inverse Operator ******************* */ 00748 00749 static int parent_noinv_set_exec(bContext *C, wmOperator *op) 00750 { 00751 Main *bmain= CTX_data_main(C); 00752 Object *par= ED_object_active_context(C); 00753 00754 par->recalc |= OB_RECALC_OB; 00755 00756 /* context iterator */ 00757 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00758 if (ob != par) { 00759 if (BKE_object_parent_loop_check(par, ob)) { 00760 BKE_report(op->reports, RPT_ERROR, "Loop in parents"); 00761 } 00762 else { 00763 /* clear inverse matrix and also the object location */ 00764 unit_m4(ob->parentinv); 00765 memset(ob->loc, 0, 3*sizeof(float)); 00766 00767 /* set recalc flags */ 00768 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; 00769 00770 /* set parenting type for object - object only... */ 00771 ob->parent= par; 00772 ob->partype= PAROBJECT; /* note, dna define, not operator property */ 00773 } 00774 } 00775 } 00776 CTX_DATA_END; 00777 00778 DAG_scene_sort(bmain, CTX_data_scene(C)); 00779 DAG_ids_flush_update(bmain, 0); 00780 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00781 00782 return OPERATOR_FINISHED; 00783 } 00784 00785 void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot) 00786 { 00787 /* identifiers */ 00788 ot->name= "Make Parent without Inverse"; 00789 ot->description = "Set the object's parenting without setting the inverse parent correction"; 00790 ot->idname= "OBJECT_OT_parent_no_inverse_set"; 00791 00792 /* api callbacks */ 00793 ot->invoke= WM_operator_confirm; 00794 ot->exec= parent_noinv_set_exec; 00795 ot->poll= ED_operator_object_active_editable; 00796 00797 /* flags */ 00798 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00799 } 00800 00801 /************************ Clear Slow Parent Operator *********************/ 00802 00803 static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) 00804 { 00805 Main *bmain= CTX_data_main(C); 00806 Scene *scene= CTX_data_scene(C); 00807 00808 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00809 if(ob->parent) { 00810 if(ob->partype & PARSLOW) { 00811 ob->partype -= PARSLOW; 00812 where_is_object(scene, ob); 00813 ob->partype |= PARSLOW; 00814 ob->recalc |= OB_RECALC_OB; 00815 } 00816 } 00817 } 00818 CTX_DATA_END; 00819 00820 DAG_ids_flush_update(bmain, 0); 00821 WM_event_add_notifier(C, NC_SCENE, scene); 00822 00823 return OPERATOR_FINISHED; 00824 } 00825 00826 void OBJECT_OT_slow_parent_clear(wmOperatorType *ot) 00827 { 00828 00829 /* identifiers */ 00830 ot->name= "Clear Slow Parent"; 00831 ot->description = "Clear the object's slow parent"; 00832 ot->idname= "OBJECT_OT_slow_parent_clear"; 00833 00834 /* api callbacks */ 00835 ot->invoke= WM_operator_confirm; 00836 ot->exec= object_slow_parent_clear_exec; 00837 ot->poll= ED_operator_view3d_active; 00838 00839 /* flags */ 00840 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00841 } 00842 00843 /********************** Make Slow Parent Operator *********************/ 00844 00845 static int object_slow_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) 00846 { 00847 Main *bmain= CTX_data_main(C); 00848 Scene *scene= CTX_data_scene(C); 00849 00850 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00851 if(ob->parent) 00852 ob->partype |= PARSLOW; 00853 00854 ob->recalc |= OB_RECALC_OB; 00855 00856 } 00857 CTX_DATA_END; 00858 00859 DAG_ids_flush_update(bmain, 0); 00860 WM_event_add_notifier(C, NC_SCENE, scene); 00861 00862 return OPERATOR_FINISHED; 00863 } 00864 00865 void OBJECT_OT_slow_parent_set(wmOperatorType *ot) 00866 { 00867 00868 /* identifiers */ 00869 ot->name= "Set Slow Parent"; 00870 ot->description = "Set the object's slow parent"; 00871 ot->idname= "OBJECT_OT_slow_parent_set"; 00872 00873 /* api callbacks */ 00874 ot->invoke= WM_operator_confirm; 00875 ot->exec= object_slow_parent_set_exec; 00876 ot->poll= ED_operator_view3d_active; 00877 00878 /* flags */ 00879 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00880 } 00881 00882 /* ******************** Clear Track Operator ******************* */ 00883 00884 static EnumPropertyItem prop_clear_track_types[] = { 00885 {0, "CLEAR", 0, "Clear Track", ""}, 00886 {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, 00887 {0, NULL, 0, NULL, NULL} 00888 }; 00889 00890 /* note, poll should check for editable scene */ 00891 static int object_track_clear_exec(bContext *C, wmOperator *op) 00892 { 00893 Main *bmain= CTX_data_main(C); 00894 Scene *scene= CTX_data_scene(C); 00895 int type= RNA_enum_get(op->ptr, "type"); 00896 00897 if(CTX_data_edit_object(C)) { 00898 BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); 00899 return OPERATOR_CANCELLED; 00900 } 00901 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00902 bConstraint *con, *pcon; 00903 00904 /* remove track-object for old track */ 00905 ob->track= NULL; 00906 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00907 00908 /* also remove all tracking constraints */ 00909 for (con= ob->constraints.last; con; con= pcon) { 00910 pcon= con->prev; 00911 if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK)) 00912 remove_constraint(&ob->constraints, con); 00913 } 00914 00915 if(type == 1) 00916 object_apply_mat4(ob, ob->obmat, TRUE, TRUE); 00917 } 00918 CTX_DATA_END; 00919 00920 DAG_ids_flush_update(bmain, 0); 00921 DAG_scene_sort(bmain, scene); 00922 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00923 00924 return OPERATOR_FINISHED; 00925 } 00926 00927 void OBJECT_OT_track_clear(wmOperatorType *ot) 00928 { 00929 /* identifiers */ 00930 ot->name= "Clear track"; 00931 ot->description = "Clear tracking constraint or flag from object"; 00932 ot->idname= "OBJECT_OT_track_clear"; 00933 00934 /* api callbacks */ 00935 ot->invoke= WM_menu_invoke; 00936 ot->exec= object_track_clear_exec; 00937 00938 ot->poll= ED_operator_objectmode; 00939 00940 /* flags */ 00941 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00942 00943 ot->prop= RNA_def_enum(ot->srna, "type", prop_clear_track_types, 0, "Type", ""); 00944 } 00945 00946 /************************** Make Track Operator *****************************/ 00947 00948 static EnumPropertyItem prop_make_track_types[] = { 00949 {1, "DAMPTRACK", 0, "Damped Track Constraint", ""}, 00950 {2, "TRACKTO", 0, "Track To Constraint", ""}, 00951 {3, "LOCKTRACK", 0, "Lock Track Constraint", ""}, 00952 {0, NULL, 0, NULL, NULL} 00953 }; 00954 00955 static int track_set_exec(bContext *C, wmOperator *op) 00956 { 00957 Main *bmain= CTX_data_main(C); 00958 Scene *scene= CTX_data_scene(C); 00959 Object *obact= ED_object_active_context(C); 00960 00961 int type= RNA_enum_get(op->ptr, "type"); 00962 00963 if(type == 1) { 00964 bConstraint *con; 00965 bDampTrackConstraint *data; 00966 00967 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00968 if(ob!=obact) { 00969 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK); 00970 00971 data = con->data; 00972 data->tar = obact; 00973 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00974 00975 /* Lamp, Camera and Speaker track differently by default */ 00976 if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) 00977 data->trackflag = TRACK_nZ; 00978 } 00979 } 00980 CTX_DATA_END; 00981 } 00982 else if(type == 2) { 00983 bConstraint *con; 00984 bTrackToConstraint *data; 00985 00986 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00987 if(ob!=obact) { 00988 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO); 00989 00990 data = con->data; 00991 data->tar = obact; 00992 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00993 00994 /* Lamp, Camera and Speaker track differently by default */ 00995 if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) { 00996 data->reserved1 = TRACK_nZ; 00997 data->reserved2 = UP_Y; 00998 } 00999 } 01000 } 01001 CTX_DATA_END; 01002 } 01003 else if(type == 3) { 01004 bConstraint *con; 01005 bLockTrackConstraint *data; 01006 01007 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 01008 if(ob!=obact) { 01009 con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK); 01010 01011 data = con->data; 01012 data->tar = obact; 01013 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 01014 01015 /* Lamp, Camera and Speaker track differently by default */ 01016 if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) { 01017 data->trackflag = TRACK_nZ; 01018 data->lockflag = LOCK_Y; 01019 } 01020 } 01021 } 01022 CTX_DATA_END; 01023 } 01024 01025 DAG_scene_sort(bmain, scene); 01026 DAG_ids_flush_update(bmain, 0); 01027 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 01028 01029 return OPERATOR_FINISHED; 01030 } 01031 01032 void OBJECT_OT_track_set(wmOperatorType *ot) 01033 { 01034 /* identifiers */ 01035 ot->name= "Make Track"; 01036 ot->description = "Make the object track another object, either by constraint or old way or locked track"; 01037 ot->idname= "OBJECT_OT_track_set"; 01038 01039 /* api callbacks */ 01040 ot->invoke= WM_menu_invoke; 01041 ot->exec= track_set_exec; 01042 01043 ot->poll= ED_operator_objectmode; 01044 01045 /* flags */ 01046 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01047 01048 /* properties */ 01049 ot->prop= RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", ""); 01050 } 01051 01052 /************************** Move to Layer Operator *****************************/ 01053 01054 static unsigned int move_to_layer_init(bContext *C, wmOperator *op) 01055 { 01056 int values[20], a; 01057 unsigned int lay= 0; 01058 01059 if(!RNA_struct_property_is_set(op->ptr, "layers")) { 01060 /* note: layers are set in bases, library objects work for this */ 01061 CTX_DATA_BEGIN(C, Base*, base, selected_bases) { 01062 lay |= base->lay; 01063 } 01064 CTX_DATA_END; 01065 01066 for(a=0; a<20; a++) 01067 values[a]= (lay & (1<<a)); 01068 01069 RNA_boolean_set_array(op->ptr, "layers", values); 01070 } 01071 else { 01072 RNA_boolean_get_array(op->ptr, "layers", values); 01073 01074 for(a=0; a<20; a++) 01075 if(values[a]) 01076 lay |= (1 << a); 01077 } 01078 01079 return lay; 01080 } 01081 01082 static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event) 01083 { 01084 View3D *v3d= CTX_wm_view3d(C); 01085 if(v3d && v3d->localvd) { 01086 return WM_operator_confirm_message(C, op, "Move from localview"); 01087 } 01088 else { 01089 move_to_layer_init(C, op); 01090 return WM_operator_props_popup(C, op, event); 01091 } 01092 } 01093 01094 static int move_to_layer_exec(bContext *C, wmOperator *op) 01095 { 01096 Main *bmain= CTX_data_main(C); 01097 Scene *scene= CTX_data_scene(C); 01098 View3D *v3d= CTX_wm_view3d(C); 01099 unsigned int lay, local; 01100 /* int islamp= 0; */ /* UNUSED */ 01101 01102 lay= move_to_layer_init(C, op); 01103 lay &= 0xFFFFFF; 01104 01105 if(lay==0) return OPERATOR_CANCELLED; 01106 01107 if(v3d && v3d->localvd) { 01108 /* now we can move out of localview. */ 01109 /* note: layers are set in bases, library objects work for this */ 01110 CTX_DATA_BEGIN(C, Base*, base, selected_bases) { 01111 lay= base->lay & ~v3d->lay; 01112 base->lay= lay; 01113 base->object->lay= lay; 01114 base->object->flag &= ~SELECT; 01115 base->flag &= ~SELECT; 01116 /* if(base->object->type==OB_LAMP) islamp= 1; */ 01117 } 01118 CTX_DATA_END; 01119 } 01120 else { 01121 /* normal non localview operation */ 01122 /* note: layers are set in bases, library objects work for this */ 01123 CTX_DATA_BEGIN(C, Base*, base, selected_bases) { 01124 /* upper byte is used for local view */ 01125 local= base->lay & 0xFF000000; 01126 base->lay= lay + local; 01127 base->object->lay= lay; 01128 /* if(base->object->type==OB_LAMP) islamp= 1; */ 01129 } 01130 CTX_DATA_END; 01131 } 01132 01133 /* warning, active object may be hidden now */ 01134 01135 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, scene); 01136 WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene); 01137 01138 DAG_scene_sort(bmain, scene); 01139 01140 return OPERATOR_FINISHED; 01141 } 01142 01143 void OBJECT_OT_move_to_layer(wmOperatorType *ot) 01144 { 01145 /* identifiers */ 01146 ot->name= "Move to Layer"; 01147 ot->description = "Move the object to different layers"; 01148 ot->idname= "OBJECT_OT_move_to_layer"; 01149 01150 /* api callbacks */ 01151 ot->invoke= move_to_layer_invoke; 01152 ot->exec= move_to_layer_exec; 01153 ot->poll= ED_operator_objectmode; 01154 01155 /* flags */ 01156 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01157 01158 /* properties */ 01159 RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); 01160 } 01161 01162 /************************** Link to Scene Operator *****************************/ 01163 01164 #if 0 01165 static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr)) 01166 { 01167 Scene *sce= (Scene*) BLI_findlink(&bmain->scene, G.curscreen->scenenr-1); 01168 Base *base, *nbase; 01169 01170 if(sce==0) return; 01171 if(sce->id.lib) return; 01172 01173 for(base= FIRSTBASE; base; base= base->next) { 01174 if(TESTBASE(v3d, base)) { 01175 01176 nbase= MEM_mallocN( sizeof(Base), "newbase"); 01177 *nbase= *base; 01178 BLI_addhead( &(sce->base), nbase); 01179 id_us_plus((ID *)base->object); 01180 } 01181 } 01182 } 01183 #endif 01184 01185 static int make_links_scene_exec(bContext *C, wmOperator *op) 01186 { 01187 Main *bmain= CTX_data_main(C); 01188 Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); 01189 01190 if(scene_to==NULL) { 01191 BKE_report(op->reports, RPT_ERROR, "Scene not found"); 01192 return OPERATOR_CANCELLED; 01193 } 01194 01195 if(scene_to == CTX_data_scene(C)) { 01196 BKE_report(op->reports, RPT_ERROR, "Can't link objects into the same scene"); 01197 return OPERATOR_CANCELLED; 01198 } 01199 01200 if(scene_to->id.lib) { 01201 BKE_report(op->reports, RPT_ERROR, "Can't link objects into a linked scene"); 01202 return OPERATOR_CANCELLED; 01203 } 01204 01205 CTX_DATA_BEGIN(C, Base*, base, selected_bases) 01206 { 01207 if(!object_in_scene(base->object, scene_to)) { 01208 Base *nbase= MEM_mallocN( sizeof(Base), "newbase"); 01209 *nbase= *base; 01210 BLI_addhead( &(scene_to->base), nbase); 01211 id_us_plus((ID *)base->object); 01212 } 01213 } 01214 CTX_DATA_END; 01215 01216 DAG_ids_flush_update(bmain, 0); 01217 01218 /* one day multiple scenes will be visible, then we should have some update function for them */ 01219 return OPERATOR_FINISHED; 01220 } 01221 01222 enum { 01223 MAKE_LINKS_OBDATA = 1, 01224 MAKE_LINKS_MATERIALS, 01225 MAKE_LINKS_ANIMDATA, 01226 MAKE_LINKS_DUPLIGROUP, 01227 MAKE_LINKS_MODIFIERS 01228 }; 01229 01230 /* Return 1 if make link data is allow, zero otherwise */ 01231 static int allow_make_links_data(int ev, Object *ob, Object *obt) 01232 { 01233 switch(ev) { 01234 case MAKE_LINKS_OBDATA: 01235 if (ob->type == obt->type && ob->type != OB_EMPTY) 01236 return 1; 01237 break; 01238 case MAKE_LINKS_MATERIALS: 01239 if (OB_TYPE_SUPPORT_MATERIAL(ob->type) && 01240 OB_TYPE_SUPPORT_MATERIAL(obt->type)) 01241 { 01242 return 1; 01243 } 01244 break; 01245 case MAKE_LINKS_ANIMDATA: 01246 case MAKE_LINKS_DUPLIGROUP: 01247 return 1; 01248 case MAKE_LINKS_MODIFIERS: 01249 if (ob->type != OB_EMPTY && obt->type != OB_EMPTY) 01250 return 1; 01251 break; 01252 } 01253 return 0; 01254 } 01255 01256 static int make_links_data_exec(bContext *C, wmOperator *op) 01257 { 01258 Main *bmain= CTX_data_main(C); 01259 int event = RNA_enum_get(op->ptr, "type"); 01260 Object *ob; 01261 ID *id; 01262 int a; 01263 01264 ob= ED_object_active_context(C); 01265 01266 CTX_DATA_BEGIN(C, Object*, obt, selected_editable_objects) { 01267 if(ob != obt) { 01268 if (allow_make_links_data(event, ob, obt)) { 01269 switch(event) { 01270 case MAKE_LINKS_OBDATA: /* obdata */ 01271 id= obt->data; 01272 id->us--; 01273 01274 id= ob->data; 01275 id_us_plus(id); 01276 obt->data= id; 01277 01278 /* if amount of material indices changed: */ 01279 test_object_materials(obt->data); 01280 01281 obt->recalc |= OB_RECALC_DATA; 01282 break; 01283 case MAKE_LINKS_MATERIALS: 01284 /* new approach, using functions from kernel */ 01285 for(a=0; a<ob->totcol; a++) { 01286 Material *ma= give_current_material(ob, a+1); 01287 assign_material(obt, ma, a+1); /* also works with ma==NULL */ 01288 } 01289 break; 01290 case MAKE_LINKS_ANIMDATA: 01291 BKE_copy_animdata_id((ID *)obt, (ID *)ob, FALSE); 01292 BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data, FALSE); 01293 break; 01294 case MAKE_LINKS_DUPLIGROUP: 01295 obt->dup_group= ob->dup_group; 01296 if(obt->dup_group) { 01297 id_lib_extern(&obt->dup_group->id); 01298 obt->transflag |= OB_DUPLIGROUP; 01299 } 01300 break; 01301 case MAKE_LINKS_MODIFIERS: 01302 object_link_modifiers(obt, ob); 01303 obt->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 01304 break; 01305 } 01306 } 01307 } 01308 } 01309 CTX_DATA_END; 01310 01311 DAG_scene_sort(bmain, CTX_data_scene(C)); 01312 01313 DAG_ids_flush_update(bmain, 0); 01314 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); 01315 return OPERATOR_FINISHED; 01316 } 01317 01318 01319 void OBJECT_OT_make_links_scene(wmOperatorType *ot) 01320 { 01321 PropertyRNA *prop; 01322 01323 /* identifiers */ 01324 ot->name= "Link Objects to Scene"; 01325 ot->description = "Link selection to another scene"; 01326 ot->idname= "OBJECT_OT_make_links_scene"; 01327 01328 /* api callbacks */ 01329 ot->invoke= WM_enum_search_invoke; 01330 ot->exec= make_links_scene_exec; 01331 /* better not run the poll check */ 01332 01333 /* flags */ 01334 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01335 01336 /* properties */ 01337 prop= RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", ""); 01338 RNA_def_enum_funcs(prop, RNA_scene_local_itemf); 01339 ot->prop= prop; 01340 } 01341 01342 void OBJECT_OT_make_links_data(wmOperatorType *ot) 01343 { 01344 static EnumPropertyItem make_links_items[]= { 01345 {MAKE_LINKS_OBDATA, "OBDATA", 0, "Object Data", ""}, 01346 {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""}, 01347 {MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""}, 01348 {MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""}, 01349 {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""}, 01350 {0, NULL, 0, NULL, NULL}}; 01351 01352 /* identifiers */ 01353 ot->name= "Link Data"; 01354 ot->description = "Make links from the active object to other selected objects"; 01355 ot->idname= "OBJECT_OT_make_links_data"; 01356 01357 /* api callbacks */ 01358 ot->exec= make_links_data_exec; 01359 ot->poll= ED_operator_object_active; 01360 01361 /* flags */ 01362 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01363 01364 /* properties */ 01365 ot->prop= RNA_def_enum(ot->srna, "type", make_links_items, 0, "Type", ""); 01366 } 01367 01368 01369 /**************************** Make Single User ********************************/ 01370 01371 static void single_object_users(Scene *scene, View3D *v3d, int flag) 01372 { 01373 Base *base; 01374 Object *ob, *obn; 01375 01376 clear_sca_new_poins(); /* sensor/contr/act */ 01377 01378 /* duplicate (must set newid) */ 01379 for(base= FIRSTBASE; base; base= base->next) { 01380 ob= base->object; 01381 01382 /* newid may still have some trash from Outliner tree building, 01383 * so clear that first to avoid errors [#26002] 01384 */ 01385 ob->id.newid = NULL; 01386 01387 if( (base->flag & flag)==flag ) { 01388 if(ob->id.lib==NULL && ob->id.us>1) { 01389 /* base gets copy of object */ 01390 obn= copy_object(ob); 01391 base->object= obn; 01392 ob->id.us--; 01393 } 01394 } 01395 } 01396 01397 ID_NEW(scene->camera); 01398 if(v3d) ID_NEW(v3d->camera); 01399 01400 /* object pointers */ 01401 for(base= FIRSTBASE; base; base= base->next) { 01402 object_relink(base->object); 01403 } 01404 01405 set_sca_new_poins(); 01406 } 01407 01408 /* not an especially efficient function, only added so the single user 01409 * button can be functional.*/ 01410 void ED_object_single_user(Scene *scene, Object *ob) 01411 { 01412 Base *base; 01413 01414 for(base= FIRSTBASE; base; base= base->next) { 01415 if(base->object == ob) base->flag |= OB_DONE; 01416 else base->flag &= ~OB_DONE; 01417 } 01418 01419 single_object_users(scene, NULL, OB_DONE); 01420 } 01421 01422 static void new_id_matar(Material **matar, int totcol) 01423 { 01424 ID *id; 01425 int a; 01426 01427 for(a=0; a<totcol; a++) { 01428 id= (ID *)matar[a]; 01429 if(id && id->lib == NULL) { 01430 if(id->newid) { 01431 matar[a]= (Material *)id->newid; 01432 id_us_plus(id->newid); 01433 id->us--; 01434 } 01435 else if(id->us>1) { 01436 matar[a]= copy_material(matar[a]); 01437 id->us--; 01438 id->newid= (ID *)matar[a]; 01439 } 01440 } 01441 } 01442 } 01443 01444 static void single_obdata_users(Main *bmain, Scene *scene, int flag) 01445 { 01446 Object *ob; 01447 Lamp *la; 01448 Curve *cu; 01449 //Camera *cam; 01450 Base *base; 01451 Mesh *me; 01452 ID *id; 01453 int a; 01454 01455 for(base= FIRSTBASE; base; base= base->next) { 01456 ob= base->object; 01457 if(ob->id.lib==NULL && (base->flag & flag)==flag ) { 01458 id= ob->data; 01459 01460 if(id && id->us>1 && id->lib==NULL) { 01461 ob->recalc= OB_RECALC_DATA; 01462 01463 BKE_copy_animdata_id_action(id); 01464 01465 switch(ob->type) { 01466 case OB_LAMP: 01467 ob->data= la= copy_lamp(ob->data); 01468 for(a=0; a<MAX_MTEX; a++) { 01469 if(la->mtex[a]) { 01470 ID_NEW(la->mtex[a]->object); 01471 } 01472 } 01473 break; 01474 case OB_CAMERA: 01475 ob->data= copy_camera(ob->data); 01476 break; 01477 case OB_MESH: 01478 ob->data= copy_mesh(ob->data); 01479 //me= ob->data; 01480 //if(me && me->key) 01481 // ipo_idnew(me->key->ipo); /* drivers */ 01482 break; 01483 case OB_MBALL: 01484 ob->data= copy_mball(ob->data); 01485 break; 01486 case OB_CURVE: 01487 case OB_SURF: 01488 case OB_FONT: 01489 ob->data= cu= copy_curve(ob->data); 01490 ID_NEW(cu->bevobj); 01491 ID_NEW(cu->taperobj); 01492 break; 01493 case OB_LATTICE: 01494 ob->data= copy_lattice(ob->data); 01495 break; 01496 case OB_ARMATURE: 01497 ob->recalc |= OB_RECALC_DATA; 01498 ob->data= copy_armature(ob->data); 01499 armature_rebuild_pose(ob, ob->data); 01500 break; 01501 case OB_SPEAKER: 01502 ob->data= copy_speaker(ob->data); 01503 break; 01504 default: 01505 if (G.f & G_DEBUG) 01506 printf("ERROR single_obdata_users: can't copy %s\n", id->name); 01507 return; 01508 } 01509 01510 id->us--; 01511 id->newid= ob->data; 01512 01513 } 01514 01515 } 01516 } 01517 01518 me= bmain->mesh.first; 01519 while(me) { 01520 ID_NEW(me->texcomesh); 01521 me= me->id.next; 01522 } 01523 } 01524 01525 static void single_object_action_users(Scene *scene, int flag) 01526 { 01527 Object *ob; 01528 Base *base; 01529 01530 for(base= FIRSTBASE; base; base= base->next) { 01531 ob= base->object; 01532 if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { 01533 ob->recalc= OB_RECALC_DATA; 01534 BKE_copy_animdata_id_action(&ob->id); 01535 } 01536 } 01537 } 01538 01539 static void single_mat_users(Scene *scene, int flag, int do_textures) 01540 { 01541 Object *ob; 01542 Base *base; 01543 Material *ma, *man; 01544 Tex *tex; 01545 int a, b; 01546 01547 for(base= FIRSTBASE; base; base= base->next) { 01548 ob= base->object; 01549 if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { 01550 01551 for(a=1; a<=ob->totcol; a++) { 01552 ma= give_current_material(ob, a); 01553 if(ma) { 01554 /* do not test for LIB_NEW: this functions guaranteed delivers single_users! */ 01555 01556 if(ma->id.us>1) { 01557 man= copy_material(ma); 01558 BKE_copy_animdata_id_action(&man->id); 01559 01560 man->id.us= 0; 01561 assign_material(ob, man, a); 01562 01563 if(do_textures) { 01564 for(b=0; b<MAX_MTEX; b++) { 01565 if(ma->mtex[b] && (tex= ma->mtex[b]->tex)) { 01566 if(tex->id.us>1) { 01567 tex->id.us--; 01568 tex= copy_texture(tex); 01569 BKE_copy_animdata_id_action(&tex->id); 01570 ma->mtex[b]->tex= tex; 01571 } 01572 } 01573 } 01574 } 01575 } 01576 } 01577 } 01578 } 01579 } 01580 } 01581 01582 static void do_single_tex_user(Tex **from) 01583 { 01584 Tex *tex, *texn; 01585 01586 tex= *from; 01587 if(tex==NULL) return; 01588 01589 if(tex->id.newid) { 01590 *from= (Tex *)tex->id.newid; 01591 id_us_plus(tex->id.newid); 01592 tex->id.us--; 01593 } 01594 else if(tex->id.us>1) { 01595 texn= copy_texture(tex); 01596 BKE_copy_animdata_id_action(&texn->id); 01597 tex->id.newid= (ID *)texn; 01598 tex->id.us--; 01599 *from= texn; 01600 } 01601 } 01602 01603 static void single_tex_users_expand(Main *bmain) 01604 { 01605 /* only when 'parent' blocks are LIB_NEW */ 01606 Material *ma; 01607 Lamp *la; 01608 World *wo; 01609 int b; 01610 01611 for(ma= bmain->mat.first; ma; ma=ma->id.next) { 01612 if(ma->id.flag & LIB_NEW) { 01613 for(b=0; b<MAX_MTEX; b++) { 01614 if(ma->mtex[b] && ma->mtex[b]->tex) { 01615 do_single_tex_user( &(ma->mtex[b]->tex) ); 01616 } 01617 } 01618 } 01619 } 01620 01621 for(la= bmain->lamp.first; la; la=la->id.next) { 01622 if(la->id.flag & LIB_NEW) { 01623 for(b=0; b<MAX_MTEX; b++) { 01624 if(la->mtex[b] && la->mtex[b]->tex) { 01625 do_single_tex_user( &(la->mtex[b]->tex) ); 01626 } 01627 } 01628 } 01629 } 01630 01631 for(wo= bmain->world.first; wo; wo=wo->id.next) { 01632 if(wo->id.flag & LIB_NEW) { 01633 for(b=0; b<MAX_MTEX; b++) { 01634 if(wo->mtex[b] && wo->mtex[b]->tex) { 01635 do_single_tex_user( &(wo->mtex[b]->tex) ); 01636 } 01637 } 01638 } 01639 } 01640 } 01641 01642 static void single_mat_users_expand(Main *bmain) 01643 { 01644 /* only when 'parent' blocks are LIB_NEW */ 01645 Object *ob; 01646 Mesh *me; 01647 Curve *cu; 01648 MetaBall *mb; 01649 Material *ma; 01650 int a; 01651 01652 for(ob=bmain->object.first; ob; ob=ob->id.next) 01653 if(ob->id.flag & LIB_NEW) 01654 new_id_matar(ob->mat, ob->totcol); 01655 01656 for(me=bmain->mesh.first; me; me=me->id.next) 01657 if(me->id.flag & LIB_NEW) 01658 new_id_matar(me->mat, me->totcol); 01659 01660 for(cu=bmain->curve.first; cu; cu=cu->id.next) 01661 if(cu->id.flag & LIB_NEW) 01662 new_id_matar(cu->mat, cu->totcol); 01663 01664 for(mb=bmain->mball.first; mb; mb=mb->id.next) 01665 if(mb->id.flag & LIB_NEW) 01666 new_id_matar(mb->mat, mb->totcol); 01667 01668 /* material imats */ 01669 for(ma=bmain->mat.first; ma; ma=ma->id.next) 01670 if(ma->id.flag & LIB_NEW) 01671 for(a=0; a<MAX_MTEX; a++) 01672 if(ma->mtex[a]) 01673 ID_NEW(ma->mtex[a]->object); 01674 } 01675 01676 /* used for copying scenes */ 01677 void ED_object_single_users(Main *bmain, Scene *scene, int full) 01678 { 01679 single_object_users(scene, NULL, 0); 01680 01681 if(full) { 01682 single_obdata_users(bmain, scene, 0); 01683 single_object_action_users(scene, 0); 01684 single_mat_users_expand(bmain); 01685 single_tex_users_expand(bmain); 01686 } 01687 01688 clear_id_newpoins(); 01689 } 01690 01691 /******************************* Make Local ***********************************/ 01692 01693 /* helper for below, ma was checked to be not NULL */ 01694 static void make_local_makelocalmaterial(Material *ma) 01695 { 01696 AnimData *adt; 01697 int b; 01698 01699 id_make_local(&ma->id, 0); 01700 01701 for(b=0; b<MAX_MTEX; b++) 01702 if(ma->mtex[b] && ma->mtex[b]->tex) 01703 id_make_local(&ma->mtex[b]->tex->id, 0); 01704 01705 adt= BKE_animdata_from_id(&ma->id); 01706 if(adt) BKE_animdata_make_local(adt); 01707 01708 /* nodetree? XXX */ 01709 } 01710 01711 static int make_local_exec(bContext *C, wmOperator *op) 01712 { 01713 Main *bmain= CTX_data_main(C); 01714 AnimData *adt; 01715 ParticleSystem *psys; 01716 Material *ma, ***matarar; 01717 Lamp *la; 01718 ID *id; 01719 int a, b, mode= RNA_enum_get(op->ptr, "type"); 01720 01721 if(mode==3) { 01722 BKE_library_make_local(bmain, NULL, 0); /* NULL is all libs */ 01723 WM_event_add_notifier(C, NC_WINDOW, NULL); 01724 return OPERATOR_FINISHED; 01725 } 01726 01727 clear_id_newpoins(); 01728 01729 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { 01730 if(ob->id.lib) 01731 id_make_local(&ob->id, 0); 01732 } 01733 CTX_DATA_END; 01734 01735 /* maybe object pointers */ 01736 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { 01737 if(ob->id.lib==NULL) { 01738 ID_NEW(ob->parent); 01739 } 01740 } 01741 CTX_DATA_END; 01742 01743 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { 01744 id= ob->data; 01745 01746 if(id && mode>1) { 01747 id_make_local(id, 0); 01748 adt= BKE_animdata_from_id(id); 01749 if(adt) BKE_animdata_make_local(adt); 01750 01751 /* tag indirect data direct */ 01752 matarar= (Material ***)give_matarar(ob); 01753 if(matarar) { 01754 for(a=0; a<ob->totcol; a++) { 01755 ma= (*matarar)[a]; 01756 if(ma) 01757 id_lib_extern(&ma->id); 01758 } 01759 } 01760 } 01761 01762 for(psys=ob->particlesystem.first; psys; psys=psys->next) 01763 id_make_local(&psys->part->id, 0); 01764 01765 adt= BKE_animdata_from_id(&ob->id); 01766 if(adt) BKE_animdata_make_local(adt); 01767 } 01768 CTX_DATA_END; 01769 01770 if(mode>1) { 01771 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { 01772 if(ob->type==OB_LAMP) { 01773 la= ob->data; 01774 01775 for(b=0; b<MAX_MTEX; b++) 01776 if(la->mtex[b] && la->mtex[b]->tex) 01777 id_make_local(&la->mtex[b]->tex->id, 0); 01778 } 01779 else { 01780 for(a=0; a<ob->totcol; a++) { 01781 ma= ob->mat[a]; 01782 if(ma) 01783 make_local_makelocalmaterial(ma); 01784 } 01785 01786 matarar= (Material ***)give_matarar(ob); 01787 if(matarar) { 01788 for(a=0; a<ob->totcol; a++) { 01789 ma= (*matarar)[a]; 01790 if(ma) 01791 make_local_makelocalmaterial(ma); 01792 } 01793 } 01794 } 01795 } 01796 CTX_DATA_END; 01797 } 01798 01799 WM_event_add_notifier(C, NC_WINDOW, NULL); 01800 01801 return OPERATOR_FINISHED; 01802 } 01803 01804 void OBJECT_OT_make_local(wmOperatorType *ot) 01805 { 01806 static EnumPropertyItem type_items[]= { 01807 {1, "SELECTED_OBJECTS", 0, "Selected Objects", ""}, 01808 {2, "SELECTED_OBJECTS_DATA", 0, "Selected Objects and Data", ""}, 01809 {3, "ALL", 0, "All", ""}, 01810 {0, NULL, 0, NULL, NULL}}; 01811 01812 /* identifiers */ 01813 ot->name= "Make Local"; 01814 ot->description = "Make library linked datablocks local to this file"; 01815 ot->idname= "OBJECT_OT_make_local"; 01816 01817 /* api callbacks */ 01818 ot->invoke= WM_menu_invoke; 01819 ot->exec= make_local_exec; 01820 ot->poll= ED_operator_objectmode; 01821 01822 /* flags */ 01823 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01824 01825 /* properties */ 01826 ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); 01827 } 01828 01829 static int make_single_user_exec(bContext *C, wmOperator *op) 01830 { 01831 Main *bmain= CTX_data_main(C); 01832 Scene *scene= CTX_data_scene(C); 01833 View3D *v3d= CTX_wm_view3d(C); /* ok if this is NULL */ 01834 int flag= RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */ 01835 01836 if(RNA_boolean_get(op->ptr, "object")) 01837 single_object_users(scene, v3d, flag); 01838 01839 if(RNA_boolean_get(op->ptr, "obdata")) 01840 single_obdata_users(bmain, scene, flag); 01841 01842 if(RNA_boolean_get(op->ptr, "material")) 01843 single_mat_users(scene, flag, RNA_boolean_get(op->ptr, "texture")); 01844 01845 #if 0 /* can't do this separate from materials */ 01846 if(RNA_boolean_get(op->ptr, "texture")) 01847 single_mat_users(scene, flag, TRUE); 01848 #endif 01849 if(RNA_boolean_get(op->ptr, "animation")) 01850 single_object_action_users(scene, flag); 01851 01852 clear_id_newpoins(); 01853 01854 WM_event_add_notifier(C, NC_WINDOW, NULL); 01855 return OPERATOR_FINISHED; 01856 } 01857 01858 void OBJECT_OT_make_single_user(wmOperatorType *ot) 01859 { 01860 static EnumPropertyItem type_items[]= { 01861 {SELECT, "SELECTED_OBJECTS", 0, "Selected Objects", ""}, 01862 {0, "ALL", 0, "All", ""}, 01863 {0, NULL, 0, NULL, NULL}}; 01864 01865 /* identifiers */ 01866 ot->name= "Make Single User"; 01867 ot->description = "Make linked data local to each object"; 01868 ot->idname= "OBJECT_OT_make_single_user"; 01869 01870 /* api callbacks */ 01871 ot->invoke= WM_menu_invoke; 01872 ot->exec= make_single_user_exec; 01873 ot->poll= ED_operator_objectmode; 01874 01875 /* flags */ 01876 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01877 01878 /* properties */ 01879 ot->prop= RNA_def_enum(ot->srna, "type", type_items, SELECT, "Type", ""); 01880 01881 RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects"); 01882 RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data"); 01883 RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each datablock"); 01884 RNA_def_boolean(ot->srna, "texture", 0, "Textures", "Make textures local to each material"); 01885 RNA_def_boolean(ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object"); 01886 } 01887 01888 static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event) 01889 { 01890 Main *bmain= CTX_data_main(C); 01891 Base *base= ED_view3d_give_base_under_cursor(C, event->mval); 01892 Material *ma; 01893 char name[MAX_ID_NAME-2]; 01894 01895 RNA_string_get(op->ptr, "name", name); 01896 ma= (Material *)find_id("MA", name); 01897 if(base==NULL || ma==NULL) 01898 return OPERATOR_CANCELLED; 01899 01900 assign_material(base->object, ma, 1); 01901 01902 DAG_ids_flush_update(bmain, 0); 01903 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); 01904 01905 return OPERATOR_FINISHED; 01906 } 01907 01908 /* used for dropbox */ 01909 /* assigns to object under cursor, only first material slot */ 01910 void OBJECT_OT_drop_named_material(wmOperatorType *ot) 01911 { 01912 01913 /* identifiers */ 01914 ot->name= "Drop Named Material on Object"; 01915 ot->description = ""; 01916 ot->idname= "OBJECT_OT_drop_named_material"; 01917 01918 /* api callbacks */ 01919 ot->invoke= drop_named_material_invoke; 01920 ot->poll= ED_operator_objectmode; 01921 01922 /* flags */ 01923 ot->flag= OPTYPE_UNDO; 01924 01925 /* properties */ 01926 RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME-2, "Name", "Material name to assign"); 01927 }