Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_orientations.c')
-rw-r--r--source/blender/editors/transform/transform_orientations.c183
1 files changed, 119 insertions, 64 deletions
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e805743e6bb..69dfc4a7ad4 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BKE_action.h"
+#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
@@ -52,6 +53,7 @@
#include "ED_armature.h"
#include "transform.h"
+#include "transform_orientations.h"
/* *********************** TransSpace ************************** */
@@ -239,6 +241,54 @@ static TransformOrientation *createMeshSpace(bContext *C,
return addMatrixSpace(C, mat, name, overwrite);
}
+bool transform_orientations_create_from_axis(float mat[3][3],
+ const float x[3],
+ const float y[3],
+ const float z[3])
+{
+ bool is_zero[3] = {true, true, true};
+ zero_m3(mat);
+ if (x) {
+ is_zero[0] = normalize_v3_v3(mat[0], x) == 0.0f;
+ }
+ if (y) {
+ is_zero[1] = normalize_v3_v3(mat[1], y) == 0.0f;
+ }
+ if (z) {
+ is_zero[2] = normalize_v3_v3(mat[2], z) == 0.0f;
+ }
+
+ int zero_axis = is_zero[0] + is_zero[1] + is_zero[2];
+ if (zero_axis == 0) {
+ return true;
+ }
+
+ if (zero_axis == 1) {
+ int axis = is_zero[0] ? 0 : is_zero[1] ? 1 : 2;
+ cross_v3_v3v3(mat[axis], mat[(axis + 1) % 3], mat[(axis + 2) % 3]);
+ if (normalize_v3(mat[axis]) != 0.0f) {
+ return true;
+ }
+ }
+ else if (zero_axis == 2) {
+ int axis, a, b;
+ axis = !is_zero[0] ? 0 : !is_zero[1] ? 1 : 2;
+ a = (axis + 1) % 3;
+ b = (axis + 2) % 3;
+
+ mat[a][a] = 1.0f;
+ mat[b][b] = 1.0f;
+ project_plane_v3_v3v3(mat[a], mat[a], mat[axis]);
+ project_plane_v3_v3v3(mat[b], mat[b], mat[axis]);
+ if ((normalize_v3(mat[a]) != 0.0f) && (normalize_v3(mat[b]) != 0.0f)) {
+ return true;
+ }
+ }
+
+ unit_m3(mat);
+ return false;
+}
+
bool createSpaceNormal(float mat[3][3], const float normal[3])
{
float tangent[3] = {0.0f, 0.0f, 1.0f};
@@ -475,7 +525,7 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
}
case V3D_ORIENT_NORMAL: {
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
- ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
+ ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat);
return V3D_ORIENT_NORMAL;
}
/* no break we define 'normal' as 'local' in Object mode */
@@ -485,14 +535,13 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
if (ob) {
if (ob->mode & OB_MODE_POSE) {
/* each bone moves on its own local axis, but to avoid confusion,
- * use the active pones axis for display [#33575], this works as expected on a single
+ * use the active pones axis for display T33575, this works as expected on a single
* bone and users who select many bones will understand what's going on and what local
* means when they start transforming */
- ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
+ ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat);
}
else {
- copy_m3_m4(r_mat, ob->obmat);
- normalize_m3(r_mat);
+ transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat));
}
return V3D_ORIENT_LOCAL;
}
@@ -533,42 +582,39 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
/* Sets the matrix of the specified space orientation.
* If the matrix cannot be obtained, an orientation different from the one
* informed is returned */
-short transform_orientation_matrix_get(bContext *C,
- TransInfo *t,
- const short orientation,
- const float custom[3][3],
- float r_spacemtx[3][3])
+short transform_orientation_matrix_get(
+ bContext *C, TransInfo *t, short orientation, const float custom[3][3], float r_spacemtx[3][3])
{
if (orientation == V3D_ORIENT_CUSTOM_MATRIX) {
copy_m3_m3(r_spacemtx, custom);
return V3D_ORIENT_CUSTOM_MATRIX;
}
- if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
- Object *ob = CTX_data_active_object(C);
- Object *obedit = CTX_data_active_object(C);
- RegionView3D *rv3d = t->region->regiondata;
- int orientation_index_custom = 0;
+ Object *ob = CTX_data_active_object(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = t->scene;
+ RegionView3D *rv3d = NULL;
+ int orientation_index_custom = 0;
- if (orientation >= V3D_ORIENT_CUSTOM) {
- orientation_index_custom = orientation - V3D_ORIENT_CUSTOM;
- }
+ if (orientation >= V3D_ORIENT_CUSTOM) {
+ orientation_index_custom = orientation - V3D_ORIENT_CUSTOM;
+ orientation = V3D_ORIENT_CUSTOM;
+ }
- return ED_transform_calc_orientation_from_type_ex(
- C,
- r_spacemtx,
- /* extra args (can be accessed from context) */
- t->scene,
- rv3d,
- ob,
- obedit,
- orientation,
- orientation_index_custom,
- t->around);
+ if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
+ rv3d = t->region->regiondata;
}
- unit_m3(r_spacemtx);
- return V3D_ORIENT_GLOBAL;
+ return ED_transform_calc_orientation_from_type_ex(C,
+ r_spacemtx,
+ /* extra args (can be accessed from context) */
+ scene,
+ rv3d,
+ ob,
+ obedit,
+ orientation,
+ orientation_index_custom,
+ t->around);
}
const char *transform_orientations_spacename_get(TransInfo *t, const short orient_type)
@@ -599,12 +645,17 @@ const char *transform_orientations_spacename_get(TransInfo *t, const short orien
void transform_orientations_current_set(TransInfo *t, const short orient_index)
{
+ if (t->orient_curr == orient_index) {
+ return;
+ }
+
const short orientation = t->orient[orient_index].type;
const char *spacename = transform_orientations_spacename_get(t, orientation);
BLI_strncpy(t->spacename, spacename, sizeof(t->spacename));
copy_m3_m3(t->spacemtx, t->orient[orient_index].matrix);
- invert_m3_m3(t->spacemtx_inv, t->spacemtx);
+ invert_m3_m3_safe_ortho(t->spacemtx_inv, t->spacemtx);
+ t->orient_curr = orient_index;
}
/**
@@ -685,15 +736,14 @@ static uint bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const uint n)
#endif
int getTransformOrientation_ex(const bContext *C,
+ struct Object *ob,
+ struct Object *obedit,
float normal[3],
float plane[3],
const short around)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- Object *obedit = CTX_data_edit_object(C);
- Base *base;
- Object *ob = OBACT(view_layer);
int result = ORIENTATION_NONE;
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
@@ -766,7 +816,7 @@ int getTransformOrientation_ex(const bContext *C,
}
if (em->bm->totedgesel >= 1) {
- /* find an edge that's apart of v_tri (no need to search all edges) */
+ /* find an edge that's a part of v_tri (no need to search all edges) */
float e_length;
int j;
@@ -1185,30 +1235,30 @@ int getTransformOrientation_ex(const bContext *C,
result = ORIENTATION_EDGE;
}
}
- else if (ob && (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) {
- /* pass */
- }
else {
/* we need the one selected object, if its not active */
- base = BASACT(view_layer);
- ob = OBACT(view_layer);
- if (base && ((base->flag & BASE_SELECTED) != 0)) {
- /* pass */
- }
- else {
- /* first selected */
- ob = NULL;
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTED_EDITABLE(v3d, base)) {
- ob = base->object;
- break;
+ if (ob != NULL) {
+ bool ok = false;
+ if (activeOnly || (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) {
+ /* Ignore selection state. */
+ ok = true;
+ }
+ else {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (UNLIKELY(base == NULL)) {
+ /* This is very unlikely, if it happens allow the value to be set since the caller
+ * may have taken the object from outside this view-layer. */
+ ok = true;
+ }
+ else if (BASE_SELECTED(v3d, base)) {
+ ok = true;
}
}
- }
- if (ob) {
- copy_v3_v3(normal, ob->obmat[2]);
- copy_v3_v3(plane, ob->obmat[1]);
+ if (ok) {
+ copy_v3_v3(normal, ob->obmat[2]);
+ copy_v3_v3(plane, ob->obmat[1]);
+ }
}
result = ORIENTATION_NORMAL;
}
@@ -1218,22 +1268,27 @@ int getTransformOrientation_ex(const bContext *C,
int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
{
+ Object *obact = CTX_data_active_object(C);
+ Object *obedit = CTX_data_edit_object(C);
+
/* dummy value, not V3D_AROUND_ACTIVE and not V3D_AROUND_LOCAL_ORIGINS */
short around = V3D_AROUND_CENTER_BOUNDS;
- return getTransformOrientation_ex(C, normal, plane, around);
+ return getTransformOrientation_ex(C, obact, obedit, normal, plane, around);
}
void ED_getTransformOrientationMatrix(const bContext *C,
- float orientation_mat[3][3],
- const short around)
+ struct Object *ob,
+ struct Object *obedit,
+ const short around,
+ float r_orientation_mat[3][3])
{
float normal[3] = {0.0, 0.0, 0.0};
float plane[3] = {0.0, 0.0, 0.0};
int type;
- type = getTransformOrientation_ex(C, normal, plane, around);
+ type = getTransformOrientation_ex(C, ob, obedit, normal, plane, around);
/* Fallback, when the plane can't be calculated. */
if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
@@ -1242,22 +1297,22 @@ void ED_getTransformOrientationMatrix(const bContext *C,
switch (type) {
case ORIENTATION_NORMAL:
- if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
+ if (createSpaceNormalTangent(r_orientation_mat, normal, plane) == 0) {
type = ORIENTATION_NONE;
}
break;
case ORIENTATION_VERT:
- if (createSpaceNormal(orientation_mat, normal) == 0) {
+ if (createSpaceNormal(r_orientation_mat, normal) == 0) {
type = ORIENTATION_NONE;
}
break;
case ORIENTATION_EDGE:
- if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
+ if (createSpaceNormalTangent(r_orientation_mat, normal, plane) == 0) {
type = ORIENTATION_NONE;
}
break;
case ORIENTATION_FACE:
- if (createSpaceNormalTangent(orientation_mat, normal, plane) == 0) {
+ if (createSpaceNormalTangent(r_orientation_mat, normal, plane) == 0) {
type = ORIENTATION_NONE;
}
break;
@@ -1267,6 +1322,6 @@ void ED_getTransformOrientationMatrix(const bContext *C,
}
if (type == ORIENTATION_NONE) {
- unit_m3(orientation_mat);
+ unit_m3(r_orientation_mat);
}
}