30
33
#include "DNA_armature_types.h"
31
34
#include "DNA_curve_types.h"
35
#include "DNA_mesh_types.h"
32
36
#include "DNA_object_types.h"
33
37
#include "DNA_scene_types.h"
34
38
#include "DNA_screen_types.h"
35
39
#include "DNA_view3d_types.h"
37
#include "BKE_global.h"
38
#include "BKE_utildefines.h"
42
#include "BLI_blenlib.h"
43
#include "BLI_utildefines.h"
39
45
#include "BKE_armature.h"
46
#include "BKE_curve.h"
40
47
#include "BKE_context.h"
48
#include "BKE_tessmesh.h"
41
49
#include "BKE_report.h"
44
#include "BLI_blenlib.h"
45
#include "BLI_editVert.h"
51
#include "BLF_translation.h"
47
53
//#include "BIF_editmesh.h"
48
54
//#include "BIF_interface.h"
67
74
BLI_freelistN(transform_spaces);
69
76
// Need to loop over all view3d
70
if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
77
if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
71
78
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
75
TransformOrientation* findOrientationName(bContext *C, char *name)
82
static TransformOrientation* findOrientationName(ListBase *lb, const char *name)
77
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
78
84
TransformOrientation *ts= NULL;
80
for (ts = transform_spaces->first; ts; ts = ts->next) {
81
if (strncmp(ts->name, name, 35) == 0) {
86
for (ts= lb->first; ts; ts = ts->next) {
87
if (strncmp(ts->name, name, sizeof(ts->name)-1) == 0) {
89
void uniqueOrientationName(bContext *C, char *name)
91
if (findOrientationName(C, name) != NULL)
98
number = strlen(name);
100
if (number && isdigit(name[number-1]))
102
dot = strrchr(name, '.'); // last occurrence
107
for (number = 1; number <= 999; number++)
109
sprintf(tempname, "%s.%03d", name, number);
110
if (findOrientationName(C, tempname) == NULL)
112
BLI_strncpy(name, tempname, 32);
95
static int uniqueOrientationNameCheck(void *arg, const char *name)
97
return findOrientationName((ListBase *)arg, name) != NULL;
100
static void uniqueOrientationName(ListBase *lb, char *name)
102
BLI_uniquename_cb(uniqueOrientationNameCheck, lb, "Space", '.', name, sizeof(((TransformOrientation *)NULL)->name));
119
105
void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite)
135
121
ts = createObjectSpace(C, reports, name, overwrite);
138
if (use && ts != NULL)
124
if (use && ts != NULL) {
140
125
BIF_selectTransformOrientation(C, ts);
144
TransformOrientation *createObjectSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
129
TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite)
145
131
Base *base = CTX_data_active_base(C);
156
142
normalize_m3(mat);
158
144
/* use object name if no name is given */
161
strncpy(name, ob->id.name+2, 35);
146
strncpy(name, ob->id.name+2, MAX_ID_NAME-2);
164
149
return addMatrixSpace(C, mat, name, overwrite);
167
TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
152
TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite)
169
155
float normal[3], plane[3];
180
165
strcpy(name, "Bone");
183
168
return addMatrixSpace(C, mat, name, overwrite);
186
TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) {
171
TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite)
188
174
float normal[3], plane[3];
238
221
float tangent[3] = {0.0f, 0.0f, 1.0f};
240
VECCOPY(mat[2], normal);
223
copy_v3_v3(mat[2], normal);
241
224
if (normalize_v3(mat[2]) == 0.0f) {
242
225
return 0; /* error return */
259
242
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
261
VECCOPY(mat[2], normal);
244
copy_v3_v3(mat[2], normal);
262
245
if (normalize_v3(mat[2]) == 0.0f) {
263
246
return 0; /* error return */
266
249
/* preempt zero length tangent from causing trouble */
267
if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0)
250
if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) {
284
TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) {
266
TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite)
285
268
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
286
269
TransformOrientation *ts = NULL;
290
ts = findOrientationName(C, name);
272
ts = findOrientationName(transform_spaces, name);
294
uniqueOrientationName(C, name);
275
uniqueOrientationName(transform_spaces, name);
297
278
/* if not, create a new one */
300
280
ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix");
301
281
BLI_addtail(transform_spaces, ts);
302
strncpy(ts->name, name, 35);
282
strncpy(ts->name, name, sizeof(ts->name));
305
285
/* copy matrix into transform space */
311
void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) {
291
void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target)
312
293
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
313
TransformOrientation *ts = transform_spaces->first;
294
TransformOrientation *ts;
316
297
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
317
298
if (ts == target) {
318
299
View3D *v3d = CTX_wm_view3d(C);
320
301
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
322
303
// Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
338
void BIF_removeTransformOrientationIndex(bContext *C, int index) {
319
void BIF_removeTransformOrientationIndex(bContext *C, int index)
339
321
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
340
TransformOrientation *ts = transform_spaces->first;
343
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
345
View3D *v3d = CTX_wm_view3d(C);
347
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
349
// Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
350
if (selected_index == i) {
351
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
353
else if (selected_index > i) {
322
TransformOrientation *ts= BLI_findlink(transform_spaces, index);
359
BLI_freelinkN(transform_spaces, ts);
325
View3D *v3d = CTX_wm_view3d(C);
327
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
329
// Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D
330
if (selected_index == index) {
331
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
333
else if (selected_index > index) {
339
BLI_freelinkN(transform_spaces, ts);
365
void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) {
343
void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target)
366
345
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
367
346
View3D *v3d = CTX_wm_view3d(C);
368
TransformOrientation *ts = transform_spaces->first;
347
TransformOrientation *ts;
371
350
for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
379
void BIF_selectTransformOrientationValue(bContext *C, int orientation) {
358
void BIF_selectTransformOrientationValue(bContext *C, int orientation)
380
360
View3D *v3d = CTX_wm_view3d(C);
381
if(v3d) /* currently using generic poll */
361
if (v3d) /* currently using generic poll */
382
362
v3d->twmode = orientation;
401
381
RNA_enum_item_add(&item, &totitem, &local);
402
382
RNA_enum_item_add(&item, &totitem, &view);
405
385
scene= CTX_data_scene(C);
408
388
transform_spaces = &scene->transform_spaces;
409
389
ts = transform_spaces->first;
414
394
RNA_enum_item_add_separator(&item, &totitem);
416
for(; ts; ts = ts->next) {
396
for (; ts; ts = ts->next) {
417
397
tmp.identifier = "CUSTOM";
418
398
tmp.name= ts->name;
428
char * BIF_menustringTransformOrientation(const bContext *C, char *title) {
429
char menu[] = "%t|Global%x0|Local%x1|Gimbal%x4|Normal%x2|View%x3";
408
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");
430
411
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
431
412
TransformOrientation *ts;
432
413
int i = V3D_MANIP_CUSTOM;
433
414
char *str_menu, *p;
436
str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + 40 * BIF_countTransformOrientation(C), "UserTransSpace from matrix");
415
const int elem_size = MAX_NAME + 4;
417
title = IFACE_(title);
419
str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), TIP_("UserTransSpace from matrix"));
439
422
p += sprintf(str_menu, "%s", title);
461
void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) {
445
void applyTransformOrientation(const bContext *C, float mat[3][3], char *name)
462
447
TransformOrientation *ts;
463
448
View3D *v3d = CTX_wm_view3d(C);
464
449
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
487
for(bone= lb->first; bone; bone= bone->next) {
472
for (bone= lb->first; bone; bone= bone->next) {
488
473
bone->flag &= ~BONE_TRANSFORM;
491
if(bone->layer & arm->layer) {
476
if (bone->layer & arm->layer) {
492
477
if (bone->flag & BONE_SELECTED) {
493
478
bone->flag |= BONE_TRANSFORM;
523
508
/* no gimbal fallthrough to normal */
524
509
case V3D_MANIP_NORMAL:
525
if(obedit || (ob && ob->mode & OB_MODE_POSE)) {
510
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
526
511
strcpy(t->spacename, "normal");
527
512
ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE));
531
516
case V3D_MANIP_LOCAL:
532
517
strcpy(t->spacename, "local");
535
520
copy_m3_m4(t->spacemtx, ob->obmat);
536
521
normalize_m3(t->spacemtx);
538
524
unit_m3(t->spacemtx);
543
529
case V3D_MANIP_VIEW:
544
if (t->ar->regiontype == RGN_TYPE_WINDOW)
530
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
546
531
RegionView3D *rv3d = t->ar->regiondata;
589
if(ob->type==OB_MESH)
572
if (ob->type==OB_MESH) {
591
573
Mesh *me= ob->data;
592
EditMesh *em = me->edit_mesh;
574
BMEditMesh *em = me->edit_btmesh;
595
577
float vec[3]= {0,0,0};
597
579
/* USE LAST SELECTED WITH ACTIVE */
598
if (activeOnly && EM_get_actSelection(em, &ese))
600
EM_editselection_normal(normal, &ese);
601
EM_editselection_plane(plane, &ese);
580
if (activeOnly && BM_select_history_active_get(em->bm, &ese)) {
581
BM_editselection_normal(&ese, normal);
582
BM_editselection_plane(&ese, plane);
606
587
result = ORIENTATION_VERT;
609
590
result = ORIENTATION_EDGE;
612
593
result = ORIENTATION_FACE;
618
if (em->totfacesel >= 1)
622
for(efa= em->faces.first; efa; efa= efa->next)
626
VECADD(normal, normal, efa->n);
627
sub_v3_v3v3(vec, efa->v2->co, efa->v1->co);
628
VECADD(plane, plane, vec);
598
if (em->bm->totfacesel >= 1) {
602
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
603
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
604
add_v3_v3(normal, efa->no);
606
BM_FACE_FIRST_LOOP(efa)->v->co,
607
BM_FACE_FIRST_LOOP(efa)->next->v->co);
608
add_v3_v3(plane, vec);
632
612
result = ORIENTATION_FACE;
634
else if (em->totvertsel == 3)
636
EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL;
614
else if (em->bm->totvertsel == 3) {
615
BMVert *v1 = NULL, *v2 = NULL, *v3 = NULL;
637
617
float cotangent[3];
639
for (eve = em->verts.first; eve; eve = eve->next)
641
if ( eve->f & SELECT ) {
619
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
620
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
642
621
if (v1 == NULL) {
659
638
/* if there's an edge available, use that for the tangent */
660
if (em->totedgesel >= 1)
662
EditEdge *eed = NULL;
664
for(eed= em->edges.first; eed; eed= eed->next) {
665
if(eed->f & SELECT) {
639
if (em->bm->totedgesel >= 1) {
643
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
644
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
666
645
sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
672
651
result = ORIENTATION_FACE;
674
else if (em->totedgesel == 1)
678
for(eed= em->edges.first; eed; eed= eed->next) {
679
if(eed->f & SELECT) {
653
else if (em->bm->totedgesel == 1) {
657
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
658
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
680
659
/* use average vert normals as plane and edge vector as normal */
681
VECCOPY(plane, eed->v1->no);
682
VECADD(plane, plane, eed->v2->no);
660
copy_v3_v3(plane, eed->v1->no);
661
add_v3_v3(plane, eed->v2->no);
683
662
sub_v3_v3v3(normal, eed->v2->co, eed->v1->co);
687
666
result = ORIENTATION_EDGE;
689
else if (em->totvertsel == 2)
691
EditVert *v1 = NULL, *v2 = NULL;
693
for (eve = em->verts.first; eve; eve = eve->next)
695
if ( eve->f & SELECT ) {
668
else if (em->bm->totvertsel == 2) {
669
BMVert *v1 = NULL, *v2 = NULL;
672
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
673
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
696
674
if (v1 == NULL) {
702
VECCOPY(plane, v1->no);
703
VECADD(plane, plane, v2->no);
680
copy_v3_v3(plane, v1->no);
681
add_v3_v3(plane, v2->no);
704
682
sub_v3_v3v3(normal, v2->co, v1->co);
709
687
result = ORIENTATION_EDGE;
711
else if (em->totvertsel == 1)
713
for (eve = em->verts.first; eve; eve = eve->next)
715
if ( eve->f & SELECT ) {
716
VECCOPY(normal, eve->no);
689
else if (em->bm->totvertsel == 1) {
692
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
693
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
694
copy_v3_v3(normal, eve->no);
720
698
result = ORIENTATION_VERT;
722
else if (em->totvertsel > 3)
724
normal[0] = normal[1] = normal[2] = 0;
726
for (eve = em->verts.first; eve; eve = eve->next)
728
if ( eve->f & SELECT ) {
700
else if (em->bm->totvertsel > 3) {
705
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
706
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
729
707
add_v3_v3(normal, eve->no);
736
714
} /* end editmesh */
737
else if ELEM(obedit->type, OB_CURVE, OB_SURF)
715
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
739
716
Curve *cu= obedit->data;
744
for (nu = cu->editnurb->first; nu; nu = nu->next)
720
ListBase *nurbs= curve_editnurbs(cu);
722
for (nu = nurbs->first; nu; nu = nu->next) {
746
723
/* only bezier has a normal */
747
if(nu->type == CU_BEZIER)
724
if (nu->type == CU_BEZIER) {
754
if ( (bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT )
730
if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) {
756
731
sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]);
762
735
sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]);
766
738
sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]);
770
741
sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]);
778
if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0)
749
if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) {
780
750
result = ORIENTATION_NORMAL;
783
else if(obedit->type==OB_MBALL)
753
else if (obedit->type==OB_MBALL) {
786
755
/* editmball.c */
787
extern ListBase editelems; /* go away ! */
788
756
MetaElem *ml, *ml_sel = NULL;
790
758
/* loop and check that only one element is selected */
791
for (ml = editelems.first; ml; ml = ml->next)
759
for (ml = editelems.first; ml; ml = ml->next) {
793
760
if (ml->flag & SELECT) {
761
if (ml_sel == NULL) {
810
774
/* Rotation of MetaElem is stored in quat */
811
quat_to_mat4( mat,ml_sel->quat);
775
quat_to_mat4( mat,ml_sel->quat);
813
VECCOPY(normal, mat[2]);
777
copy_v3_v3(normal, mat[2]);
815
779
negate_v3_v3(plane, mat[1]);
822
else if (obedit->type == OB_ARMATURE)
786
else if (obedit->type == OB_ARMATURE) {
824
787
bArmature *arm = obedit->data;
827
790
for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
828
if (arm->layer & ebone->layer)
830
if (ebone->flag & BONE_SELECTED)
791
if (arm->layer & ebone->layer) {
792
if (ebone->flag & BONE_SELECTED) {
834
795
sub_v3_v3v3(vec, ebone->tail, ebone->head);
835
796
normalize_v3(vec);
836
797
add_v3_v3(normal, vec);
838
vec_roll_to_mat3(vec, ebone->roll, mat);
839
add_v3_v3(plane, mat[2]);
799
vec_roll_to_mat3(vec, ebone->roll, tmat);
800
add_v3_v3(plane, tmat[2]);
844
805
normalize_v3(normal);
845
806
normalize_v3(plane);
847
if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0)
808
if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) {
849
809
result = ORIENTATION_EDGE;
854
814
/* Vectors from edges don't need the special transpose inverse multiplication */
855
if (result == ORIENTATION_EDGE)
815
if (result == ORIENTATION_EDGE) {
857
816
mul_mat3_m4_v3(ob->obmat, normal);
858
817
mul_mat3_m4_v3(ob->obmat, plane);
862
820
mul_m3_v3(mat, normal);
863
821
mul_m3_v3(mat, plane);
866
else if(ob && (ob->mode & OB_MODE_POSE))
824
else if (ob && (ob->mode & OB_MODE_POSE)) {
868
825
bArmature *arm= ob->data;
869
826
bPoseChannel *pchan;
872
829
totsel = count_bone_select(arm, &arm->bonebase, 1);
874
831
float imat[3][3], mat[3][3];
876
833
/* use channels to get stats */
877
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
834
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
878
835
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
879
836
add_v3_v3(normal, pchan->pose_mat[2]);
880
837
add_v3_v3(plane, pchan->pose_mat[1]);
893
850
result = ORIENTATION_EDGE;
896
else if(ob && (ob->mode & (OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT)))
853
else if (ob && (ob->mode & (OB_MODE_ALL_PAINT|OB_MODE_PARTICLE_EDIT))) {
900
857
/* we need the one selected object, if its not active */
902
if(ob && !(ob->flag & SELECT)) ob = NULL;
859
if (ob && !(ob->flag & SELECT)) ob = NULL;
904
for(base= scene->base.first; base; base= base->next) {
905
if TESTBASELIB(v3d, base) {
861
for (base= scene->base.first; base; base= base->next) {
862
if (TESTBASELIB(v3d, base)) {
907
864
ob= base->object;
914
VECCOPY(normal, ob->obmat[2]);
915
VECCOPY(plane, ob->obmat[1]);
871
copy_v3_v3(normal, ob->obmat[2]);
872
copy_v3_v3(plane, ob->obmat[1]);
917
874
result = ORIENTATION_NORMAL;
934
891
case ORIENTATION_NORMAL:
935
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0)
892
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
937
893
type = ORIENTATION_NONE;
940
896
case ORIENTATION_VERT:
941
if (createSpaceNormal(orientation_mat, normal) == 0)
897
if (createSpaceNormal(orientation_mat, normal) == 0) {
943
898
type = ORIENTATION_NONE;
946
901
case ORIENTATION_EDGE:
947
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0)
902
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
949
903
type = ORIENTATION_NONE;
952
906
case ORIENTATION_FACE:
953
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0)
907
if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
955
908
type = ORIENTATION_NONE;
960
if (type == ORIENTATION_NONE)
913
if (type == ORIENTATION_NONE) {
962
914
unit_m3(orientation_mat);