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 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <string.h> 00035 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "DNA_armature_types.h" 00039 #include "DNA_curve_types.h" 00040 #include "DNA_lattice_types.h" 00041 #include "DNA_meta_types.h" 00042 #include "DNA_scene_types.h" 00043 #include "DNA_object_types.h" 00044 00045 #include "BLI_blenlib.h" 00046 #include "BLI_math.h" 00047 #include "BLI_editVert.h" 00048 #include "BLI_linklist.h" 00049 #include "BLI_utildefines.h" 00050 00051 #include "BKE_armature.h" 00052 #include "BKE_context.h" 00053 #include "BKE_curve.h" 00054 #include "BKE_depsgraph.h" 00055 #include "BKE_lattice.h" 00056 #include "BKE_main.h" 00057 #include "BKE_object.h" 00058 #include "BKE_scene.h" 00059 #include "BKE_tracking.h" 00060 00061 #include "WM_api.h" 00062 #include "WM_types.h" 00063 00064 00065 00066 #include "ED_armature.h" 00067 #include "ED_mesh.h" 00068 #include "ED_keyframing.h" 00069 #include "ED_screen.h" 00070 #include "ED_curve.h" /* for curve_editnurbs */ 00071 00072 #include "view3d_intern.h" 00073 00074 extern float originmat[3][3]; /* XXX object.c */ 00075 00076 /* ************************************************** */ 00077 /* ********************* old transform stuff ******** */ 00078 /* *********** will get replaced with new transform * */ 00079 /* ************************************************** */ 00080 00081 typedef struct TransVert { 00082 float *loc; 00083 float oldloc[3], fac; 00084 float *val, oldval; 00085 int flag; 00086 float *nor; 00087 } TransVert; 00088 00089 static TransVert *transvmain=NULL; 00090 static int tottrans= 0; 00091 00092 /* copied from editobject.c, now uses (almost) proper depgraph */ 00093 static void special_transvert_update(Object *obedit) 00094 { 00095 if(obedit) { 00096 DAG_id_tag_update(obedit->data, 0); 00097 00098 if(obedit->type==OB_MESH) { 00099 Mesh *me= obedit->data; 00100 recalc_editnormals(me->edit_mesh); // does face centers too 00101 } 00102 else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { 00103 Curve *cu= obedit->data; 00104 ListBase *nurbs= curve_editnurbs(cu); 00105 Nurb *nu= nurbs->first; 00106 00107 while(nu) { 00108 /* keep handles' vectors unchanged */ 00109 if(nu->bezt) { 00110 int a= nu->pntsu; 00111 TransVert *tv= transvmain; 00112 BezTriple *bezt= nu->bezt; 00113 00114 while(a--) { 00115 if(bezt->f1 & SELECT) tv++; 00116 00117 if(bezt->f2 & SELECT) { 00118 float v[3]; 00119 00120 if(bezt->f1 & SELECT) { 00121 sub_v3_v3v3(v, (tv-1)->oldloc, tv->oldloc); 00122 add_v3_v3v3(bezt->vec[0], bezt->vec[1], v); 00123 } 00124 00125 if(bezt->f3 & SELECT) { 00126 sub_v3_v3v3(v, (tv+1)->oldloc, tv->oldloc); 00127 add_v3_v3v3(bezt->vec[2], bezt->vec[1], v); 00128 } 00129 00130 tv++; 00131 } 00132 00133 if(bezt->f3 & SELECT) tv++; 00134 00135 bezt++; 00136 } 00137 } 00138 00139 test2DNurb(nu); 00140 testhandlesNurb(nu); /* test for bezier too */ 00141 nu= nu->next; 00142 } 00143 } 00144 else if(obedit->type==OB_ARMATURE){ 00145 bArmature *arm= obedit->data; 00146 EditBone *ebo; 00147 TransVert *tv= transvmain; 00148 int a=0; 00149 00150 /* Ensure all bone tails are correctly adjusted */ 00151 for (ebo= arm->edbo->first; ebo; ebo=ebo->next) { 00152 /* adjust tip if both ends selected */ 00153 if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) { 00154 if (tv) { 00155 float diffvec[3]; 00156 00157 sub_v3_v3v3(diffvec, tv->loc, tv->oldloc); 00158 add_v3_v3(ebo->tail, diffvec); 00159 00160 a++; 00161 if (a<tottrans) tv++; 00162 } 00163 } 00164 } 00165 00166 /* Ensure all bones are correctly adjusted */ 00167 for (ebo= arm->edbo->first; ebo; ebo=ebo->next) { 00168 if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ 00169 /* If this bone has a parent tip that has been moved */ 00170 if (ebo->parent->flag & BONE_TIPSEL){ 00171 copy_v3_v3(ebo->head, ebo->parent->tail); 00172 } 00173 /* If this bone has a parent tip that has NOT been moved */ 00174 else{ 00175 copy_v3_v3(ebo->parent->tail, ebo->head); 00176 } 00177 } 00178 } 00179 if(arm->flag & ARM_MIRROR_EDIT) 00180 transform_armature_mirror_update(obedit); 00181 } 00182 else if(obedit->type==OB_LATTICE) { 00183 Lattice *lt= obedit->data; 00184 00185 if(lt->editlatt->latt->flag & LT_OUTSIDE) 00186 outside_lattice(lt->editlatt->latt); 00187 } 00188 } 00189 } 00190 00191 /* copied from editobject.c, needs to be replaced with new transform code still */ 00192 /* mode flags: */ 00193 #define TM_ALL_JOINTS 1 /* all joints (for bones only) */ 00194 #define TM_SKIP_HANDLES 2 /* skip handles when control point is selected (for curves only) */ 00195 static void make_trans_verts(Object *obedit, float *min, float *max, int mode) 00196 { 00197 Nurb *nu; 00198 BezTriple *bezt; 00199 BPoint *bp; 00200 TransVert *tv=NULL; 00201 MetaElem *ml; 00202 EditVert *eve; 00203 EditBone *ebo; 00204 float total, center[3], centroid[3]; 00205 int a; 00206 00207 tottrans= 0; // global! 00208 00209 INIT_MINMAX(min, max); 00210 centroid[0]=centroid[1]=centroid[2]= 0.0; 00211 00212 if(obedit->type==OB_MESH) { 00213 Mesh *me= obedit->data; 00214 EditMesh *em= me->edit_mesh; 00215 00216 // transform now requires awareness for select mode, so we tag the f1 flags in verts 00217 tottrans= 0; 00218 if(em->selectmode & SCE_SELECT_VERTEX) { 00219 for(eve= em->verts.first; eve; eve= eve->next) { 00220 if(eve->h==0 && (eve->f & SELECT)) { 00221 eve->f1= SELECT; 00222 tottrans++; 00223 } 00224 else eve->f1= 0; 00225 } 00226 } 00227 else if(em->selectmode & SCE_SELECT_EDGE) { 00228 EditEdge *eed; 00229 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; 00230 for(eed= em->edges.first; eed; eed= eed->next) { 00231 if(eed->h==0 && (eed->f & SELECT)) eed->v1->f1= eed->v2->f1= SELECT; 00232 } 00233 for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; 00234 } 00235 else { 00236 EditFace *efa; 00237 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; 00238 for(efa= em->faces.first; efa; efa= efa->next) { 00239 if(efa->h==0 && (efa->f & SELECT)) { 00240 efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT; 00241 if(efa->v4) efa->v4->f1= SELECT; 00242 } 00243 } 00244 for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; 00245 } 00246 00247 /* and now make transverts */ 00248 if(tottrans) { 00249 tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); 00250 00251 for(eve= em->verts.first; eve; eve= eve->next) { 00252 if(eve->f1) { 00253 copy_v3_v3(tv->oldloc, eve->co); 00254 tv->loc= eve->co; 00255 if(eve->no[0] != 0.0f || eve->no[1] != 0.0f ||eve->no[2] != 0.0f) 00256 tv->nor= eve->no; // note this is a hackish signal (ton) 00257 tv->flag= eve->f1 & SELECT; 00258 tv++; 00259 } 00260 } 00261 } 00262 } 00263 else if (obedit->type==OB_ARMATURE){ 00264 bArmature *arm= obedit->data; 00265 int totmalloc= BLI_countlist(arm->edbo); 00266 00267 totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */ 00268 00269 tv=transvmain= MEM_callocN(totmalloc*sizeof(TransVert), "maketransverts armature"); 00270 00271 for (ebo= arm->edbo->first; ebo; ebo=ebo->next){ 00272 if(ebo->layer & arm->layer) { 00273 short tipsel= (ebo->flag & BONE_TIPSEL); 00274 short rootsel= (ebo->flag & BONE_ROOTSEL); 00275 short rootok= (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)); 00276 00277 if ((tipsel && rootsel) || (rootsel)) { 00278 /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints), 00279 * otherwise we get zero-length bones as tips will snap to the same 00280 * location as heads. 00281 */ 00282 if (rootok) { 00283 copy_v3_v3(tv->oldloc, ebo->head); 00284 tv->loc= ebo->head; 00285 tv->nor= NULL; 00286 tv->flag= 1; 00287 tv++; 00288 tottrans++; 00289 } 00290 00291 if ((mode & TM_ALL_JOINTS) && (tipsel)) { 00292 copy_v3_v3(tv->oldloc, ebo->tail); 00293 tv->loc= ebo->tail; 00294 tv->nor= NULL; 00295 tv->flag= 1; 00296 tv++; 00297 tottrans++; 00298 } 00299 } 00300 else if (tipsel) { 00301 copy_v3_v3(tv->oldloc, ebo->tail); 00302 tv->loc= ebo->tail; 00303 tv->nor= NULL; 00304 tv->flag= 1; 00305 tv++; 00306 tottrans++; 00307 } 00308 } 00309 } 00310 } 00311 else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { 00312 Curve *cu= obedit->data; 00313 int totmalloc= 0; 00314 ListBase *nurbs= curve_editnurbs(cu); 00315 00316 for(nu= nurbs->first; nu; nu= nu->next) { 00317 if(nu->type == CU_BEZIER) 00318 totmalloc += 3*nu->pntsu; 00319 else 00320 totmalloc += nu->pntsu*nu->pntsv; 00321 } 00322 tv=transvmain= MEM_callocN(totmalloc*sizeof(TransVert), "maketransverts curve"); 00323 00324 nu= nurbs->first; 00325 while(nu) { 00326 if(nu->type == CU_BEZIER) { 00327 a= nu->pntsu; 00328 bezt= nu->bezt; 00329 while(a--) { 00330 if(bezt->hide==0) { 00331 int skip_handle= 0; 00332 if(bezt->f2 & SELECT) 00333 skip_handle= mode & TM_SKIP_HANDLES; 00334 00335 if((bezt->f1 & SELECT) && !skip_handle) { 00336 copy_v3_v3(tv->oldloc, bezt->vec[0]); 00337 tv->loc= bezt->vec[0]; 00338 tv->flag= bezt->f1 & SELECT; 00339 tv++; 00340 tottrans++; 00341 } 00342 if(bezt->f2 & SELECT) { 00343 copy_v3_v3(tv->oldloc, bezt->vec[1]); 00344 tv->loc= bezt->vec[1]; 00345 tv->val= &(bezt->alfa); 00346 tv->oldval= bezt->alfa; 00347 tv->flag= bezt->f2 & SELECT; 00348 tv++; 00349 tottrans++; 00350 } 00351 if((bezt->f3 & SELECT) && !skip_handle) { 00352 copy_v3_v3(tv->oldloc, bezt->vec[2]); 00353 tv->loc= bezt->vec[2]; 00354 tv->flag= bezt->f3 & SELECT; 00355 tv++; 00356 tottrans++; 00357 } 00358 } 00359 bezt++; 00360 } 00361 } 00362 else { 00363 a= nu->pntsu*nu->pntsv; 00364 bp= nu->bp; 00365 while(a--) { 00366 if(bp->hide==0) { 00367 if(bp->f1 & SELECT) { 00368 copy_v3_v3(tv->oldloc, bp->vec); 00369 tv->loc= bp->vec; 00370 tv->val= &(bp->alfa); 00371 tv->oldval= bp->alfa; 00372 tv->flag= bp->f1 & SELECT; 00373 tv++; 00374 tottrans++; 00375 } 00376 } 00377 bp++; 00378 } 00379 } 00380 nu= nu->next; 00381 } 00382 } 00383 else if(obedit->type==OB_MBALL) { 00384 MetaBall *mb= obedit->data; 00385 int totmalloc= BLI_countlist(mb->editelems); 00386 00387 tv=transvmain= MEM_callocN(totmalloc*sizeof(TransVert), "maketransverts mball"); 00388 00389 ml= mb->editelems->first; 00390 while(ml) { 00391 if(ml->flag & SELECT) { 00392 tv->loc= &ml->x; 00393 copy_v3_v3(tv->oldloc, tv->loc); 00394 tv->val= &(ml->rad); 00395 tv->oldval= ml->rad; 00396 tv->flag= 1; 00397 tv++; 00398 tottrans++; 00399 } 00400 ml= ml->next; 00401 } 00402 } 00403 else if(obedit->type==OB_LATTICE) { 00404 Lattice *lt= obedit->data; 00405 00406 bp= lt->editlatt->latt->def; 00407 00408 a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; 00409 00410 tv=transvmain= MEM_callocN(a*sizeof(TransVert), "maketransverts latt"); 00411 00412 while(a--) { 00413 if(bp->f1 & SELECT) { 00414 if(bp->hide==0) { 00415 copy_v3_v3(tv->oldloc, bp->vec); 00416 tv->loc= bp->vec; 00417 tv->flag= bp->f1 & SELECT; 00418 tv++; 00419 tottrans++; 00420 } 00421 } 00422 bp++; 00423 } 00424 } 00425 00426 if(!tottrans && transvmain) { 00427 /* prevent memory leak. happens for curves/latticies due to */ 00428 /* difficult condition of adding points to trans data */ 00429 MEM_freeN(transvmain); 00430 transvmain= NULL; 00431 } 00432 00433 /* cent etc */ 00434 tv= transvmain; 00435 total= 0.0; 00436 for(a=0; a<tottrans; a++, tv++) { 00437 if(tv->flag & SELECT) { 00438 add_v3_v3(centroid, tv->oldloc); 00439 total += 1.0f; 00440 DO_MINMAX(tv->oldloc, min, max); 00441 } 00442 } 00443 if(total != 0.0f) { 00444 mul_v3_fl(centroid, 1.0f/total); 00445 } 00446 00447 mid_v3_v3v3(center, min, max); 00448 } 00449 00450 /* *********************** operators ******************** */ 00451 00452 static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) 00453 { 00454 Main *bmain= CTX_data_main(C); 00455 Object *obedit= CTX_data_edit_object(C); 00456 Scene *scene= CTX_data_scene(C); 00457 RegionView3D *rv3d= CTX_wm_region_data(C); 00458 TransVert *tv; 00459 float gridf, imat[3][3], bmat[3][3], vec[3]; 00460 int a; 00461 00462 gridf= rv3d->gridview; 00463 00464 if(obedit) { 00465 tottrans= 0; 00466 00467 if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 00468 make_trans_verts(obedit, bmat[0], bmat[1], 0); 00469 if(tottrans==0) return OPERATOR_CANCELLED; 00470 00471 copy_m3_m4(bmat, obedit->obmat); 00472 invert_m3_m3(imat, bmat); 00473 00474 tv= transvmain; 00475 for(a=0; a<tottrans; a++, tv++) { 00476 copy_v3_v3(vec, tv->loc); 00477 mul_m3_v3(bmat, vec); 00478 add_v3_v3(vec, obedit->obmat[3]); 00479 vec[0]= gridf*floorf(0.5f+ vec[0]/gridf); 00480 vec[1]= gridf*floorf(0.5f+ vec[1]/gridf); 00481 vec[2]= gridf*floorf(0.5f+ vec[2]/gridf); 00482 sub_v3_v3(vec, obedit->obmat[3]); 00483 00484 mul_m3_v3(imat, vec); 00485 copy_v3_v3(tv->loc, vec); 00486 } 00487 00488 special_transvert_update(obedit); 00489 00490 MEM_freeN(transvmain); 00491 transvmain= NULL; 00492 } 00493 else { 00494 struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); 00495 00496 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00497 if(ob->mode & OB_MODE_POSE) { 00498 bPoseChannel *pchan; 00499 bArmature *arm= ob->data; 00500 00501 invert_m4_m4(ob->imat, ob->obmat); 00502 00503 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 00504 if(pchan->bone->flag & BONE_SELECTED) { 00505 if(pchan->bone->layer & arm->layer) { 00506 if((pchan->bone->flag & BONE_CONNECTED)==0) { 00507 float nLoc[3]; 00508 float inv_restmat[4][4]; 00509 00510 /* get nearest grid point to snap to */ 00511 copy_v3_v3(nLoc, pchan->pose_mat[3]); 00512 /* We must operate in world space! */ 00513 mul_m4_v3(ob->obmat, nLoc); 00514 vec[0]= gridf * (float)(floor(0.5f+ nLoc[0]/gridf)); 00515 vec[1]= gridf * (float)(floor(0.5f+ nLoc[1]/gridf)); 00516 vec[2]= gridf * (float)(floor(0.5f+ nLoc[2]/gridf)); 00517 /* Back in object space... */ 00518 mul_m4_v3(ob->imat, vec); 00519 00520 /* get location of grid point in *rest* bone-space */ 00521 invert_m4_m4(inv_restmat, pchan->bone->arm_mat); 00522 mul_m4_v3(inv_restmat, vec); 00523 00524 /* adjust location */ 00525 if ((pchan->protectflag & OB_LOCK_LOCX)==0) 00526 pchan->loc[0]= vec[0]; 00527 if ((pchan->protectflag & OB_LOCK_LOCY)==0) 00528 pchan->loc[1]= vec[1]; 00529 if ((pchan->protectflag & OB_LOCK_LOCZ)==0) 00530 pchan->loc[2]= vec[2]; 00531 00532 /* auto-keyframing */ 00533 ED_autokeyframe_pchan(C, scene, ob, pchan, ks); 00534 } 00535 /* if the bone has a parent and is connected to the parent, 00536 * don't do anything - will break chain unless we do auto-ik. 00537 */ 00538 } 00539 } 00540 } 00541 ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); 00542 00543 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00544 } 00545 else { 00546 ob->recalc |= OB_RECALC_OB; 00547 00548 vec[0]= -ob->obmat[3][0]+gridf*floorf(0.5f+ ob->obmat[3][0]/gridf); 00549 vec[1]= -ob->obmat[3][1]+gridf*floorf(0.5f+ ob->obmat[3][1]/gridf); 00550 vec[2]= -ob->obmat[3][2]+gridf*floorf(0.5f+ ob->obmat[3][2]/gridf); 00551 00552 if(ob->parent) { 00553 where_is_object(scene, ob); 00554 00555 invert_m3_m3(imat, originmat); 00556 mul_m3_v3(imat, vec); 00557 } 00558 if ((ob->protectflag & OB_LOCK_LOCX)==0) 00559 ob->loc[0]+= vec[0]; 00560 if ((ob->protectflag & OB_LOCK_LOCY)==0) 00561 ob->loc[1]+= vec[1]; 00562 if ((ob->protectflag & OB_LOCK_LOCZ)==0) 00563 ob->loc[2]+= vec[2]; 00564 00565 /* auto-keyframing */ 00566 ED_autokeyframe_object(C, scene, ob, ks); 00567 } 00568 } 00569 CTX_DATA_END; 00570 } 00571 00572 DAG_ids_flush_update(bmain, 0); 00573 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00574 00575 return OPERATOR_FINISHED; 00576 } 00577 00578 void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) 00579 { 00580 /* identifiers */ 00581 ot->name= "Snap Selection to Grid"; 00582 ot->description= "Snap selected item(s) to nearest grid node"; 00583 ot->idname= "VIEW3D_OT_snap_selected_to_grid"; 00584 00585 /* api callbacks */ 00586 ot->exec= snap_sel_to_grid; 00587 ot->poll= ED_operator_region_view3d_active; 00588 00589 /* flags */ 00590 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00591 } 00592 00593 /* *************************************************** */ 00594 00595 static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) 00596 { 00597 Main *bmain= CTX_data_main(C); 00598 Object *obedit= CTX_data_edit_object(C); 00599 Scene *scene= CTX_data_scene(C); 00600 View3D *v3d= CTX_wm_view3d(C); 00601 TransVert *tv; 00602 float *curs, imat[3][3], bmat[3][3], vec[3]; 00603 int a; 00604 00605 curs= give_cursor(scene, v3d); 00606 00607 if(obedit) { 00608 tottrans= 0; 00609 00610 if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 00611 make_trans_verts(obedit, bmat[0], bmat[1], 0); 00612 if(tottrans==0) return OPERATOR_CANCELLED; 00613 00614 copy_m3_m4(bmat, obedit->obmat); 00615 invert_m3_m3(imat, bmat); 00616 00617 tv= transvmain; 00618 for(a=0; a<tottrans; a++, tv++) { 00619 sub_v3_v3v3(vec, curs, obedit->obmat[3]); 00620 mul_m3_v3(imat, vec); 00621 copy_v3_v3(tv->loc, vec); 00622 } 00623 00624 special_transvert_update(obedit); 00625 00626 MEM_freeN(transvmain); 00627 transvmain= NULL; 00628 } 00629 else { 00630 struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); 00631 00632 CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { 00633 if(ob->mode & OB_MODE_POSE) { 00634 bPoseChannel *pchan; 00635 bArmature *arm= ob->data; 00636 00637 invert_m4_m4(ob->imat, ob->obmat); 00638 copy_v3_v3(vec, curs); 00639 mul_m4_v3(ob->imat, vec); 00640 00641 for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { 00642 if(pchan->bone->flag & BONE_SELECTED) { 00643 if(pchan->bone->layer & arm->layer) { 00644 if((pchan->bone->flag & BONE_CONNECTED)==0) { 00645 float inv_restmat[4][4]; 00646 00647 /* get location of cursor in *rest* bone-space */ 00648 invert_m4_m4(inv_restmat, pchan->bone->arm_mat); 00649 mul_m4_v3(inv_restmat, vec); 00650 00651 /* copy new position */ 00652 if ((pchan->protectflag & OB_LOCK_LOCX)==0) 00653 pchan->loc[0]= vec[0]; 00654 if ((pchan->protectflag & OB_LOCK_LOCY)==0) 00655 pchan->loc[1]= vec[1]; 00656 if ((pchan->protectflag & OB_LOCK_LOCZ)==0) 00657 pchan->loc[2]= vec[2]; 00658 00659 /* auto-keyframing */ 00660 ED_autokeyframe_pchan(C, scene, ob, pchan, ks); 00661 } 00662 /* if the bone has a parent and is connected to the parent, 00663 * don't do anything - will break chain unless we do auto-ik. 00664 */ 00665 } 00666 } 00667 } 00668 ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); 00669 00670 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00671 } 00672 else { 00673 ob->recalc |= OB_RECALC_OB; 00674 00675 vec[0]= -ob->obmat[3][0] + curs[0]; 00676 vec[1]= -ob->obmat[3][1] + curs[1]; 00677 vec[2]= -ob->obmat[3][2] + curs[2]; 00678 00679 if(ob->parent) { 00680 where_is_object(scene, ob); 00681 00682 invert_m3_m3(imat, originmat); 00683 mul_m3_v3(imat, vec); 00684 } 00685 if ((ob->protectflag & OB_LOCK_LOCX)==0) 00686 ob->loc[0]+= vec[0]; 00687 if ((ob->protectflag & OB_LOCK_LOCY)==0) 00688 ob->loc[1]+= vec[1]; 00689 if ((ob->protectflag & OB_LOCK_LOCZ)==0) 00690 ob->loc[2]+= vec[2]; 00691 00692 /* auto-keyframing */ 00693 ED_autokeyframe_object(C, scene, ob, ks); 00694 } 00695 } 00696 CTX_DATA_END; 00697 } 00698 00699 DAG_ids_flush_update(bmain, 0); 00700 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00701 00702 return OPERATOR_FINISHED; 00703 } 00704 00705 void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) 00706 { 00707 /* identifiers */ 00708 ot->name= "Snap Selection to Cursor"; 00709 ot->description= "Snap selected item(s) to cursor"; 00710 ot->idname= "VIEW3D_OT_snap_selected_to_cursor"; 00711 00712 /* api callbacks */ 00713 ot->exec= snap_sel_to_curs; 00714 ot->poll= ED_operator_view3d_active; 00715 00716 /* flags */ 00717 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00718 } 00719 00720 /* *************************************************** */ 00721 00722 static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op)) 00723 { 00724 Scene *scene= CTX_data_scene(C); 00725 RegionView3D *rv3d= CTX_wm_region_data(C); 00726 View3D *v3d= CTX_wm_view3d(C); 00727 float gridf, *curs; 00728 00729 gridf= rv3d->gridview; 00730 curs= give_cursor(scene, v3d); 00731 00732 curs[0]= gridf*floorf(0.5f+curs[0]/gridf); 00733 curs[1]= gridf*floorf(0.5f+curs[1]/gridf); 00734 curs[2]= gridf*floorf(0.5f+curs[2]/gridf); 00735 00736 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); // hrm 00737 00738 return OPERATOR_FINISHED; 00739 } 00740 00741 void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) 00742 { 00743 /* identifiers */ 00744 ot->name= "Snap Cursor to Grid"; 00745 ot->description= "Snap cursor to nearest grid node"; 00746 ot->idname= "VIEW3D_OT_snap_cursor_to_grid"; 00747 00748 /* api callbacks */ 00749 ot->exec= snap_curs_to_grid; 00750 ot->poll= ED_operator_region_view3d_active; 00751 00752 /* flags */ 00753 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00754 } 00755 00756 /* **************************************************** */ 00757 00758 static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) 00759 { 00760 MovieClip *clip= object_get_movieclip(scene, ob, 0); 00761 MovieTracking *tracking; 00762 MovieTrackingObject *object; 00763 int ok= 0; 00764 float min[3], max[3], mat[4][4], pos[3], cammat[4][4] = MAT4_UNITY; 00765 00766 if(!clip) 00767 return; 00768 00769 tracking= &clip->tracking; 00770 00771 copy_m4_m4(cammat, ob->obmat); 00772 00773 BKE_get_tracking_mat(scene, ob, mat); 00774 00775 INIT_MINMAX(min, max); 00776 00777 for (object= tracking->objects.first; object; object= object->next) { 00778 ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); 00779 MovieTrackingTrack *track= tracksbase->first; 00780 float obmat[4][4]; 00781 00782 if(object->flag & TRACKING_OBJECT_CAMERA) { 00783 copy_m4_m4(obmat, mat); 00784 } 00785 else { 00786 float imat[4][4]; 00787 00788 BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, imat); 00789 invert_m4(imat); 00790 00791 mult_m4_m4m4(obmat, cammat, imat); 00792 } 00793 00794 while(track) { 00795 if((track->flag&TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) { 00796 ok= 1; 00797 mul_v3_m4v3(pos, obmat, track->bundle_pos); 00798 DO_MINMAX(pos, min, max); 00799 } 00800 00801 track= track->next; 00802 } 00803 } 00804 00805 if(ok) { 00806 mid_v3_v3v3(vec, min, max); 00807 } 00808 } 00809 00810 static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) 00811 { 00812 Object *obedit= CTX_data_edit_object(C); 00813 Scene *scene= CTX_data_scene(C); 00814 View3D *v3d= CTX_wm_view3d(C); 00815 TransVert *tv; 00816 float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3]; 00817 int count, a; 00818 00819 curs= give_cursor(scene, v3d); 00820 00821 count= 0; 00822 INIT_MINMAX(min, max); 00823 centroid[0]= centroid[1]= centroid[2]= 0.0; 00824 00825 if(obedit) { 00826 tottrans=0; 00827 00828 if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 00829 make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS|TM_SKIP_HANDLES); 00830 if(tottrans==0) return OPERATOR_CANCELLED; 00831 00832 copy_m3_m4(bmat, obedit->obmat); 00833 00834 tv= transvmain; 00835 for(a=0; a<tottrans; a++, tv++) { 00836 copy_v3_v3(vec, tv->loc); 00837 mul_m3_v3(bmat, vec); 00838 add_v3_v3(vec, obedit->obmat[3]); 00839 add_v3_v3(centroid, vec); 00840 DO_MINMAX(vec, min, max); 00841 } 00842 00843 if(v3d->around==V3D_CENTROID) { 00844 mul_v3_fl(centroid, 1.0f/(float)tottrans); 00845 copy_v3_v3(curs, centroid); 00846 } 00847 else { 00848 mid_v3_v3v3(curs, min, max); 00849 } 00850 MEM_freeN(transvmain); 00851 transvmain= NULL; 00852 } 00853 else { 00854 Object *obact= CTX_data_active_object(C); 00855 00856 if(obact && (obact->mode & OB_MODE_POSE)) { 00857 bArmature *arm= obact->data; 00858 bPoseChannel *pchan; 00859 for (pchan = obact->pose->chanbase.first; pchan; pchan=pchan->next) { 00860 if(arm->layer & pchan->bone->layer) { 00861 if(pchan->bone->flag & BONE_SELECTED) { 00862 copy_v3_v3(vec, pchan->pose_head); 00863 mul_m4_v3(obact->obmat, vec); 00864 add_v3_v3(centroid, vec); 00865 DO_MINMAX(vec, min, max); 00866 count++; 00867 } 00868 } 00869 } 00870 } 00871 else { 00872 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { 00873 copy_v3_v3(vec, ob->obmat[3]); 00874 00875 /* special case for camera -- snap to bundles */ 00876 if(ob->type==OB_CAMERA) { 00877 /* snap to bundles should happen only when bundles are visible */ 00878 if(v3d->flag2&V3D_SHOW_RECONSTRUCTION) { 00879 bundle_midpoint(scene, ob, vec); 00880 } 00881 } 00882 00883 add_v3_v3(centroid, vec); 00884 DO_MINMAX(vec, min, max); 00885 count++; 00886 } 00887 CTX_DATA_END; 00888 } 00889 if(count) { 00890 if(v3d->around==V3D_CENTROID) { 00891 mul_v3_fl(centroid, 1.0f/(float)count); 00892 copy_v3_v3(curs, centroid); 00893 } 00894 else { 00895 mid_v3_v3v3(curs, min, max); 00896 } 00897 } 00898 } 00899 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); 00900 00901 return OPERATOR_FINISHED; 00902 } 00903 00904 void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) 00905 { 00906 /* identifiers */ 00907 ot->name= "Snap Cursor to Selected"; 00908 ot->description= "Snap cursor to center of selected item(s)"; 00909 ot->idname= "VIEW3D_OT_snap_cursor_to_selected"; 00910 00911 /* api callbacks */ 00912 ot->exec= snap_curs_to_sel; 00913 ot->poll= ED_operator_view3d_active; 00914 00915 /* flags */ 00916 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00917 } 00918 00919 /* ********************************************** */ 00920 00921 static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op)) 00922 { 00923 Object *obedit= CTX_data_edit_object(C); 00924 Object *obact= CTX_data_active_object(C); 00925 Scene *scene= CTX_data_scene(C); 00926 View3D *v3d= CTX_wm_view3d(C); 00927 float *curs; 00928 00929 curs = give_cursor(scene, v3d); 00930 00931 if (obedit) { 00932 if (obedit->type == OB_MESH) { 00933 /* check active */ 00934 Mesh *me= obedit->data; 00935 EditSelection ese; 00936 00937 if (EM_get_actSelection(me->edit_mesh, &ese)) { 00938 EM_editselection_center(curs, &ese); 00939 } 00940 00941 mul_m4_v3(obedit->obmat, curs); 00942 } 00943 } 00944 else { 00945 if (obact) { 00946 copy_v3_v3(curs, obact->obmat[3]); 00947 } 00948 } 00949 00950 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); 00951 return OPERATOR_FINISHED; 00952 } 00953 00954 void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) 00955 { 00956 /* identifiers */ 00957 ot->name= "Snap Cursor to Active"; 00958 ot->description= "Snap cursor to active item"; 00959 ot->idname= "VIEW3D_OT_snap_cursor_to_active"; 00960 00961 /* api callbacks */ 00962 ot->exec= snap_curs_to_active; 00963 ot->poll= ED_operator_view3d_active; 00964 00965 /* flags */ 00966 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00967 } 00968 00969 /* **************************************************** */ 00970 /*New Code - Snap Cursor to Center -*/ 00971 static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op)) 00972 { 00973 Scene *scene= CTX_data_scene(C); 00974 View3D *v3d= CTX_wm_view3d(C); 00975 float *curs; 00976 curs= give_cursor(scene, v3d); 00977 00978 curs[0]= 0.0; 00979 curs[1]= 0.0; 00980 curs[2]= 0.0; 00981 00982 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d); 00983 00984 return OPERATOR_FINISHED; 00985 } 00986 00987 void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) 00988 { 00989 /* identifiers */ 00990 ot->name= "Snap Cursor to Center"; 00991 ot->description= "Snap cursor to the Center"; 00992 ot->idname= "VIEW3D_OT_snap_cursor_to_center"; 00993 00994 /* api callbacks */ 00995 ot->exec= snap_curs_to_center; 00996 ot->poll= ED_operator_view3d_active; 00997 00998 /* flags */ 00999 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01000 } 01001 01002 /* **************************************************** */ 01003 01004 01005 int minmax_verts(Object *obedit, float *min, float *max) 01006 { 01007 TransVert *tv; 01008 float centroid[3], vec[3], bmat[3][3]; 01009 int a; 01010 01011 tottrans=0; 01012 if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) 01013 make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS); 01014 01015 if(tottrans==0) return 0; 01016 01017 copy_m3_m4(bmat, obedit->obmat); 01018 01019 tv= transvmain; 01020 for(a=0; a<tottrans; a++, tv++) { 01021 copy_v3_v3(vec, tv->loc); 01022 mul_m3_v3(bmat, vec); 01023 add_v3_v3(vec, obedit->obmat[3]); 01024 add_v3_v3(centroid, vec); 01025 DO_MINMAX(vec, min, max); 01026 } 01027 01028 MEM_freeN(transvmain); 01029 transvmain= NULL; 01030 01031 return 1; 01032 } 01033