[Bf-blender-cvs] [df94f2f399b] master: Fix T51180: BMesh crash using calc_uvs=True

Campbell Barton noreply at git.blender.org
Mon May 15 08:54:29 CEST 2017


Commit: df94f2f399b7e008fb5c5a1e8865fb659d67e23f
Author: Campbell Barton
Date:   Mon May 15 16:53:57 2017 +1000
Branches: master
https://developer.blender.org/rBdf94f2f399b7e008fb5c5a1e8865fb659d67e23f

Fix T51180: BMesh crash using calc_uvs=True

Don't assume UV layer exist.

===================================================================

M	source/blender/bmesh/intern/bmesh_operators.h
M	source/blender/bmesh/operators/bmo_primitive.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 3eaa24f7bb2..b670f31ad9f 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -141,12 +141,19 @@ void BM_mesh_esubdivide(
         const short use_only_quads,
         const int seed);
 
-void BM_mesh_calc_uvs_grid(BMesh *bm, const uint x_segments, const uint y_segments, const short oflag);
-void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag);
-void BM_mesh_calc_uvs_circle(BMesh *bm, float mat[4][4], const float radius, const short oflag);
+void BM_mesh_calc_uvs_grid(
+        BMesh *bm, const uint x_segments, const uint y_segments,
+        const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_sphere(
+        BMesh *bm,
+        const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_circle(
+        BMesh *bm, float mat[4][4], const float radius,
+        const short oflag, const int cd_loop_uv_offset);
 void BM_mesh_calc_uvs_cone(
         BMesh *bm, float mat[4][4],
-        const float radius_top, const float radius_bottom, const int segments, const bool cap_ends, const short oflag);
+        const float radius_top, const float radius_bottom, const int segments, const bool cap_ends,
+        const short oflag, const int cd_loop_uv_offset);
 void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag);
 
 #include "intern/bmesh_operator_api_inline.h"
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 039a215bdc5..cca0f7387cd 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -764,7 +764,9 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
 	const uint ytot = max_ii(2, BMO_slot_int_get(op->slots_in, "y_segments"));
 	const float xtot_inv2 = 2.0f / (xtot - 1);
 	const float ytot_inv2 = 2.0f / (ytot - 1);
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 
 	BMVert **varr;
 	BMVert *vquad[4];
@@ -814,7 +816,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
 #undef XY
 
 	if (calc_uvs) {
-		BM_mesh_calc_uvs_grid(bm, xtot, ytot, FACE_MARK);
+		BM_mesh_calc_uvs_grid(bm, xtot, ytot, FACE_MARK, cd_loop_uv_offset);
 	}
 }
 
@@ -826,7 +828,9 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
  * \param y_segments The y-resolution of the grid
  * \param oflag The flag to check faces with.
  */
-void BM_mesh_calc_uvs_grid(BMesh *bm, const uint x_segments, const uint y_segments, const short oflag)
+void BM_mesh_calc_uvs_grid(
+        BMesh *bm, const uint x_segments, const uint y_segments,
+        const short oflag, const int cd_loop_uv_offset)
 {
 	BMFace *f;
 	BMLoop *l;
@@ -837,8 +841,6 @@ void BM_mesh_calc_uvs_grid(BMesh *bm, const uint x_segments, const uint y_segmen
 	float x = 0.0f;
 	float y = 0.0f;
 
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
 	int loop_index;
 
 	BLI_assert(cd_loop_uv_offset != -1);
@@ -884,7 +886,9 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
 	const float dia = BMO_slot_float_get(op->slots_in, "diameter");
 	const int seg = BMO_slot_int_get(op->slots_in, "u_segments");
 	const int tot = BMO_slot_int_get(op->slots_in, "v_segments");
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 
 	BMOperator bmop, prevop;
 	BMVert *eve, *preveve;
@@ -982,7 +986,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
 			}
 		}
 
-		BM_mesh_calc_uvs_sphere(bm, FACE_MARK);
+		BM_mesh_calc_uvs_sphere(bm, FACE_MARK, cd_loop_uv_offset);
 	}
 
 	/* and now do imat */
@@ -1000,7 +1004,9 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
 	const float dia = BMO_slot_float_get(op->slots_in, "diameter");
 	const float dia_div = dia / 200.0f;
 	const int subdiv = BMO_slot_int_get(op->slots_in, "subdivisions");
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 
 	BMVert *eva[12];
 	BMVert *v;
@@ -1026,7 +1032,6 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
 	}
 
 	int uvi = 0;
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
 	for (a = 0; a < 20; a++) {
 		BMFace *f;
 		BMVert *v1, *v2, *v3;
@@ -1157,13 +1162,13 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset)
  * \param bm The BMesh to operate on
  * \param oflag The flag to check faces with.
  */
-void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag)
+void BM_mesh_calc_uvs_sphere(
+        BMesh *bm,
+        const short oflag, const int cd_loop_uv_offset)
 {
 	BMFace *f;
 	BMIter iter;
 
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
 	BLI_assert(cd_loop_uv_offset != -1); /* caller is responsible for giving us UVs */
 
 	BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -1206,7 +1211,9 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
 	int i;
 
 	BMO_slot_mat4_get(op->slots_in, "matrix", mat);
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 
 	for (i = 0; i < monkeynv; i++) {
 		float v[3];
@@ -1234,7 +1241,6 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
 	}
 
 	int uvi = 0;
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
 	for (i = 0; i < monkeynf; i++) {
 		BMFace *f_new_a = BM_face_create_quad_tri(bm,
 		                        tv[monkeyf[i][0] + i - monkeyo],
@@ -1283,7 +1289,9 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
 	const int segs = BMO_slot_int_get(op->slots_in, "segments");
 	const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
 	const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 
 	BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
 	float vec[3], mat[4][4], phi, phid;
@@ -1343,7 +1351,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
 		BMO_face_flag_enable(bm, f, FACE_NEW);
 
 		if (calc_uvs) {
-			BM_mesh_calc_uvs_circle(bm, mat, dia, FACE_NEW);
+			BM_mesh_calc_uvs_circle(bm, mat, dia, FACE_NEW, cd_loop_uv_offset);
 		}
 	}
 	
@@ -1362,14 +1370,14 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
  * \param radius The size of the circle.
  * \param oflag The flag to check faces with.
  */
-void BM_mesh_calc_uvs_circle(BMesh *bm, float mat[4][4], const float radius, const short oflag)
+void BM_mesh_calc_uvs_circle(
+        BMesh *bm, float mat[4][4], const float radius,
+        const short oflag, const int cd_loop_uv_offset)
 {
 	BMFace *f;
 	BMLoop *l;
 	BMIter fiter, liter;
 
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
 	const float uv_scale = 0.5f / radius;
 	const float uv_center = 0.5f;
 
@@ -1409,7 +1417,9 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
 	int segs = BMO_slot_int_get(op->slots_in, "segments");
 	const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
 	const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
 	int a;
 	
 	if (!segs)
@@ -1506,7 +1516,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
 	}
 
 	if (calc_uvs) {
-		BM_mesh_calc_uvs_cone(bm, mat, dia2, dia1, segs, cap_ends, FACE_MARK);
+		BM_mesh_calc_uvs_cone(bm, mat, dia2, dia1, segs, cap_ends, FACE_MARK, cd_loop_uv_offset);
 	}
 
 	if (!cap_tris) {
@@ -1530,12 +1540,12 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
  */
 void BM_mesh_calc_uvs_cone(
         BMesh *bm, float mat[4][4],
-        const float radius_top, const float radius_bottom, const int segments, const bool cap_ends, const short oflag)
+        const float radius_top, const float radius_bottom, const int segments, const bool cap_ends,
+        const short oflag, const int cd_loop_uv_offset)
 {
 	BMFace *f;
 	BMLoop *l;
 	BMIter fiter, liter;
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
 
 	const float uv_width = 1.0f / (float)segments;
 	const float uv_height = cap_ends ? 0.5f : 1.0f;
@@ -1627,8 +1637,10 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
 	BMVert *verts[8];
 	float mat[4][4];
 	float off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
-	const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
-	int i, x, y, z;
+
+	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+	const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
 	/* rotation order set to match 'BM_mesh_calc_uvs_cube' */
 	const char faces[6][4] = {
 		{0, 1, 3, 2},
@@ -1642,11 +1654,11 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
 	BMO_slot_mat4_get(op->slots_in, "matrix", mat);
 
 	if (!off) off = 0.5f;
-	i = 0;
+	int i = 0;
 
-	for (x = -1; x < 2; x += 2) {
-		for (y = -1; y < 2; y += 2) {
-			for (z = -1; z < 2; z += 2) {
+	for (int x = -1; x < 2; x += 2) {
+		for (int y = -1; y < 2; y += 2) {
+			for (int z = -1; z < 2; z += 2) {
 				float vec[3] = {(float)x * off, (float)y * off, (float)z * off};
 				mul_m4_v3(mat

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list