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