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 * Contributor(s): Martin Poirier 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00028 #include <string.h> 00029 #include <ctype.h> 00030 00031 #include "MEM_guardedalloc.h" 00032 00033 #include "DNA_armature_types.h" 00034 #include "DNA_curve_types.h" 00035 #include "DNA_object_types.h" 00036 #include "DNA_scene_types.h" 00037 #include "DNA_screen_types.h" 00038 #include "DNA_view3d_types.h" 00039 00040 00041 #include "BKE_armature.h" 00042 #include "BKE_curve.h" 00043 #include "BKE_context.h" 00044 #include "BKE_report.h" 00045 00046 #include "BLI_math.h" 00047 #include "BLI_blenlib.h" 00048 #include "BLI_editVert.h" 00049 #include "BLI_utildefines.h" 00050 00051 #include "BLF_translation.h" 00052 00053 //#include "BIF_editmesh.h" 00054 //#include "BIF_interface.h" 00055 //#include "BIF_space.h" 00056 //#include "BIF_toolbox.h" 00057 00058 #include "ED_armature.h" 00059 #include "ED_mesh.h" 00060 00061 #include "RNA_define.h" 00062 00063 #include "UI_interface.h" 00064 00065 #include "transform.h" 00066 00067 /* *********************** TransSpace ************************** */ 00068 00069 void BIF_clearTransformOrientation(bContext *C) 00070 { 00071 View3D *v3d = CTX_wm_view3d(C); 00072 00073 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00074 BLI_freelistN(transform_spaces); 00075 00076 // Need to loop over all view3d 00077 if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) { 00078 v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ 00079 } 00080 } 00081 00082 static TransformOrientation* findOrientationName(ListBase *lb, const char *name) 00083 { 00084 TransformOrientation *ts= NULL; 00085 00086 for (ts= lb->first; ts; ts = ts->next) { 00087 if (strncmp(ts->name, name, sizeof(ts->name)-1) == 0) { 00088 return ts; 00089 } 00090 } 00091 00092 return NULL; 00093 } 00094 00095 static int uniqueOrientationNameCheck(void *arg, const char *name) 00096 { 00097 return findOrientationName((ListBase *)arg, name) != NULL; 00098 } 00099 00100 static void uniqueOrientationName(ListBase *lb, char *name) 00101 { 00102 BLI_uniquename_cb(uniqueOrientationNameCheck, lb, "Space", '.', name, sizeof(((TransformOrientation *)NULL)->name)); 00103 } 00104 00105 void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite) 00106 { 00107 Object *obedit = CTX_data_edit_object(C); 00108 Object *ob = CTX_data_active_object(C); 00109 TransformOrientation *ts = NULL; 00110 00111 if (obedit) { 00112 if (obedit->type == OB_MESH) 00113 ts = createMeshSpace(C, reports, name, overwrite); 00114 else if (obedit->type == OB_ARMATURE) 00115 ts = createBoneSpace(C, reports, name, overwrite); 00116 } 00117 else if (ob && (ob->mode & OB_MODE_POSE)) { 00118 ts = createBoneSpace(C, reports, name, overwrite); 00119 } 00120 else { 00121 ts = createObjectSpace(C, reports, name, overwrite); 00122 } 00123 00124 if (use && ts != NULL) 00125 { 00126 BIF_selectTransformOrientation(C, ts); 00127 } 00128 } 00129 00130 TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite) 00131 { 00132 Base *base = CTX_data_active_base(C); 00133 Object *ob; 00134 float mat[3][3]; 00135 00136 if (base == NULL) 00137 return NULL; 00138 00139 00140 ob = base->object; 00141 00142 copy_m3_m4(mat, ob->obmat); 00143 normalize_m3(mat); 00144 00145 /* use object name if no name is given */ 00146 if (name[0] == 0) 00147 { 00148 strncpy(name, ob->id.name+2, MAX_ID_NAME-2); 00149 } 00150 00151 return addMatrixSpace(C, mat, name, overwrite); 00152 } 00153 00154 TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) 00155 { 00156 float mat[3][3]; 00157 float normal[3], plane[3]; 00158 00159 getTransformOrientation(C, normal, plane, 0); 00160 00161 if (createSpaceNormalTangent(mat, normal, plane) == 0) { 00162 BKE_reports_prepend(reports, "Cannot use zero-length bone"); 00163 return NULL; 00164 } 00165 00166 if (name[0] == 0) 00167 { 00168 strcpy(name, "Bone"); 00169 } 00170 00171 return addMatrixSpace(C, mat, name, overwrite); 00172 } 00173 00174 TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) 00175 { 00176 float mat[3][3]; 00177 float normal[3], plane[3]; 00178 int type; 00179 00180 type = getTransformOrientation(C, normal, plane, 0); 00181 00182 switch (type) 00183 { 00184 case ORIENTATION_VERT: 00185 if (createSpaceNormal(mat, normal) == 0) { 00186 BKE_reports_prepend(reports, "Cannot use vertex with zero-length normal"); 00187 return NULL; 00188 } 00189 00190 if (name[0] == 0) 00191 { 00192 strcpy(name, "Vertex"); 00193 } 00194 break; 00195 case ORIENTATION_EDGE: 00196 if (createSpaceNormalTangent(mat, normal, plane) == 0) { 00197 BKE_reports_prepend(reports, "Cannot use zero-length edge"); 00198 return NULL; 00199 } 00200 00201 if (name[0] == 0) 00202 { 00203 strcpy(name, "Edge"); 00204 } 00205 break; 00206 case ORIENTATION_FACE: 00207 if (createSpaceNormalTangent(mat, normal, plane) == 0) { 00208 BKE_reports_prepend(reports, "Cannot use zero-area face"); 00209 return NULL; 00210 } 00211 00212 if (name[0] == 0) 00213 { 00214 strcpy(name, "Face"); 00215 } 00216 break; 00217 default: 00218 return NULL; 00219 break; 00220 } 00221 00222 return addMatrixSpace(C, mat, name, overwrite); 00223 } 00224 00225 int createSpaceNormal(float mat[3][3], float normal[3]) 00226 { 00227 float tangent[3] = {0.0f, 0.0f, 1.0f}; 00228 00229 copy_v3_v3(mat[2], normal); 00230 if (normalize_v3(mat[2]) == 0.0f) { 00231 return 0; /* error return */ 00232 } 00233 00234 cross_v3_v3v3(mat[0], mat[2], tangent); 00235 if (dot_v3v3(mat[0], mat[0]) == 0.0f) { 00236 tangent[0] = 1.0f; 00237 tangent[1] = tangent[2] = 0.0f; 00238 cross_v3_v3v3(mat[0], tangent, mat[2]); 00239 } 00240 00241 cross_v3_v3v3(mat[1], mat[2], mat[0]); 00242 00243 normalize_m3(mat); 00244 00245 return 1; 00246 } 00247 00248 int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) 00249 { 00250 copy_v3_v3(mat[2], normal); 00251 if (normalize_v3(mat[2]) == 0.0f) { 00252 return 0; /* error return */ 00253 } 00254 00255 /* preempt zero length tangent from causing trouble */ 00256 if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) 00257 { 00258 tangent[2] = 1; 00259 } 00260 00261 cross_v3_v3v3(mat[0], mat[2], tangent); 00262 if (normalize_v3(mat[0]) == 0.0f) { 00263 return 0; /* error return */ 00264 } 00265 00266 cross_v3_v3v3(mat[1], mat[2], mat[0]); 00267 00268 normalize_m3(mat); 00269 00270 return 1; 00271 } 00272 00273 TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) 00274 { 00275 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00276 TransformOrientation *ts = NULL; 00277 00278 if (overwrite) 00279 { 00280 ts = findOrientationName(transform_spaces, name); 00281 } 00282 else 00283 { 00284 uniqueOrientationName(transform_spaces, name); 00285 } 00286 00287 /* if not, create a new one */ 00288 if (ts == NULL) 00289 { 00290 ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix"); 00291 BLI_addtail(transform_spaces, ts); 00292 strncpy(ts->name, name, sizeof(ts->name)); 00293 } 00294 00295 /* copy matrix into transform space */ 00296 copy_m3_m3(ts->mat, mat); 00297 00298 return ts; 00299 } 00300 00301 void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) 00302 { 00303 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00304 TransformOrientation *ts; 00305 int i; 00306 00307 for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { 00308 if (ts == target) { 00309 View3D *v3d = CTX_wm_view3d(C); 00310 if(v3d) { 00311 int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); 00312 00313 // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D 00314 if (selected_index == i) { 00315 v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ 00316 } 00317 else if (selected_index > i) { 00318 v3d->twmode--; 00319 } 00320 00321 } 00322 00323 BLI_freelinkN(transform_spaces, ts); 00324 break; 00325 } 00326 } 00327 } 00328 00329 void BIF_removeTransformOrientationIndex(bContext *C, int index) 00330 { 00331 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00332 TransformOrientation *ts= BLI_findlink(transform_spaces, index); 00333 00334 if (ts) { 00335 View3D *v3d = CTX_wm_view3d(C); 00336 if(v3d) { 00337 int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); 00338 00339 // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D 00340 if (selected_index == index) { 00341 v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ 00342 } 00343 else if (selected_index > index) { 00344 v3d->twmode--; 00345 } 00346 00347 } 00348 00349 BLI_freelinkN(transform_spaces, ts); 00350 } 00351 } 00352 00353 void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) 00354 { 00355 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00356 View3D *v3d = CTX_wm_view3d(C); 00357 TransformOrientation *ts; 00358 int i; 00359 00360 for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { 00361 if (ts == target) { 00362 v3d->twmode = V3D_MANIP_CUSTOM + i; 00363 break; 00364 } 00365 } 00366 } 00367 00368 void BIF_selectTransformOrientationValue(bContext *C, int orientation) 00369 { 00370 View3D *v3d = CTX_wm_view3d(C); 00371 if(v3d) /* currently using generic poll */ 00372 v3d->twmode = orientation; 00373 } 00374 00375 EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) 00376 { 00377 Scene *scene; 00378 ListBase *transform_spaces; 00379 TransformOrientation *ts= NULL; 00380 00381 EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}; 00382 EnumPropertyItem normal = {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}; 00383 EnumPropertyItem local = {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}; 00384 EnumPropertyItem view = {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}; 00385 EnumPropertyItem tmp = {0, "", 0, "", ""}; 00386 EnumPropertyItem *item= NULL; 00387 int i = V3D_MANIP_CUSTOM, totitem= 0; 00388 00389 RNA_enum_item_add(&item, &totitem, &global); 00390 RNA_enum_item_add(&item, &totitem, &normal); 00391 RNA_enum_item_add(&item, &totitem, &local); 00392 RNA_enum_item_add(&item, &totitem, &view); 00393 00394 if(C) { 00395 scene= CTX_data_scene(C); 00396 00397 if(scene) { 00398 transform_spaces = &scene->transform_spaces; 00399 ts = transform_spaces->first; 00400 } 00401 } 00402 00403 if(ts) 00404 RNA_enum_item_add_separator(&item, &totitem); 00405 00406 for(; ts; ts = ts->next) { 00407 tmp.identifier = "CUSTOM"; 00408 tmp.name= ts->name; 00409 tmp.value = i++; 00410 RNA_enum_item_add(&item, &totitem, &tmp); 00411 } 00412 00413 RNA_enum_item_end(&item, &totitem); 00414 00415 return item; 00416 } 00417 00418 const char * BIF_menustringTransformOrientation(const bContext *C, const char *title) 00419 { 00420 const char* menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3"); 00421 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00422 TransformOrientation *ts; 00423 int i = V3D_MANIP_CUSTOM; 00424 char *str_menu, *p; 00425 const int elem_size = MAX_NAME + 4; 00426 00427 title = IFACE_(title); 00428 00429 str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix")); 00430 p = str_menu; 00431 00432 p += sprintf(str_menu, "%s", title); 00433 p += sprintf(p, "%s", menu); 00434 00435 for (ts = transform_spaces->first; ts; ts = ts->next) { 00436 p += sprintf(p, "|%s%%x%d", ts->name, i++); 00437 } 00438 00439 return str_menu; 00440 } 00441 00442 int BIF_countTransformOrientation(const bContext *C) 00443 { 00444 ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; 00445 TransformOrientation *ts; 00446 int count = 0; 00447 00448 for (ts = transform_spaces->first; ts; ts = ts->next) { 00449 count++; 00450 } 00451 00452 return count; 00453 } 00454 00455 void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) 00456 { 00457 TransformOrientation *ts; 00458 View3D *v3d = CTX_wm_view3d(C); 00459 int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); 00460 int i; 00461 00462 if (selected_index >= 0) { 00463 for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { 00464 if (selected_index == i) { 00465 00466 if (name) 00467 strcpy(name, ts->name); 00468 00469 copy_m3_m3(mat, ts->mat); 00470 break; 00471 } 00472 } 00473 } 00474 } 00475 00476 static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) 00477 { 00478 Bone *bone; 00479 int do_next; 00480 int total = 0; 00481 00482 for(bone= lb->first; bone; bone= bone->next) { 00483 bone->flag &= ~BONE_TRANSFORM; 00484 do_next = do_it; 00485 if(do_it) { 00486 if(bone->layer & arm->layer) { 00487 if (bone->flag & BONE_SELECTED) { 00488 bone->flag |= BONE_TRANSFORM; 00489 total++; 00490 do_next= 0; // no transform on children if one parent bone is selected 00491 } 00492 } 00493 } 00494 total += count_bone_select(arm, &bone->childbase, do_next); 00495 } 00496 00497 return total; 00498 } 00499 00500 void initTransformOrientation(bContext *C, TransInfo *t) 00501 { 00502 View3D *v3d = CTX_wm_view3d(C); 00503 Object *ob = CTX_data_active_object(C); 00504 Object *obedit = CTX_data_active_object(C); 00505 00506 switch(t->current_orientation) { 00507 case V3D_MANIP_GLOBAL: 00508 unit_m3(t->spacemtx); 00509 strcpy(t->spacename, "global"); 00510 break; 00511 00512 case V3D_MANIP_GIMBAL: 00513 unit_m3(t->spacemtx); 00514 if (gimbal_axis(ob, t->spacemtx)) { 00515 strcpy(t->spacename, "gimbal"); 00516 break; 00517 } 00518 /* no gimbal fallthrough to normal */ 00519 case V3D_MANIP_NORMAL: 00520 if(obedit || (ob && ob->mode & OB_MODE_POSE)) { 00521 strcpy(t->spacename, "normal"); 00522 ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE)); 00523 break; 00524 } 00525 /* no break we define 'normal' as 'local' in Object mode */ 00526 case V3D_MANIP_LOCAL: 00527 strcpy(t->spacename, "local"); 00528 00529 if(ob) { 00530 copy_m3_m4(t->spacemtx, ob->obmat); 00531 normalize_m3(t->spacemtx); 00532 } else { 00533 unit_m3(t->spacemtx); 00534 } 00535 00536 break; 00537 00538 case V3D_MANIP_VIEW: 00539 if (t->ar->regiontype == RGN_TYPE_WINDOW) 00540 { 00541 RegionView3D *rv3d = t->ar->regiondata; 00542 float mat[3][3]; 00543 00544 strcpy(t->spacename, "view"); 00545 copy_m3_m4(mat, rv3d->viewinv); 00546 normalize_m3(mat); 00547 copy_m3_m3(t->spacemtx, mat); 00548 } 00549 else 00550 { 00551 unit_m3(t->spacemtx); 00552 } 00553 break; 00554 default: /* V3D_MANIP_CUSTOM */ 00555 applyTransformOrientation(C, t->spacemtx, t->spacename); 00556 break; 00557 } 00558 } 00559 00560 int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int activeOnly) 00561 { 00562 Scene *scene = CTX_data_scene(C); 00563 View3D *v3d = CTX_wm_view3d(C); 00564 Object *obedit= CTX_data_edit_object(C); 00565 Base *base; 00566 Object *ob = OBACT; 00567 int result = ORIENTATION_NONE; 00568 00569 normal[0] = normal[1] = normal[2] = 0; 00570 plane[0] = plane[1] = plane[2] = 0; 00571 00572 if(obedit) 00573 { 00574 float imat[3][3], mat[3][3]; 00575 00576 /* we need the transpose of the inverse for a normal... */ 00577 copy_m3_m4(imat, ob->obmat); 00578 00579 invert_m3_m3(mat, imat); 00580 transpose_m3(mat); 00581 00582 ob= obedit; 00583 00584 if(ob->type==OB_MESH) 00585 { 00586 Mesh *me= ob->data; 00587 EditMesh *em = me->edit_mesh; 00588 EditVert *eve; 00589 EditSelection ese; 00590 float vec[3]= {0,0,0}; 00591 00592 /* USE LAST SELECTED WITH ACTIVE */ 00593 if (activeOnly && EM_get_actSelection(em, &ese)) 00594 { 00595 EM_editselection_normal(normal, &ese); 00596 EM_editselection_plane(plane, &ese); 00597 00598 switch (ese.type) 00599 { 00600 case EDITVERT: 00601 result = ORIENTATION_VERT; 00602 break; 00603 case EDITEDGE: 00604 result = ORIENTATION_EDGE; 00605 break; 00606 case EDITFACE: 00607 result = ORIENTATION_FACE; 00608 break; 00609 } 00610 } 00611 else 00612 { 00613 if (em->totfacesel >= 1) 00614 { 00615 EditFace *efa; 00616 00617 for(efa= em->faces.first; efa; efa= efa->next) 00618 { 00619 if(efa->f & SELECT) 00620 { 00621 add_v3_v3(normal, efa->n); 00622 sub_v3_v3v3(vec, efa->v2->co, efa->v1->co); 00623 add_v3_v3(plane, vec); 00624 } 00625 } 00626 00627 result = ORIENTATION_FACE; 00628 } 00629 else if (em->totvertsel == 3) 00630 { 00631 EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL; 00632 float cotangent[3]; 00633 00634 for (eve = em->verts.first; eve; eve = eve->next) 00635 { 00636 if ( eve->f & SELECT ) { 00637 if (v1 == NULL) { 00638 v1 = eve; 00639 } 00640 else if (v2 == NULL) { 00641 v2 = eve; 00642 } 00643 else { 00644 v3 = eve; 00645 00646 sub_v3_v3v3(plane, v2->co, v1->co); 00647 sub_v3_v3v3(cotangent, v3->co, v2->co); 00648 cross_v3_v3v3(normal, cotangent, plane); 00649 break; 00650 } 00651 } 00652 } 00653 00654 /* if there's an edge available, use that for the tangent */ 00655 if (em->totedgesel >= 1) 00656 { 00657 EditEdge *eed = NULL; 00658 00659 for(eed= em->edges.first; eed; eed= eed->next) { 00660 if(eed->f & SELECT) { 00661 sub_v3_v3v3(plane, eed->v2->co, eed->v1->co); 00662 break; 00663 } 00664 } 00665 } 00666 00667 result = ORIENTATION_FACE; 00668 } 00669 else if (em->totedgesel == 1) 00670 { 00671 EditEdge *eed; 00672 00673 for(eed= em->edges.first; eed; eed= eed->next) { 00674 if(eed->f & SELECT) { 00675 /* use average vert normals as plane and edge vector as normal */ 00676 copy_v3_v3(plane, eed->v1->no); 00677 add_v3_v3(plane, eed->v2->no); 00678 sub_v3_v3v3(normal, eed->v2->co, eed->v1->co); 00679 break; 00680 } 00681 } 00682 result = ORIENTATION_EDGE; 00683 } 00684 else if (em->totvertsel == 2) 00685 { 00686 EditVert *v1 = NULL, *v2 = NULL; 00687 00688 for (eve = em->verts.first; eve; eve = eve->next) 00689 { 00690 if ( eve->f & SELECT ) { 00691 if (v1 == NULL) { 00692 v1 = eve; 00693 } 00694 else { 00695 v2 = eve; 00696 00697 copy_v3_v3(plane, v1->no); 00698 add_v3_v3(plane, v2->no); 00699 sub_v3_v3v3(normal, v2->co, v1->co); 00700 break; 00701 } 00702 } 00703 } 00704 result = ORIENTATION_EDGE; 00705 } 00706 else if (em->totvertsel == 1) 00707 { 00708 for (eve = em->verts.first; eve; eve = eve->next) 00709 { 00710 if ( eve->f & SELECT ) { 00711 copy_v3_v3(normal, eve->no); 00712 break; 00713 } 00714 } 00715 result = ORIENTATION_VERT; 00716 } 00717 else if (em->totvertsel > 3) 00718 { 00719 normal[0] = normal[1] = normal[2] = 0; 00720 00721 for (eve = em->verts.first; eve; eve = eve->next) 00722 { 00723 if ( eve->f & SELECT ) { 00724 add_v3_v3(normal, eve->no); 00725 } 00726 } 00727 normalize_v3(normal); 00728 result = ORIENTATION_VERT; 00729 } 00730 } 00731 } /* end editmesh */ 00732 else if ELEM(obedit->type, OB_CURVE, OB_SURF) 00733 { 00734 Curve *cu= obedit->data; 00735 Nurb *nu; 00736 BezTriple *bezt; 00737 int a; 00738 ListBase *nurbs= curve_editnurbs(cu); 00739 00740 for (nu = nurbs->first; nu; nu = nu->next) 00741 { 00742 /* only bezier has a normal */ 00743 if(nu->type == CU_BEZIER) 00744 { 00745 bezt= nu->bezt; 00746 a= nu->pntsu; 00747 while(a--) 00748 { 00749 /* exception */ 00750 if ( (bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT ) 00751 { 00752 sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); 00753 } 00754 else 00755 { 00756 if(bezt->f1) 00757 { 00758 sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]); 00759 } 00760 if(bezt->f2) 00761 { 00762 sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); 00763 } 00764 if(bezt->f3) 00765 { 00766 sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]); 00767 } 00768 } 00769 bezt++; 00770 } 00771 } 00772 } 00773 00774 if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) 00775 { 00776 result = ORIENTATION_NORMAL; 00777 } 00778 } 00779 else if(obedit->type==OB_MBALL) 00780 { 00781 #if 0 // XXX 00782 /* editmball.c */ 00783 extern ListBase editelems; /* go away ! */ 00784 MetaElem *ml, *ml_sel = NULL; 00785 00786 /* loop and check that only one element is selected */ 00787 for (ml = editelems.first; ml; ml = ml->next) 00788 { 00789 if (ml->flag & SELECT) { 00790 if (ml_sel == NULL) 00791 { 00792 ml_sel = ml; 00793 } 00794 else 00795 { 00796 ml_sel = NULL; 00797 break; 00798 } 00799 } 00800 } 00801 00802 if (ml_sel) 00803 { 00804 float mat[4][4]; 00805 00806 /* Rotation of MetaElem is stored in quat */ 00807 quat_to_mat4( mat,ml_sel->quat); 00808 00809 copy_v3_v3(normal, mat[2]); 00810 00811 negate_v3_v3(plane, mat[1]); 00812 00813 result = ORIENTATION_NORMAL; 00814 } 00815 #endif 00816 00817 } 00818 else if (obedit->type == OB_ARMATURE) 00819 { 00820 bArmature *arm = obedit->data; 00821 EditBone *ebone; 00822 00823 for (ebone = arm->edbo->first; ebone; ebone=ebone->next) { 00824 if (arm->layer & ebone->layer) 00825 { 00826 if (ebone->flag & BONE_SELECTED) 00827 { 00828 float tmat[3][3]; 00829 float vec[3]; 00830 sub_v3_v3v3(vec, ebone->tail, ebone->head); 00831 normalize_v3(vec); 00832 add_v3_v3(normal, vec); 00833 00834 vec_roll_to_mat3(vec, ebone->roll, tmat); 00835 add_v3_v3(plane, tmat[2]); 00836 } 00837 } 00838 } 00839 00840 normalize_v3(normal); 00841 normalize_v3(plane); 00842 00843 if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) 00844 { 00845 result = ORIENTATION_EDGE; 00846 } 00847 00848 } 00849 00850 /* Vectors from edges don't need the special transpose inverse multiplication */ 00851 if (result == ORIENTATION_EDGE) 00852 { 00853 mul_mat3_m4_v3(ob->obmat, normal); 00854 mul_mat3_m4_v3(ob->obmat, plane); 00855 } 00856 else 00857 { 00858 mul_m3_v3(mat, normal); 00859 mul_m3_v3(mat, plane); 00860 } 00861 } 00862 else if(ob && (ob->mode & OB_MODE_POSE)) 00863 { 00864 bArmature *arm= ob->data; 00865 bPoseChannel *pchan; 00866 int totsel; 00867 00868 totsel = count_bone_select(arm, &arm->bonebase, 1); 00869 if(totsel) { 00870 float imat[3][3], mat[3][3]; 00871 00872 /* use channels to get stats */ 00873 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 00874 if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { 00875 add_v3_v3(normal, pchan->pose_mat[2]); 00876 add_v3_v3(plane, pchan->pose_mat[1]); 00877 } 00878 } 00879 negate_v3(plane); 00880 00881 /* we need the transpose of the inverse for a normal... */ 00882 copy_m3_m4(imat, ob->obmat); 00883 00884 invert_m3_m3(mat, imat); 00885 transpose_m3(mat); 00886 mul_m3_v3(mat, normal); 00887 mul_m3_v3(mat, plane); 00888 00889 result = ORIENTATION_EDGE; 00890 } 00891 } 00892 else if(ob && (ob->mode & (OB_MODE_ALL_PAINT|OB_MODE_PARTICLE_EDIT))) 00893 { 00894 } 00895 else { 00896 /* we need the one selected object, if its not active */ 00897 ob = OBACT; 00898 if(ob && !(ob->flag & SELECT)) ob = NULL; 00899 00900 for(base= scene->base.first; base; base= base->next) { 00901 if TESTBASELIB(v3d, base) { 00902 if(ob == NULL) { 00903 ob= base->object; 00904 break; 00905 } 00906 } 00907 } 00908 00909 if (ob) { 00910 copy_v3_v3(normal, ob->obmat[2]); 00911 copy_v3_v3(plane, ob->obmat[1]); 00912 } 00913 result = ORIENTATION_NORMAL; 00914 } 00915 00916 return result; 00917 } 00918 00919 void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly) 00920 { 00921 float normal[3]={0.0, 0.0, 0.0}; 00922 float plane[3]={0.0, 0.0, 0.0}; 00923 00924 int type; 00925 00926 type = getTransformOrientation(C, normal, plane, activeOnly); 00927 00928 switch (type) 00929 { 00930 case ORIENTATION_NORMAL: 00931 if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) 00932 { 00933 type = ORIENTATION_NONE; 00934 } 00935 break; 00936 case ORIENTATION_VERT: 00937 if (createSpaceNormal(orientation_mat, normal) == 0) 00938 { 00939 type = ORIENTATION_NONE; 00940 } 00941 break; 00942 case ORIENTATION_EDGE: 00943 if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) 00944 { 00945 type = ORIENTATION_NONE; 00946 } 00947 break; 00948 case ORIENTATION_FACE: 00949 if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) 00950 { 00951 type = ORIENTATION_NONE; 00952 } 00953 break; 00954 } 00955 00956 if (type == ORIENTATION_NONE) 00957 { 00958 unit_m3(orientation_mat); 00959 } 00960 }