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