[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60260] trunk/blender/source/blender: Fix [#36759] UV Project - Specified UV Map doesnt work properly

Bastien Montagne montagne29 at wanadoo.fr
Fri Sep 20 13:14:08 CEST 2013


Revision: 60260
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60260
Author:   mont29
Date:     2013-09-20 11:14:08 +0000 (Fri, 20 Sep 2013)
Log Message:
-----------
Fix [#36759] UV Project - Specified UV Map doesnt work properly

In fact, the issue was that names of mloopuv/mtespoly layers could very easily get out of sync (a simple rename was enough), while most tools (such as the UVProject modifier) expect matching layers to have the same name!

Now matching names are check on load, and renaming of a layer through RNA is guaranted to be synchronized with its counterparts.

Thanks to Brecht & Campbell for reviews.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_mesh.h
    trunk/blender/source/blender/blenkernel/intern/mesh.c
    trunk/blender/source/blender/blenkernel/intern/mesh_validate.c
    trunk/blender/source/blender/makesrna/intern/rna_mesh.c

Modified: trunk/blender/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_mesh.h	2013-09-20 10:14:58 UTC (rev 60259)
+++ trunk/blender/source/blender/blenkernel/BKE_mesh.h	2013-09-20 11:14:08 UTC (rev 60260)
@@ -119,6 +119,10 @@
 void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]);
 void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob);
 
+bool BKE_mesh_uv_cdlayer_rename_index(struct Mesh *me, const int poly_index, const int loop_index, const int face_index,
+                                      const char *new_name, const bool do_tessface);
+bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const char *new_name, bool do_tessface);
+
 float (*BKE_mesh_vertexCos_get(struct Mesh *me, int *r_numVerts))[3];
 
 /* vertex level transformations & checks (no derived mesh) */

Modified: trunk/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh.c	2013-09-20 10:14:58 UTC (rev 60259)
+++ trunk/blender/source/blender/blenkernel/intern/mesh.c	2013-09-20 11:14:08 UTC (rev 60260)
@@ -40,6 +40,8 @@
 #include "BLI_math.h"
 #include "BLI_listbase.h"
 #include "BLI_edgehash.h"
+#include "BLI_string_utf8.h"
+#include "BLI_string.h"
 
 #include "BKE_animsys.h"
 #include "BKE_main.h"
@@ -622,6 +624,86 @@
 	}
 }
 
+bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index,
+                                      const char *new_name, const bool do_tessface)
+{
+	CustomData *pdata = &me->pdata, *ldata = &me->ldata, *fdata = &me->fdata;
+	CustomDataLayer *cdlp = &pdata->layers[poly_index];
+	CustomDataLayer *cdlu = &ldata->layers[loop_index];
+	CustomDataLayer *cdlf = do_tessface ? &fdata->layers[face_index] : NULL;
+	const int step = do_tessface ? 3 : 2;
+	int i;
+
+	BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
+	CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+
+	/* Loop until we do have exactly the same name for all layers! */
+	for (i = 1; (strcmp(cdlp->name, cdlu->name) != 0 || (cdlf && strcmp(cdlp->name, cdlf->name) != 0)); i++) {
+		switch (i % step) {
+			case 0:
+				BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
+				CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+				break;
+			case 1:
+				BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
+				CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
+				break;
+			case 2:
+				BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
+				CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
+				break;
+		}
+	}
+
+	return true;
+}
+
+bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
+{
+	CustomData *pdata = &me->pdata, *ldata = &me->ldata, *fdata = &me->fdata;
+	const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
+	const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
+	const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
+	int pidx, lidx, fidx;
+
+	do_tessface = (do_tessface && fdata->totlayer);
+	pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
+	lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
+	fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
+
+	/* None of those cases should happen, in theory!
+	 * Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
+	 */
+	if (pidx == -1) {
+		if (lidx == -1) {
+			if (fidx == -1) {
+				/* No layer found with this name! */
+				return false;
+			}
+			else {
+				lidx = lidx_start + (fidx - fidx_start);
+			}
+		}
+		pidx = pidx_start + (lidx - lidx_start);
+	}
+	else {
+		if (lidx == -1) {
+			lidx = lidx_start + (pidx - pidx_start);
+		}
+		if (fidx == -1 && do_tessface) {
+			fidx = fidx_start + (pidx - pidx_start);
+		}
+	}
+#if 0
+	/* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
+	else if ((pidx - pidx_start) != (lidx - lidx_start)) {
+		lidx = lidx_start + (pidx - pidx_start);
+	}
+#endif
+
+	return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
+}
+
 void BKE_mesh_boundbox_calc(Mesh *me, float r_loc[3], float r_size[3])
 {
 	BoundBox *bb;

Modified: trunk/blender/source/blender/blenkernel/intern/mesh_validate.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh_validate.c	2013-09-20 10:14:58 UTC (rev 60259)
+++ trunk/blender/source/blender/blenkernel/intern/mesh_validate.c	2013-09-20 11:14:08 UTC (rev 60260)
@@ -989,28 +989,37 @@
 {
 	int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
 	int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+	int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
+	int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
+	int i;
 
 	if (LIKELY(totlayer_mtex == totlayer_uv)) {
 		/* pass */
 	}
 	else if (totlayer_mtex < totlayer_uv) {
-		const int uv_index_first = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
 		do {
-			const char *from_name =  me->ldata.layers[uv_index_first + totlayer_mtex].name;
+			const char *from_name =  me->ldata.layers[uv_index + totlayer_mtex].name;
 			CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name);
 			CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex);
 		} while (totlayer_uv != ++totlayer_mtex);
 	}
 	else if (totlayer_uv < totlayer_mtex) {
-		const int mtex_index_first = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
 		do {
-			const char *from_name = me->pdata.layers[mtex_index_first + totlayer_uv].name;
+			const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name;
 			CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name);
 			CustomData_set_layer_unique_name(&me->ldata, totlayer_uv);
 		} while (totlayer_mtex != ++totlayer_uv);
 	}
 
 	BLI_assert(totlayer_mtex == totlayer_uv);
+
+	/* Check uv/tex names match as well!!! */
+	for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) {
+		const char *name = me->pdata.layers[mtex_index].name;
+		if (strcmp(name, me->ldata.layers[uv_index].name) != 0) {
+			BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name, false);
+		}
+	}
 }
 /** \} */
 

Modified: trunk/blender/source/blender/makesrna/intern/rna_mesh.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_mesh.c	2013-09-20 10:14:58 UTC (rev 60259)
+++ trunk/blender/source/blender/makesrna/intern/rna_mesh.c	2013-09-20 11:14:08 UTC (rev 60260)
@@ -184,18 +184,22 @@
 	rna_cd_layer_name_set(rna_mesh_edata(ptr), (CustomDataLayer *)ptr->data, value);
 }
 #endif
+#if 0
 static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value)
 {
 	rna_cd_layer_name_set(rna_mesh_pdata(ptr), (CustomDataLayer *)ptr->data, value);
 }
+#endif
 static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
 {
 	rna_cd_layer_name_set(rna_mesh_ldata(ptr), (CustomDataLayer *)ptr->data, value);
 }
+#if 0
 static void rna_MeshTessfaceLayer_name_set(PointerRNA *ptr, const char *value)
 {
 	rna_cd_layer_name_set(rna_mesh_fdata(ptr), (CustomDataLayer *)ptr->data, value);
 }
+#endif
 /* only for layers shared between types */
 static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value)
 {
@@ -684,6 +688,14 @@
 	CustomData_set_layer_clone_index(data, type, n);
 }
 
+/* Generic UV rename! */
+static void rna_MeshUVLayer_name_set(PointerRNA *ptr, const char *name)
+{
+	char buf[MAX_CUSTOMDATA_LAYER_NAME];
+	BLI_strncpy_utf8(buf, name, MAX_CUSTOMDATA_LAYER_NAME);
+	BKE_mesh_uv_cdlayer_rename(rna_mesh(ptr), ((CustomDataLayer *)ptr->data)->name, buf, true);
+}
+
 /* uv_layers */
 
 DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_MLOOPUV)
@@ -1961,7 +1973,7 @@
 
 	prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
-	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshLoopLayer_name_set");
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "Name of UV map");
 	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
@@ -1999,7 +2011,7 @@
 
 	prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
-	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshTessfaceLayer_name_set");
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "Name of UV map");
 	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
@@ -2111,7 +2123,7 @@
 
 	prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
-	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set");
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "Name of UV map");
 	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 




More information about the Bf-blender-cvs mailing list