Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation, 2002-2008 full recode 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdlib.h> 00032 #include <string.h> 00033 00034 #include "MEM_guardedalloc.h" 00035 00036 #include "BLI_math.h" 00037 #include "BLI_editVert.h" 00038 #include "BLI_listbase.h" 00039 #include "BLI_string.h" 00040 #include "BLI_utildefines.h" 00041 00042 #include "DNA_curve_types.h" 00043 #include "DNA_lattice_types.h" 00044 #include "DNA_meshdata_types.h" 00045 #include "DNA_object_types.h" 00046 #include "DNA_scene_types.h" 00047 00048 #include "BKE_action.h" 00049 #include "BKE_context.h" 00050 #include "BKE_depsgraph.h" 00051 #include "BKE_main.h" 00052 #include "BKE_mesh.h" 00053 #include "BKE_modifier.h" 00054 #include "BKE_object.h" 00055 #include "BKE_report.h" 00056 #include "BKE_scene.h" 00057 #include "BKE_deform.h" 00058 00059 #include "RNA_define.h" 00060 #include "RNA_access.h" 00061 #include "RNA_enum_types.h" 00062 00063 #include "ED_curve.h" 00064 #include "ED_mesh.h" 00065 #include "ED_screen.h" 00066 00067 #include "WM_types.h" 00068 #include "WM_api.h" 00069 00070 #include "UI_resources.h" 00071 00072 #include "object_intern.h" 00073 00074 static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent) 00075 { 00076 EditVert *eve; 00077 int *index, nr, totvert=0; 00078 00079 for(eve= em->verts.first; eve; eve= eve->next) { 00080 if(eve->f & SELECT) totvert++; 00081 } 00082 if(totvert==0) return 0; 00083 00084 *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); 00085 *tot= totvert; 00086 nr= 0; 00087 zero_v3(cent); 00088 00089 for(eve= em->verts.first; eve; eve= eve->next) { 00090 if(eve->f & SELECT) { 00091 *index= nr; index++; 00092 add_v3_v3(cent, eve->co); 00093 } 00094 nr++; 00095 } 00096 00097 mul_v3_fl(cent, 1.0f/(float)totvert); 00098 00099 return totvert; 00100 } 00101 00102 static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent) 00103 { 00104 zero_v3(cent); 00105 00106 if(obedit->actdef) { 00107 const int defgrp_index= obedit->actdef-1; 00108 int totvert=0; 00109 00110 MDeformVert *dvert; 00111 EditVert *eve; 00112 00113 /* find the vertices */ 00114 for(eve= em->verts.first; eve; eve= eve->next) { 00115 dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); 00116 00117 if(dvert) { 00118 if(defvert_find_weight(dvert, defgrp_index) > 0.0f) { 00119 add_v3_v3(cent, eve->co); 00120 totvert++; 00121 } 00122 } 00123 } 00124 if(totvert) { 00125 bDeformGroup *dg = BLI_findlink(&obedit->defbase, defgrp_index); 00126 BLI_strncpy(name, dg->name, sizeof(dg->name)); 00127 mul_v3_fl(cent, 1.0f/(float)totvert); 00128 return 1; 00129 } 00130 } 00131 00132 return 0; 00133 } 00134 00135 static void select_editmesh_hook(Object *ob, HookModifierData *hmd) 00136 { 00137 Mesh *me= ob->data; 00138 EditMesh *em= BKE_mesh_get_editmesh(me); 00139 EditVert *eve; 00140 int index=0, nr=0; 00141 00142 if (hmd->indexar == NULL) 00143 return; 00144 00145 for(eve= em->verts.first; eve; eve= eve->next, nr++) { 00146 if(nr==hmd->indexar[index]) { 00147 eve->f |= SELECT; 00148 if(index < hmd->totindex-1) index++; 00149 } 00150 } 00151 EM_select_flush(em); 00152 00153 BKE_mesh_end_editmesh(me, em); 00154 } 00155 00156 static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent) 00157 { 00158 BPoint *bp; 00159 int *index, nr, totvert=0, a; 00160 00161 /* count */ 00162 a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; 00163 bp= editlatt->def; 00164 while(a--) { 00165 if(bp->f1 & SELECT) { 00166 if(bp->hide==0) totvert++; 00167 } 00168 bp++; 00169 } 00170 00171 if(totvert==0) return 0; 00172 00173 *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); 00174 *tot= totvert; 00175 nr= 0; 00176 cent[0]= cent[1]= cent[2]= 0.0; 00177 00178 a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; 00179 bp= editlatt->def; 00180 while(a--) { 00181 if(bp->f1 & SELECT) { 00182 if(bp->hide==0) { 00183 *index= nr; index++; 00184 add_v3_v3(cent, bp->vec); 00185 } 00186 } 00187 bp++; 00188 nr++; 00189 } 00190 00191 mul_v3_fl(cent, 1.0f/(float)totvert); 00192 00193 return totvert; 00194 } 00195 00196 static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) 00197 { 00198 Lattice *lt= obedit->data, *editlt; 00199 BPoint *bp; 00200 int index=0, nr=0, a; 00201 00202 editlt= lt->editlatt->latt; 00203 /* count */ 00204 a= editlt->pntsu*editlt->pntsv*editlt->pntsw; 00205 bp= editlt->def; 00206 while(a--) { 00207 if(hmd->indexar[index]==nr) { 00208 bp->f1 |= SELECT; 00209 if(index < hmd->totindex-1) index++; 00210 } 00211 nr++; 00212 bp++; 00213 } 00214 } 00215 00216 static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, float *cent) 00217 { 00218 ListBase *editnurb= object_editcurve_get(obedit); 00219 Nurb *nu; 00220 BPoint *bp; 00221 BezTriple *bezt; 00222 int *index, a, nr, totvert=0; 00223 00224 for(nu= editnurb->first; nu; nu= nu->next) { 00225 if(nu->type == CU_BEZIER) { 00226 bezt= nu->bezt; 00227 a= nu->pntsu; 00228 while(a--) { 00229 if(bezt->f1 & SELECT) totvert++; 00230 if(bezt->f2 & SELECT) totvert++; 00231 if(bezt->f3 & SELECT) totvert++; 00232 bezt++; 00233 } 00234 } 00235 else { 00236 bp= nu->bp; 00237 a= nu->pntsu*nu->pntsv; 00238 while(a--) { 00239 if(bp->f1 & SELECT) totvert++; 00240 bp++; 00241 } 00242 } 00243 } 00244 if(totvert==0) return 0; 00245 00246 *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); 00247 *tot= totvert; 00248 nr= 0; 00249 cent[0]= cent[1]= cent[2]= 0.0; 00250 00251 for(nu= editnurb->first; nu; nu= nu->next) { 00252 if(nu->type == CU_BEZIER) { 00253 bezt= nu->bezt; 00254 a= nu->pntsu; 00255 while(a--) { 00256 if(bezt->f1 & SELECT) { 00257 *index= nr; index++; 00258 add_v3_v3(cent, bezt->vec[0]); 00259 } 00260 nr++; 00261 if(bezt->f2 & SELECT) { 00262 *index= nr; index++; 00263 add_v3_v3(cent, bezt->vec[1]); 00264 } 00265 nr++; 00266 if(bezt->f3 & SELECT) { 00267 *index= nr; index++; 00268 add_v3_v3(cent, bezt->vec[2]); 00269 } 00270 nr++; 00271 bezt++; 00272 } 00273 } 00274 else { 00275 bp= nu->bp; 00276 a= nu->pntsu*nu->pntsv; 00277 while(a--) { 00278 if(bp->f1 & SELECT) { 00279 *index= nr; index++; 00280 add_v3_v3(cent, bp->vec); 00281 } 00282 nr++; 00283 bp++; 00284 } 00285 } 00286 } 00287 00288 mul_v3_fl(cent, 1.0f/(float)totvert); 00289 00290 return totvert; 00291 } 00292 00293 static int object_hook_index_array(Scene *scene, Object *obedit, int *tot, int **indexar, char *name, float *cent_r) 00294 { 00295 *indexar= NULL; 00296 *tot= 0; 00297 name[0]= 0; 00298 00299 switch(obedit->type) { 00300 case OB_MESH: 00301 { 00302 Mesh *me= obedit->data; 00303 EditMesh *em; 00304 00305 load_editMesh(scene, obedit); 00306 make_editMesh(scene, obedit); 00307 00308 em = BKE_mesh_get_editmesh(me); 00309 00310 /* check selected vertices first */ 00311 if( return_editmesh_indexar(em, tot, indexar, cent_r)) { 00312 BKE_mesh_end_editmesh(me, em); 00313 return 1; 00314 } else { 00315 int ret = return_editmesh_vgroup(obedit, em, name, cent_r); 00316 BKE_mesh_end_editmesh(me, em); 00317 return ret; 00318 } 00319 } 00320 case OB_CURVE: 00321 case OB_SURF: 00322 return return_editcurve_indexar(obedit, tot, indexar, cent_r); 00323 case OB_LATTICE: 00324 { 00325 Lattice *lt= obedit->data; 00326 return return_editlattice_indexar(lt->editlatt->latt, tot, indexar, cent_r); 00327 } 00328 default: 00329 return 0; 00330 } 00331 } 00332 00333 static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) 00334 { 00335 ListBase *editnurb= object_editcurve_get(obedit); 00336 Nurb *nu; 00337 BPoint *bp; 00338 BezTriple *bezt; 00339 int index=0, a, nr=0; 00340 00341 for(nu= editnurb->first; nu; nu= nu->next) { 00342 if(nu->type == CU_BEZIER) { 00343 bezt= nu->bezt; 00344 a= nu->pntsu; 00345 while(a--) { 00346 if(nr == hmd->indexar[index]) { 00347 bezt->f1 |= SELECT; 00348 if(index<hmd->totindex-1) index++; 00349 } 00350 nr++; 00351 if(nr == hmd->indexar[index]) { 00352 bezt->f2 |= SELECT; 00353 if(index<hmd->totindex-1) index++; 00354 } 00355 nr++; 00356 if(nr == hmd->indexar[index]) { 00357 bezt->f3 |= SELECT; 00358 if(index<hmd->totindex-1) index++; 00359 } 00360 nr++; 00361 00362 bezt++; 00363 } 00364 } 00365 else { 00366 bp= nu->bp; 00367 a= nu->pntsu*nu->pntsv; 00368 while(a--) { 00369 if(nr == hmd->indexar[index]) { 00370 bp->f1 |= SELECT; 00371 if(index<hmd->totindex-1) index++; 00372 } 00373 nr++; 00374 bp++; 00375 } 00376 } 00377 } 00378 } 00379 00380 static void object_hook_select(Object *ob, HookModifierData *hmd) 00381 { 00382 if (hmd->indexar == NULL) 00383 return; 00384 00385 if(ob->type==OB_MESH) select_editmesh_hook(ob, hmd); 00386 else if(ob->type==OB_LATTICE) select_editlattice_hook(ob, hmd); 00387 else if(ob->type==OB_CURVE) select_editcurve_hook(ob, hmd); 00388 else if(ob->type==OB_SURF) select_editcurve_hook(ob, hmd); 00389 } 00390 00391 /* special poll operators for hook operators */ 00392 // TODO: check for properties window modifier context too as alternative? 00393 static int hook_op_edit_poll(bContext *C) 00394 { 00395 Object *obedit= CTX_data_edit_object(C); 00396 00397 if (obedit) { 00398 if (ED_operator_editmesh(C)) return 1; 00399 if (ED_operator_editsurfcurve(C)) return 1; 00400 if (ED_operator_editlattice(C)) return 1; 00401 //if (ED_operator_editmball(C)) return 1; 00402 } 00403 00404 return 0; 00405 } 00406 00407 static Object *add_hook_object_new(Scene *scene, Object *obedit) 00408 { 00409 Base *base, *basedit; 00410 Object *ob; 00411 00412 ob= add_object(scene, OB_EMPTY); 00413 00414 basedit = object_in_scene(obedit, scene); 00415 base = object_in_scene(ob, scene); 00416 base->lay = ob->lay = obedit->lay; 00417 00418 /* icky, add_object sets new base as active. 00419 * so set it back to the original edit object */ 00420 scene->basact = basedit; 00421 00422 return ob; 00423 } 00424 00425 static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode) 00426 { 00427 ModifierData *md=NULL; 00428 HookModifierData *hmd = NULL; 00429 float cent[3]; 00430 int tot, ok, *indexar; 00431 char name[MAX_NAME]; 00432 00433 ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); 00434 00435 if (!ok) return; // XXX error("Requires selected vertices or active Vertex Group"); 00436 00437 if (mode==OBJECT_ADDHOOK_NEWOB && !ob) { 00438 00439 ob = add_hook_object_new(scene, obedit); 00440 00441 /* transform cent to global coords for loc */ 00442 mul_v3_m4v3(ob->loc, obedit->obmat, cent); 00443 } 00444 00445 md = obedit->modifiers.first; 00446 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { 00447 md = md->next; 00448 } 00449 00450 hmd = (HookModifierData*) modifier_new(eModifierType_Hook); 00451 BLI_insertlinkbefore(&obedit->modifiers, md, hmd); 00452 BLI_snprintf(hmd->modifier.name, sizeof(hmd->modifier.name), "Hook-%s", ob->id.name+2); 00453 modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); 00454 00455 hmd->object= ob; 00456 hmd->indexar= indexar; 00457 copy_v3_v3(hmd->cent, cent); 00458 hmd->totindex= tot; 00459 BLI_strncpy(hmd->name, name, sizeof(hmd->name)); 00460 00461 /* matrix calculus */ 00462 /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ 00463 /* (parentinv ) */ 00464 where_is_object(scene, ob); 00465 00466 invert_m4_m4(ob->imat, ob->obmat); 00467 /* apparently this call goes from right to left... */ 00468 mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, 00469 NULL, NULL, NULL, NULL, NULL); 00470 00471 DAG_scene_sort(bmain, scene); 00472 } 00473 00474 static int object_add_hook_selob_exec(bContext *C, wmOperator *op) 00475 { 00476 Main *bmain= CTX_data_main(C); 00477 Scene *scene= CTX_data_scene(C); 00478 Object *obedit = CTX_data_edit_object(C); 00479 Object *obsel=NULL; 00480 00481 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) 00482 { 00483 if (ob != obedit) { 00484 obsel = ob; 00485 break; 00486 } 00487 } 00488 CTX_DATA_END; 00489 00490 if (!obsel) { 00491 BKE_report(op->reports, RPT_ERROR, "Can't add hook with no other selected objects"); 00492 return OPERATOR_CANCELLED; 00493 } 00494 00495 add_hook_object(bmain, scene, obedit, obsel, OBJECT_ADDHOOK_SELOB); 00496 00497 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, obedit); 00498 return OPERATOR_FINISHED; 00499 } 00500 00501 void OBJECT_OT_hook_add_selobj(wmOperatorType *ot) 00502 { 00503 /* identifiers */ 00504 ot->name= "Hook to Selected Object"; 00505 ot->description= "Hook selected vertices to the first selected Object"; 00506 ot->idname= "OBJECT_OT_hook_add_selob"; 00507 00508 /* api callbacks */ 00509 ot->exec= object_add_hook_selob_exec; 00510 ot->poll= hook_op_edit_poll; 00511 00512 /* flags */ 00513 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00514 } 00515 00516 static int object_add_hook_newob_exec(bContext *C, wmOperator *UNUSED(op)) 00517 { 00518 Main *bmain= CTX_data_main(C); 00519 Scene *scene= CTX_data_scene(C); 00520 Object *obedit = CTX_data_edit_object(C); 00521 00522 add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB); 00523 00524 WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); 00525 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, obedit); 00526 return OPERATOR_FINISHED; 00527 } 00528 00529 void OBJECT_OT_hook_add_newobj(wmOperatorType *ot) 00530 { 00531 /* identifiers */ 00532 ot->name= "Hook to New Object"; 00533 ot->description= "Hook selected vertices to the first selected Object"; 00534 ot->idname= "OBJECT_OT_hook_add_newob"; 00535 00536 /* api callbacks */ 00537 ot->exec= object_add_hook_newob_exec; 00538 ot->poll= hook_op_edit_poll; 00539 00540 /* flags */ 00541 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00542 } 00543 00544 static int object_hook_remove_exec(bContext *C, wmOperator *op) 00545 { 00546 int num= RNA_enum_get(op->ptr, "modifier"); 00547 Object *ob=NULL; 00548 HookModifierData *hmd=NULL; 00549 00550 ob = CTX_data_edit_object(C); 00551 hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); 00552 00553 if (!ob || !hmd) { 00554 BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); 00555 return OPERATOR_CANCELLED; 00556 } 00557 00558 /* remove functionality */ 00559 00560 BLI_remlink(&ob->modifiers, (ModifierData *)hmd); 00561 modifier_free((ModifierData *)hmd); 00562 00563 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00564 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00565 00566 return OPERATOR_FINISHED; 00567 } 00568 00569 static EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) 00570 { 00571 Object *ob = CTX_data_edit_object(C); 00572 EnumPropertyItem tmp = {0, "", 0, "", ""}; 00573 EnumPropertyItem *item= NULL; 00574 ModifierData *md = NULL; 00575 int a, totitem= 0; 00576 00577 if(!ob) 00578 return DummyRNA_NULL_items; 00579 00580 for(a=0, md=ob->modifiers.first; md; md= md->next, a++) { 00581 if (md->type==eModifierType_Hook) { 00582 tmp.value= a; 00583 tmp.icon = ICON_HOOK; 00584 tmp.identifier= md->name; 00585 tmp.name= md->name; 00586 RNA_enum_item_add(&item, &totitem, &tmp); 00587 } 00588 } 00589 00590 RNA_enum_item_end(&item, &totitem); 00591 *free= 1; 00592 00593 return item; 00594 } 00595 00596 void OBJECT_OT_hook_remove(wmOperatorType *ot) 00597 { 00598 PropertyRNA *prop; 00599 00600 /* identifiers */ 00601 ot->name= "Remove Hook"; 00602 ot->idname= "OBJECT_OT_hook_remove"; 00603 ot->description= "Remove a hook from the active object"; 00604 00605 /* api callbacks */ 00606 ot->exec= object_hook_remove_exec; 00607 ot->invoke= WM_menu_invoke; 00608 ot->poll= hook_op_edit_poll; 00609 00610 /* flags */ 00611 /* this operator removes modifier which isn't stored in local undo stack, 00612 so redoing it from redo panel gives totally weird results */ 00613 ot->flag= /*OPTYPE_REGISTER|*/OPTYPE_UNDO; 00614 00615 /* properties */ 00616 prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove"); 00617 RNA_def_enum_funcs(prop, hook_mod_itemf); 00618 ot->prop= prop; 00619 } 00620 00621 static int object_hook_reset_exec(bContext *C, wmOperator *op) 00622 { 00623 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); 00624 int num= RNA_enum_get(op->ptr, "modifier"); 00625 Object *ob=NULL; 00626 HookModifierData *hmd=NULL; 00627 00628 if (ptr.data) { /* if modifier context is available, use that */ 00629 ob = ptr.id.data; 00630 hmd= ptr.data; 00631 } 00632 else { /* use the provided property */ 00633 ob = CTX_data_edit_object(C); 00634 hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); 00635 } 00636 if (!ob || !hmd) { 00637 BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); 00638 return OPERATOR_CANCELLED; 00639 } 00640 00641 /* reset functionality */ 00642 if(hmd->object) { 00643 bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); 00644 00645 if(hmd->subtarget[0] && pchan) { 00646 float imat[4][4], mat[4][4]; 00647 00648 /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ 00649 mult_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); 00650 00651 invert_m4_m4(imat, mat); 00652 mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); 00653 } 00654 else { 00655 invert_m4_m4(hmd->object->imat, hmd->object->obmat); 00656 mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); 00657 } 00658 } 00659 00660 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00661 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00662 00663 return OPERATOR_FINISHED; 00664 } 00665 00666 void OBJECT_OT_hook_reset(wmOperatorType *ot) 00667 { 00668 PropertyRNA *prop; 00669 00670 /* identifiers */ 00671 ot->name= "Reset Hook"; 00672 ot->description= "Recalculate and clear offset transformation"; 00673 ot->idname= "OBJECT_OT_hook_reset"; 00674 00675 /* callbacks */ 00676 ot->exec= object_hook_reset_exec; 00677 ot->poll= hook_op_edit_poll; 00678 00679 /* flags */ 00680 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00681 00682 /* properties */ 00683 prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to"); 00684 RNA_def_enum_funcs(prop, hook_mod_itemf); 00685 } 00686 00687 static int object_hook_recenter_exec(bContext *C, wmOperator *op) 00688 { 00689 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); 00690 int num= RNA_enum_get(op->ptr, "modifier"); 00691 Object *ob=NULL; 00692 HookModifierData *hmd=NULL; 00693 Scene *scene = CTX_data_scene(C); 00694 float bmat[3][3], imat[3][3]; 00695 00696 if (ptr.data) { /* if modifier context is available, use that */ 00697 ob = ptr.id.data; 00698 hmd= ptr.data; 00699 } 00700 else { /* use the provided property */ 00701 ob = CTX_data_edit_object(C); 00702 hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); 00703 } 00704 if (!ob || !hmd) { 00705 BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); 00706 return OPERATOR_CANCELLED; 00707 } 00708 00709 /* recenter functionality */ 00710 copy_m3_m4(bmat, ob->obmat); 00711 invert_m3_m3(imat, bmat); 00712 00713 sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]); 00714 mul_m3_v3(imat, hmd->cent); 00715 00716 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00717 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00718 00719 return OPERATOR_FINISHED; 00720 } 00721 00722 void OBJECT_OT_hook_recenter(wmOperatorType *ot) 00723 { 00724 PropertyRNA *prop; 00725 00726 /* identifiers */ 00727 ot->name= "Recenter Hook"; 00728 ot->description= "Set hook center to cursor position"; 00729 ot->idname= "OBJECT_OT_hook_recenter"; 00730 00731 /* callbacks */ 00732 ot->exec= object_hook_recenter_exec; 00733 ot->poll= hook_op_edit_poll; 00734 00735 /* flags */ 00736 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00737 00738 /* properties */ 00739 prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to"); 00740 RNA_def_enum_funcs(prop, hook_mod_itemf); 00741 } 00742 00743 static int object_hook_assign_exec(bContext *C, wmOperator *op) 00744 { 00745 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); 00746 int num= RNA_enum_get(op->ptr, "modifier"); 00747 Object *ob=NULL; 00748 HookModifierData *hmd=NULL; 00749 float cent[3]; 00750 char name[MAX_NAME]; 00751 int *indexar, tot; 00752 00753 if (ptr.data) { /* if modifier context is available, use that */ 00754 ob = ptr.id.data; 00755 hmd= ptr.data; 00756 } 00757 else { /* use the provided property */ 00758 ob = CTX_data_edit_object(C); 00759 hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); 00760 } 00761 if (!ob || !hmd) { 00762 BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); 00763 return OPERATOR_CANCELLED; 00764 } 00765 00766 /* assign functionality */ 00767 00768 if(!object_hook_index_array(CTX_data_scene(C), ob, &tot, &indexar, name, cent)) { 00769 BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group"); 00770 return OPERATOR_CANCELLED; 00771 } 00772 if(hmd->indexar) 00773 MEM_freeN(hmd->indexar); 00774 00775 copy_v3_v3(hmd->cent, cent); 00776 hmd->indexar= indexar; 00777 hmd->totindex= tot; 00778 00779 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00780 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); 00781 00782 return OPERATOR_FINISHED; 00783 } 00784 00785 void OBJECT_OT_hook_assign(wmOperatorType *ot) 00786 { 00787 PropertyRNA *prop; 00788 00789 /* identifiers */ 00790 ot->name= "Assign to Hook"; 00791 ot->description= "Assign the selected vertices to a hook"; 00792 ot->idname= "OBJECT_OT_hook_assign"; 00793 00794 /* callbacks */ 00795 ot->exec= object_hook_assign_exec; 00796 ot->poll= hook_op_edit_poll; 00797 00798 /* flags */ 00799 /* this operator changes data stored in modifier which doesn't get pushed to undo stack, 00800 so redoing it from redo panel gives totally weird results */ 00801 ot->flag= /*OPTYPE_REGISTER|*/OPTYPE_UNDO; 00802 00803 /* properties */ 00804 prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to"); 00805 RNA_def_enum_funcs(prop, hook_mod_itemf); 00806 } 00807 00808 static int object_hook_select_exec(bContext *C, wmOperator *op) 00809 { 00810 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); 00811 int num= RNA_enum_get(op->ptr, "modifier"); 00812 Object *ob=NULL; 00813 HookModifierData *hmd=NULL; 00814 00815 if (ptr.data) { /* if modifier context is available, use that */ 00816 ob = ptr.id.data; 00817 hmd= ptr.data; 00818 } 00819 else { /* use the provided property */ 00820 ob = CTX_data_edit_object(C); 00821 hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); 00822 } 00823 if (!ob || !hmd) { 00824 BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); 00825 return OPERATOR_CANCELLED; 00826 } 00827 00828 /* select functionality */ 00829 object_hook_select(ob, hmd); 00830 00831 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); 00832 00833 return OPERATOR_FINISHED; 00834 } 00835 00836 void OBJECT_OT_hook_select(wmOperatorType *ot) 00837 { 00838 PropertyRNA *prop; 00839 00840 /* identifiers */ 00841 ot->name= "Select Hook"; 00842 ot->description= "Select affected vertices on mesh"; 00843 ot->idname= "OBJECT_OT_hook_select"; 00844 00845 /* callbacks */ 00846 ot->exec= object_hook_select_exec; 00847 ot->poll= hook_op_edit_poll; 00848 00849 /* flags */ 00850 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00851 00852 /* properties */ 00853 prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove"); 00854 RNA_def_enum_funcs(prop, hook_mod_itemf); 00855 } 00856