33
33
#include "DNA_armature_types.h"
34
34
#include "DNA_curve_types.h"
35
35
#include "DNA_mesh_types.h"
36
#include "DNA_meta_types.h"
36
37
#include "DNA_object_types.h"
37
38
#include "DNA_scene_types.h"
38
39
#include "DNA_screen_types.h"
76
73
// Need to loop over all view3d
77
74
if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
78
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
75
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
82
static TransformOrientation* findOrientationName(ListBase *lb, const char *name)
79
static TransformOrientation *findOrientationName(ListBase *lb, const char *name)
84
TransformOrientation *ts= NULL;
81
TransformOrientation *ts = NULL;
86
for (ts= lb->first; ts; ts = ts->next) {
87
if (strncmp(ts->name, name, sizeof(ts->name)-1) == 0) {
83
for (ts = lb->first; ts; ts = ts->next) {
84
if (strncmp(ts->name, name, sizeof(ts->name) - 1) == 0) {
115
112
ts = createBoneSpace(C, reports, name, overwrite);
117
114
else if (ob && (ob->mode & OB_MODE_POSE)) {
118
ts = createBoneSpace(C, reports, name, overwrite);
115
ts = createBoneSpace(C, reports, name, overwrite);
121
118
ts = createObjectSpace(C, reports, name, overwrite);
144
141
/* use object name if no name is given */
145
142
if (name[0] == 0) {
146
strncpy(name, ob->id.name+2, MAX_ID_NAME-2);
143
strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2);
149
return addMatrixSpace(C, mat, name, overwrite);
146
return addMatrixSpace(C, mat, name, overwrite);
152
149
TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite)
266
TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite)
262
TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite)
268
264
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
269
265
TransformOrientation *ts = NULL;
319
315
void BIF_removeTransformOrientationIndex(bContext *C, int index)
321
317
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
322
TransformOrientation *ts= BLI_findlink(transform_spaces, index);
318
TransformOrientation *ts = BLI_findlink(transform_spaces, index);
325
321
View3D *v3d = CTX_wm_view3d(C);
368
364
ListBase *transform_spaces;
369
TransformOrientation *ts= NULL;
365
TransformOrientation *ts = NULL;
371
EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""};
367
EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""};
372
368
EnumPropertyItem normal = {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""};
373
369
EnumPropertyItem local = {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""};
374
370
EnumPropertyItem view = {V3D_MANIP_VIEW, "VIEW", 0, "View", ""};
375
371
EnumPropertyItem tmp = {0, "", 0, "", ""};
376
EnumPropertyItem *item= NULL;
377
int i = V3D_MANIP_CUSTOM, totitem= 0;
372
EnumPropertyItem *item = NULL;
373
int i = V3D_MANIP_CUSTOM, totitem = 0;
379
375
RNA_enum_item_add(&item, &totitem, &global);
380
376
RNA_enum_item_add(&item, &totitem, &normal);
408
const char * BIF_menustringTransformOrientation(const bContext *C, const char *title)
404
const char *BIF_menustringTransformOrientation(const bContext *C, const char *title)
410
const char* menu = IFACE_("%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3");
406
const char *menu = IFACE_("%t|Global %x0|Local %x1|Gimbal %x4|Normal %x2|View %x3");
411
407
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
412
408
TransformOrientation *ts;
413
409
int i = V3D_MANIP_CUSTOM;
417
413
title = IFACE_(title);
419
str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix"));
415
str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix");
422
418
p += sprintf(str_menu, "%s", title);
423
419
p += sprintf(p, "%s", menu);
425
421
for (ts = transform_spaces->first; ts; ts = ts->next) {
426
p += sprintf(p, "|%s%%x%d", ts->name, i++);
422
p += sprintf(p, "|%s %%x%d", ts->name, i++);
453
449
for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) {
454
450
if (selected_index == i) {
457
strcpy(name, ts->name);
453
BLI_strncpy(name, ts->name, MAX_NAME);
459
456
copy_m3_m3(mat, ts->mat);
466
463
static int count_bone_select(bArmature *arm, ListBase *lb, int do_it)
493
490
Object *ob = CTX_data_active_object(C);
494
491
Object *obedit = CTX_data_active_object(C);
496
switch(t->current_orientation) {
497
case V3D_MANIP_GLOBAL:
498
unit_m3(t->spacemtx);
499
strcpy(t->spacename, "global");
502
case V3D_MANIP_GIMBAL:
503
unit_m3(t->spacemtx);
504
if (gimbal_axis(ob, t->spacemtx)) {
505
strcpy(t->spacename, "gimbal");
493
switch (t->current_orientation) {
494
case V3D_MANIP_GLOBAL:
495
unit_m3(t->spacemtx);
496
strcpy(t->spacename, IFACE_("global"));
499
case V3D_MANIP_GIMBAL:
500
unit_m3(t->spacemtx);
501
if (gimbal_axis(ob, t->spacemtx)) {
502
strcpy(t->spacename, IFACE_("gimbal"));
508
505
/* no gimbal fallthrough to normal */
509
case V3D_MANIP_NORMAL:
510
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
511
strcpy(t->spacename, "normal");
512
ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE));
506
case V3D_MANIP_NORMAL:
507
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
508
strcpy(t->spacename, IFACE_("normal"));
509
ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE));
515
512
/* no break we define 'normal' as 'local' in Object mode */
516
case V3D_MANIP_LOCAL:
517
strcpy(t->spacename, "local");
520
copy_m3_m4(t->spacemtx, ob->obmat);
521
normalize_m3(t->spacemtx);
524
unit_m3(t->spacemtx);
530
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
531
RegionView3D *rv3d = t->ar->regiondata;
513
case V3D_MANIP_LOCAL:
514
strcpy(t->spacename, IFACE_("local"));
517
copy_m3_m4(t->spacemtx, ob->obmat);
518
normalize_m3(t->spacemtx);
521
unit_m3(t->spacemtx);
527
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
528
RegionView3D *rv3d = t->ar->regiondata;
534
strcpy(t->spacename, "view");
535
copy_m3_m4(mat, rv3d->viewinv);
537
copy_m3_m3(t->spacemtx, mat);
540
unit_m3(t->spacemtx);
543
default: /* V3D_MANIP_CUSTOM */
544
applyTransformOrientation(C, t->spacemtx, t->spacename);
531
strcpy(t->spacename, IFACE_("view"));
532
copy_m3_m4(mat, rv3d->viewinv);
534
copy_m3_m3(t->spacemtx, mat);
537
unit_m3(t->spacemtx);
540
default: /* V3D_MANIP_CUSTOM */
541
applyTransformOrientation(C, t->spacemtx, t->spacename);
551
548
Scene *scene = CTX_data_scene(C);
552
549
View3D *v3d = CTX_wm_view3d(C);
553
Object *obedit= CTX_data_edit_object(C);
550
Object *obedit = CTX_data_edit_object(C);
555
552
Object *ob = OBACT;
556
553
int result = ORIENTATION_NONE;
558
normal[0] = normal[1] = normal[2] = 0;
559
plane[0] = plane[1] = plane[2] = 0;
562
559
float imat[3][3], mat[3][3];
567
564
invert_m3_m3(mat, imat);
568
565
transpose_m3(mat);
572
if (ob->type==OB_MESH) {
574
BMEditMesh *em = me->edit_btmesh;
569
if (ob->type == OB_MESH) {
570
BMEditMesh *em = BMEdit_FromObject(ob);
576
572
BMEditSelection ese;
577
float vec[3]= {0,0,0};
573
float vec[3] = {0, 0, 0};
579
575
/* USE LAST SELECTED WITH ACTIVE */
580
576
if (activeOnly && BM_select_history_active_get(em->bm, &ese)) {
581
577
BM_editselection_normal(&ese, normal);
582
578
BM_editselection_plane(&ese, plane);
587
582
result = ORIENTATION_VERT;
714
708
} /* end editmesh */
715
709
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
716
Curve *cu= obedit->data;
710
Curve *cu = obedit->data;
720
ListBase *nurbs= curve_editnurbs(cu);
714
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
722
716
for (nu = nurbs->first; nu; nu = nu->next) {
723
717
/* only bezier has a normal */
724
718
if (nu->type == CU_BEZIER) {
730
723
if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) {
731
724
sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]);
749
if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) {
742
if (!is_zero_v3(normal)) {
750
743
result = ORIENTATION_NORMAL;
753
else if (obedit->type==OB_MBALL) {
756
MetaElem *ml, *ml_sel = NULL;
758
/* loop and check that only one element is selected */
759
for (ml = editelems.first; ml; ml = ml->next) {
760
if (ml->flag & SELECT) {
761
if (ml_sel == NULL) {
746
else if (obedit->type == OB_MBALL) {
747
MetaBall *mb = obedit->data;
774
752
/* Rotation of MetaElem is stored in quat */
775
quat_to_mat4( mat,ml_sel->quat);
777
copy_v3_v3(normal, mat[2]);
779
negate_v3_v3(plane, mat[1]);
753
quat_to_mat3(qmat, mb->lastelem->quat);
755
copy_v3_v3(normal, qmat[2]);
757
negate_v3_v3(plane, qmat[1]);
781
result = ORIENTATION_NORMAL;
759
result = ORIENTATION_FACE;
786
762
else if (obedit->type == OB_ARMATURE) {
787
763
bArmature *arm = obedit->data;
790
for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
791
if (arm->layer & ebone->layer) {
792
if (ebone->flag & BONE_SELECTED) {
795
sub_v3_v3v3(vec, ebone->tail, ebone->head);
797
add_v3_v3(normal, vec);
799
vec_roll_to_mat3(vec, ebone->roll, tmat);
800
add_v3_v3(plane, tmat[2]);
767
/* grr. but better then duplicate code */
768
#define EBONE_CALC_NORMAL_PLANE { \
771
sub_v3_v3v3(vec, ebone->tail, ebone->head); \
773
add_v3_v3(normal, vec); \
775
vec_roll_to_mat3(vec, ebone->roll, tmat); \
776
add_v3_v3(plane, tmat[2]); \
780
if (activeOnly && (ebone = arm->act_edbone)) {
781
EBONE_CALC_NORMAL_PLANE;
785
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
786
if (arm->layer & ebone->layer) {
787
if (ebone->flag & BONE_SELECTED) {
788
EBONE_CALC_NORMAL_PLANE;
805
normalize_v3(normal);
796
normalize_v3(normal);
808
if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) {
809
result = ORIENTATION_EDGE;
799
if (!is_zero_v3(plane)) {
800
result = ORIENTATION_EDGE;
803
#undef EBONE_CALC_NORMAL_PLANE
814
806
/* Vectors from edges don't need the special transpose inverse multiplication */
824
816
else if (ob && (ob->mode & OB_MODE_POSE)) {
825
bArmature *arm= ob->data;
817
bArmature *arm = ob->data;
826
818
bPoseChannel *pchan;
829
totsel = count_bone_select(arm, &arm->bonebase, 1);
831
float imat[3][3], mat[3][3];
833
/* use channels to get stats */
834
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
835
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
836
add_v3_v3(normal, pchan->pose_mat[2]);
837
add_v3_v3(plane, pchan->pose_mat[1]);
819
float imat[3][3], mat[3][3];
822
if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
823
add_v3_v3(normal, pchan->pose_mat[2]);
824
add_v3_v3(plane, pchan->pose_mat[1]);
830
totsel = count_bone_select(arm, &arm->bonebase, 1);
832
/* use channels to get stats */
833
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
834
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
835
add_v3_v3(normal, pchan->pose_mat[2]);
836
add_v3_v3(plane, pchan->pose_mat[1]);
843
/* use for both active & all */
840
845
negate_v3(plane);
842
847
/* we need the transpose of the inverse for a normal... */
880
void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly)
885
void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly)
882
float normal[3]={0.0, 0.0, 0.0};
883
float plane[3]={0.0, 0.0, 0.0};
887
float normal[3] = {0.0, 0.0, 0.0};
888
float plane[3] = {0.0, 0.0, 0.0};
887
892
type = getTransformOrientation(C, normal, plane, activeOnly);
891
895
case ORIENTATION_NORMAL:
892
896
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
893
897
type = ORIENTATION_NONE;