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:
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h2
-rw-r--r--source/blender/blenlib/intern/math_matrix.c13
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c82
3 files changed, 70 insertions, 27 deletions
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index a5ab2373b89..97cd6a60862 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -88,6 +88,7 @@ void mul_serie_m4(float R[4][4],
void mul_m4_v3(float M[4][4], float r[3]);
void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
+void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
void mul_mat3_m4_v3(float M[4][4], float r[3]);
void mul_m4_v4(float M[4][4], float r[4]);
void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
@@ -170,6 +171,7 @@ void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
+void rotate_m2(float mat[2][2], const float angle);
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 5c443b9b1f3..c12588463b0 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -344,6 +344,12 @@ void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3])
in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
+void mul_v2_m2v2(float r[2], float M[2][2], const float v[2])
+{
+ r[0] = M[0][0]*v[0] + M[1][0]*v[1];
+ r[1] = M[0][1]*v[0] + M[1][1]*v[1];
+}
+
/* same as mul_m4_v3() but doesnt apply translation component */
void mul_mat3_m4_v3(float mat[4][4], float vec[3])
{
@@ -1304,6 +1310,13 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
}
}
+void rotate_m2(float mat[2][2], const float angle)
+{
+ mat[0][0] = mat[1][1] = cosf(angle);
+ mat[0][1] = sinf(angle);
+ mat[1][0] = -mat[0][1];
+}
+
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 1b43d829947..b7e12dda663 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -100,11 +100,13 @@ struct IslandStitchData;
typedef struct IslandStitchData {
/* rotation can be used only for edges, for vertices there is no such notion */
float rotation;
+ float rotation_neg;
float translation[2];
/* Used for rotation, the island will rotate around this point */
float medianPoint[2];
int numOfElements;
int num_rot_elements;
+ int num_rot_elements_neg;
/* flag to remember if island has been added for preview */
char addedForPreview;
/* flag an island to be considered for determining static island */
@@ -286,20 +288,15 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
}
}
-static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2], float aspect)
+static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect)
{
float uv_rotation_result[2];
uv[1] /= aspect;
- uv[0] -= medianPoint[0];
- uv[1] -= medianPoint[1];
-
- uv_rotation_result[0] = cosf(rotation) * uv[0] - sinf(rotation) * uv[1];
- uv_rotation_result[1] = sinf(rotation) * uv[0] + cosf(rotation) * uv[1];
-
- uv[0] = uv_rotation_result[0] + medianPoint[0];
- uv[1] = uv_rotation_result[1] + medianPoint[1];
+ sub_v2_v2(uv, medianPoint);
+ mul_v2_m2v2(uv_rotation_result, mat, uv);
+ add_v2_v2v2(uv, uv_rotation_result, medianPoint);
uv[1] *= aspect;
}
@@ -412,17 +409,35 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
for (i = 0; i < state->element_map->totalIslands; i++) {
if (island_stitch_data[i].addedForPreview) {
int numOfIslandUVs = 0, j;
+ int totelem = island_stitch_data[i].num_rot_elements_neg + island_stitch_data[i].num_rot_elements;
+ float rotation;
+ float rotation_mat[2][2];
/* check to avoid divide by 0 */
- if (island_stitch_data[i].num_rot_elements > 0) {
+ if (island_stitch_data[i].num_rot_elements > 1)
island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
+
+ if (island_stitch_data[i].num_rot_elements_neg > 1)
+ island_stitch_data[i].rotation_neg /= island_stitch_data[i].num_rot_elements_neg;
+
+ if (island_stitch_data[i].numOfElements > 1) {
island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
- island_stitch_data[i].medianPoint[1] /= state->aspect;
+
+ island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
+ island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
}
- island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
- island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
+ island_stitch_data[i].medianPoint[1] /= state->aspect;
+ if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg < M_PI_2) ||
+ island_stitch_data[i].num_rot_elements == 0 || island_stitch_data[i].num_rot_elements_neg == 0)
+ rotation = (island_stitch_data[i].rotation*island_stitch_data[i].num_rot_elements -
+ island_stitch_data[i].rotation_neg*island_stitch_data[i].num_rot_elements_neg)/totelem;
+ else
+ rotation = (island_stitch_data[i].rotation*island_stitch_data[i].num_rot_elements +
+ (2*M_PI - island_stitch_data[i].rotation_neg)*island_stitch_data[i].num_rot_elements_neg)/totelem;
+
+ rotate_m2(rotation_mat, rotation);
numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
element = &state->element_map->buf[state->element_map->islandIndices[i]];
for (j = 0; j < numOfIslandUVs; j++, element++) {
@@ -436,15 +451,16 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
if (final) {
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
+ stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
add_v2_v2(luv->uv, island_stitch_data[i].translation);
}
else {
+
int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint,
+ stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint,
preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect);
add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
@@ -500,13 +516,15 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta
edgecos = dot_v2v2(uv1, uv2);
edgesin = cross_v2v2(uv1, uv2);
+ rotation = acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
- rotation = (edgesin > 0.0f) ?
- +acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
- -acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
-
- island_stitch_data[element1->island].num_rot_elements++;
- island_stitch_data[element1->island].rotation += rotation;
+ if (edgesin > 0.0f) {
+ island_stitch_data[element1->island].num_rot_elements++;
+ island_stitch_data[element1->island].rotation += rotation;
+ } else {
+ island_stitch_data[element1->island].num_rot_elements_neg++;
+ island_stitch_data[element1->island].rotation_neg += rotation;
+ }
}
@@ -515,7 +533,8 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
float edgecos = 1.0f, edgesin = 0.0f;
int index;
UvElement *element_iter;
- float rotation = 0;
+ float rotation = 0, rotation_neg = 0;
+ int rot_elem = 0, rot_elem_neg = 0;
BMLoop *l;
if (element->island == state->static_island && !state->midpoints)
@@ -544,16 +563,25 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
negate_v2_v2(normal, state->normals + index_tmp2 * 2);
edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
- rotation += (edgesin > 0.0f) ?
- +acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
- -acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ if (edgesin > 0.0f) {
+ rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ rot_elem++;
+ }
+ else {
+ rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ rot_elem_neg++;
+ }
}
}
- if (state->midpoints)
+ if (state->midpoints) {
rotation /= 2.0f;
- island_stitch_data[element->island].num_rot_elements++;
+ rotation_neg /= 2.0f;
+ }
+ island_stitch_data[element->island].num_rot_elements += rot_elem;
island_stitch_data[element->island].rotation += rotation;
+ island_stitch_data[element->island].num_rot_elements_neg += rot_elem_neg;
+ island_stitch_data[element->island].rotation_neg += rotation_neg;
}