[Bf-blender-cvs] [aedff9d] master: Add BKE_mesh_calc_islands_loop_poly_uvmap and use it in new OSD UV subdiv.

Bastien Montagne noreply at git.blender.org
Thu Jul 21 16:55:36 CEST 2016


Commit: aedff9dbef6c5847b6d8e855eb64401d44611f20
Author: Bastien Montagne
Date:   Thu Jul 21 16:53:00 2016 +0200
Branches: master
https://developer.blender.org/rBaedff9dbef6c5847b6d8e855eb64401d44611f20

Add BKE_mesh_calc_islands_loop_poly_uvmap and use it in new OSD UV subdiv.

Also renamed BKE_mesh_calc_islands_loop_poly_uv to BKE_mesh_calc_islands_loop_poly_edgeseam,
to avoid confusion...

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

M	source/blender/blenkernel/BKE_mesh_mapping.h
M	source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
M	source/blender/blenkernel/intern/data_transfer.c
M	source/blender/blenkernel/intern/mesh_mapping.c

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

diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 7689591..b5b5443 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -191,13 +191,21 @@ typedef bool (*MeshRemapIslandsCalc)(
 /* Above vert/UV mapping stuff does not do what we need here, but does things we do not need here.
  * So better keep them separated for now, I think.
  */
-bool BKE_mesh_calc_islands_loop_poly_uv(
+bool BKE_mesh_calc_islands_loop_poly_edgeseam(
         struct MVert *verts, const int totvert,
         struct MEdge *edges, const int totedge,
         struct MPoly *polys, const int totpoly,
         struct MLoop *loops, const int totloop,
         MeshIslandStore *r_island_store);
 
+bool BKE_mesh_calc_islands_loop_poly_uvmap(
+        struct MVert *verts, const int totvert,
+        struct MEdge *edges, const int totedge,
+        struct MPoly *polys, const int totpoly,
+        struct MLoop *loops, const int totloop,
+        const struct MLoopUV *luvs,
+        MeshIslandStore *r_island_store);
+
 int *BKE_mesh_calc_smoothgroups(
         const struct MEdge *medge, const int totedge,
         const struct MPoly *mpoly, const int totpoly,
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
index 9e8c97a..5c68e50 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
@@ -322,11 +322,12 @@ static void conv_dm_precalc_uv_layer(const OpenSubdiv_Converter *converter,
 	}
 
 	/* Calculate islands connectivity of the UVs. */
-	BKE_mesh_calc_islands_loop_poly_uv(
+	BKE_mesh_calc_islands_loop_poly_uvmap(
 	        storage->mvert, dm->getNumVerts(dm),
 	        storage->medge, dm->getNumEdges(dm),
 	        storage->mpoly, dm->getNumPolys(dm),
 	        storage->mloop, dm->getNumLoops(dm),
+	        mloopuv,
 	        &storage->island_store);
 
 	/* Here we "weld" duplicated vertices from island to the same UV value.
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 7292ed2..839673c 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -356,7 +356,7 @@ static MeshRemapIslandsCalc data_transfer_get_loop_islands_generator(const int c
 {
 	switch (cddata_type) {
 		case CD_FAKE_UV:
-			return BKE_mesh_calc_islands_loop_poly_uv;
+			return BKE_mesh_calc_islands_loop_poly_edgeseam;
 		default:
 			break;
 	}
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index dc2e953..1a20300 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -593,12 +593,12 @@ void BKE_mesh_origindex_map_create_looptri(
  */
 typedef bool (*MeshRemap_CheckIslandBoundary)(
         const struct MPoly *mpoly, const struct MLoop *mloop, const struct MEdge *medge,
-        const int nbr_egde_users);
+        const int nbr_egde_users, void *user_data);
 
 static void poly_edge_loop_islands_calc(
         const MEdge *medge, const int totedge, const MPoly *mpoly, const int totpoly,
         const MLoop *mloop, const int totloop, MeshElemMap *edge_poly_map,
-        const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check,
+        const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check, void *edge_boundary_check_data,
         int **r_poly_groups, int *r_totgroup, BLI_bitmap **r_edge_borders, int *r_totedgeborder)
 {
 	int *poly_groups;
@@ -680,7 +680,7 @@ static void poly_edge_loop_islands_calc(
 				const MeshElemMap *map_ele = &edge_poly_map[me_idx];
 				const int *p = map_ele->indices;
 				int i = map_ele->count;
-				if (!edge_boundary_check(mp, ml, me, i)) {
+				if (!edge_boundary_check(mp, ml, me, i, edge_boundary_check_data)) {
 					for (; i--; p++) {
 						/* if we meet other non initialized its a bug */
 						BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id));
@@ -772,7 +772,7 @@ static void poly_edge_loop_islands_calc(
 }
 
 static bool poly_is_island_boundary_smooth_cb(
-        const MPoly *mp, const MLoop *UNUSED(ml), const MEdge *me, const int nbr_egde_users)
+        const MPoly *mp, const MLoop *UNUSED(ml), const MEdge *me, const int nbr_egde_users, void *UNUSED(user_data))
 {
 	/* Edge is sharp if its poly is sharp, or edge itself is sharp, or edge is not used by exactly two polygons. */
 	return (!(mp->flag & ME_SMOOTH) || (me->flag & ME_SHARP) || (nbr_egde_users != 2));
@@ -795,7 +795,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
 
 	poly_edge_loop_islands_calc(
 	        medge, totedge, mpoly, totpoly, mloop, totloop, NULL, use_bitflags,
-	        poly_is_island_boundary_smooth_cb, &poly_groups, r_totgroup, NULL, NULL);
+	        poly_is_island_boundary_smooth_cb, NULL, &poly_groups, r_totgroup, NULL, NULL);
 
 	return poly_groups;
 }
@@ -902,28 +902,59 @@ void BKE_mesh_loop_islands_add(
  *       Would make things much more complex though, and each UVMap would then need its own mesh mapping,
  *       not sure we want that at all!
  */
+typedef struct MeshCheckIslandBoundaryUv {
+	const MLoop *loops;
+	const MLoopUV *luvs;
+	const MeshElemMap *edge_loop_map;
+} MeshCheckIslandBoundaryUv;
+
 static bool mesh_check_island_boundary_uv(
-        const MPoly *UNUSED(mp), const MLoop *UNUSED(ml), const MEdge *me, const int UNUSED(nbr_egde_users))
+        const MPoly *UNUSED(mp), const MLoop *ml, const MEdge *me,
+        const int UNUSED(nbr_egde_users), void *user_data)
 {
-	/* Edge is UV boundary if tagged as seam. */
-	return (me->flag & ME_SEAM) != 0;
+	if (user_data) {
+		const MeshCheckIslandBoundaryUv *data = user_data;
+		const MLoop *loops = data->loops;
+		const MLoopUV *luvs = data->luvs;
+		const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e];
+
+		BLI_assert(edge_to_loops->count >= 2 && (edge_to_loops->count % 2) == 0);
+
+		const unsigned int v1 = loops[edge_to_loops->indices[0]].v;
+		const unsigned int v2 = loops[edge_to_loops->indices[1]].v;
+		const float *uvco_v1 = luvs[edge_to_loops->indices[0]].uv;
+		const float *uvco_v2 = luvs[edge_to_loops->indices[1]].uv;
+		for (int i = 2; i < edge_to_loops->count; i += 2) {
+			if (loops[edge_to_loops->indices[i]].v == v1) {
+				if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]].uv) ||
+				    !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]].uv))
+				{
+					return true;
+				}
+			}
+			else {
+				BLI_assert(loops[edge_to_loops->indices[i]].v == v2);
+				if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]].uv) ||
+				    !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]].uv))
+				{
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	else {
+		/* Edge is UV boundary if tagged as seam. */
+		return (me->flag & ME_SEAM) != 0;
+	}
 }
 
-/**
- * Calculate UV islands.
- *
- * \note Currently we only consider edges tagges as seams as UV boundaries. This has the advantages of simplicity,
- *     and being valid/common to all UV maps. However, it means actual UV islands whithout matching UV seams
- *     will not be handled correctly...
- *
- * \note All this could be optimized...
- *     Not sure it would be worth the more complex code, though, those loops are supposed to be really quick to do...
- */
-bool BKE_mesh_calc_islands_loop_poly_uv(
+static bool mesh_calc_islands_loop_poly_uv(
         MVert *UNUSED(verts), const int UNUSED(totvert),
         MEdge *edges, const int totedge,
         MPoly *polys, const int totpoly,
         MLoop *loops, const int totloop,
+        const MLoopUV *luvs,
         MeshIslandStore *r_island_store)
 {
 	int *poly_groups = NULL;
@@ -933,6 +964,11 @@ bool BKE_mesh_calc_islands_loop_poly_uv(
 	MeshElemMap *edge_poly_map;
 	int *edge_poly_mem;
 
+	MeshElemMap *edge_loop_map;
+	int *edge_loop_mem;
+
+	MeshCheckIslandBoundaryUv edge_boundary_check_data;
+
 	int *poly_indices;
 	int *loop_indices;
 	int num_pidx, num_lidx;
@@ -953,9 +989,18 @@ bool BKE_mesh_calc_islands_loop_poly_uv(
 	BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
 	                              edges, totedge, polys, totpoly, loops, totloop);
 
+	if (luvs) {
+		BKE_mesh_edge_loop_map_create(&edge_loop_map, &edge_loop_mem,
+		                              edges, totedge, polys, totpoly, loops, totloop);
+		edge_boundary_check_data.loops = loops;
+		edge_boundary_check_data.luvs = luvs;
+		edge_boundary_check_data.edge_loop_map = edge_loop_map;
+	}
+
 	poly_edge_loop_islands_calc(
-	        edges, totedge, polys, totpoly, loops, totloop, edge_poly_map, false,
-	        mesh_check_island_boundary_uv, &poly_groups, &num_poly_groups, &edge_borders, &num_edge_borders);
+	            edges, totedge, polys, totpoly, loops, totloop, edge_poly_map, false,
+	            mesh_check_island_boundary_uv, luvs ? &edge_boundary_check_data : NULL,
+	            &poly_groups, &num_poly_groups, &edge_borders, &num_edge_borders);
 
 	if (!num_poly_groups) {
 		/* Should never happen... */
@@ -1012,6 +1057,11 @@ bool BKE_mesh_calc_islands_loop_poly_uv(
 	MEM_freeN(edge_poly_map);
 	MEM_freeN(edge_poly_mem);
 
+	if (luvs) {
+		MEM_freeN(edge_loop_map);
+		MEM_freeN(edge_loop_mem);
+	}
+
 	MEM_freeN(poly_indices);
 	MEM_freeN(loop_indices);
 	MEM_freeN(poly_groups);
@@ -1027,4 +1077,42 @@ bool BKE_mesh_calc_islands_loop_poly_uv(
 	return true;
 }
 
+/**
+ * Calculate 'generic' UV islands, i.e. based only on actual geometry data (edge seams), not some UV layers coordinates.
+ */
+bool BKE_mesh_calc_islands_loop_poly_edgeseam(
+        MVert *verts, const int totvert,
+        MEdge *edges, const int totedge,
+        MPoly *polys, const int totpoly,
+        MLoop *loops, const int totloop,
+        MeshIslandStore *r_island_store)
+{
+	return mesh_calc_islands_loop_poly_uv(
+	            verts, totvert, edges, totedge, polys, totpoly, loops, totloop, NULL, r_island_store);
+}
+
+/**
+ * Calculate UV islands.
+ *
+ * \note If no MLoopUV layer is passed, we only cons

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list