[Bf-blender-cvs] [7ce2f6d] mesh-transfer-data: First hook of islands system for Loop-data transfer.

Bastien Montagne noreply at git.blender.org
Mon Oct 13 20:16:37 CEST 2014


Commit: 7ce2f6df57408fcdae08971838a375b5978b822c
Author: Bastien Montagne
Date:   Mon Oct 13 16:45:34 2014 +0200
Branches: mesh-transfer-data
https://developer.blender.org/rB7ce2f6df57408fcdae08971838a375b5978b822c

First hook of islands system for Loop-data transfer.

Very basic tests with UVs seems to be working.

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

M	source/blender/blenkernel/BKE_mesh_mapping.h
M	source/blender/blenkernel/intern/mesh_mapping.c
M	source/blender/editors/object/object_transfer_data.c

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

diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 93cee28..e60e420 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -136,6 +136,34 @@ int *BKE_mesh_calc_smoothgroups(
         const struct MLoop *mloop, const int totloop,
         int *r_totgroup, const bool use_bitflags);
 
+/* Loop islands data helpers. */
+/* TODO: this ended up being the same as MeshElemMap... Should we use this generic struct instead? */
+typedef struct MeshIslandItem {
+	int *polys_idx;
+	int nbr_polys;
+} MeshIslandItem;
+
+/* For loops, to which poly island each loop belongs.
+ * Island definition can vary based on data type (UVs, loop normals, etc.). */
+typedef struct MeshIslands {
+	int nbr_loops;
+	int *loops_to_islands_idx;
+	int nbr_islands;
+	MeshIslandItem *islands;  /* Array, one item per island. */
+	void *mem;  /* Memory handler, internal use only. */
+} MeshIslands;
+
+void BKE_loop_islands_init(MeshIslands *islands, const int num_loops);
+void BKE_loop_islands_free(MeshIslands *islands);
+void BKE_loop_islands_add_island(MeshIslands *islands, const int num_loops, int *loop_indices,
+                                 const int num_polys, int *poly_indices);
+
+typedef bool (*loop_island_compute)(struct DerivedMesh *dm, MeshIslands *r_islands);
+/* 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_loop_island_compute_uv(struct DerivedMesh *dm, MeshIslands *r_islands);
+
 /* Generic ways to map some geometry elements from a source mesh to a dest one. */
 
 typedef struct Mesh2MeshMappingItem {
@@ -153,37 +181,9 @@ typedef struct Mesh2MeshMapping {
 	void *mem;  /* Memory handler, internal use only. */
 } Mesh2MeshMapping;
 
-
-typedef struct Mesh2MeshMappingIslandItem {
-	int nbr_polys;
-	int *polys_idx;
-} Mesh2MeshMappingIslandItem;
-
-/* For loops, to which poly island each loop belongs.
- * Island definition can vary based on data type (UVs, loop normals, etc.). */
-typedef struct Mesh2MeshMappingIslands {
-	int nbr_loops;
-	int *loops_to_islands_idx;
-	int nbr_islands;
-	Mesh2MeshMappingIslandItem *islands;  /* Array, one item per island. */
-	void *mem;  /* Memory handler, internal use only. */
-} Mesh2MeshMappingIslands;
-
-typedef bool (*loop_island_compute)(struct DerivedMesh *dm, Mesh2MeshMappingIslands *r_islands);
-/* 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_loop_island_compute_uv((struct DerivedMesh *dm, Mesh2MeshMappingIslands *r_islands);
-
-
 /* Helpers! */
 void BKE_mesh2mesh_mapping_free(Mesh2MeshMapping *map);
 
-void BKE_mesh2mesh_mapping_islands_create(Mesh2MeshMappingIslands *r_islands, const int num_loops);
-void BKE_mesh2mesh_mapping_islands_add_island(Mesh2MeshMappingIslands *r_islands,
-                                              const int num_loops, int *loop_indices,
-                                              const int num_polys, int *poly_indices);
-
 /* TODO:
  * Add other 'from/to' mapping sources, like e.g. using an UVMap, etc.
  *     http://blenderartists.org/forum/showthread.php?346458-Move-Vertices-to-the-location-of-the-Reference-Mesh-based-on-the-UV-Position
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 884c1cd..dd6d93d 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -370,22 +370,40 @@ void BKE_mesh_origindex_map_create(MeshElemMap **r_map, int **r_mem,
 /** \} */
 
 
-
 /* -------------------------------------------------------------------- */
 
-/** \name Mesh Smooth Groups
+/** \name Mesh loops/poly islands.
+ * Used currently for UVs and 'smooth groups'.
  * \{ */
 
-/**
- * Calculate smooth groups from sharp edges.
- *
- * \param r_totgroup The total number of groups, 1 or more.
- * \return Polygon aligned array of group index values (bitflags if use_bitflags is true), starting at 1.
+/** Callback deciding whether the given poly/loop/edge define an island boundary or not.
  */
-int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
-                                const MPoly *mpoly, const int totpoly,
-                                const MLoop *mloop, const int totloop,
-                                int *r_totgroup, const bool use_bitflags)
+typedef bool (*check_island_boundary)(const MPoly *mpoly, const MLoop *mloop, const MEdge *medge,
+                                      const int nbr_egde_users);
+
+static bool bke_check_island_boundary_smooth(const MPoly *mp, const MLoop *UNUSED(ml), const MEdge *me,
+                                             const int nbr_egde_users)
+{
+	/* 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));
+}
+
+/* TODO: I'm not sure edge seam flag is enough to define UV islands? Maybe we should also consider UVmaps values
+ *       themselves (i.e. different UV-edges for a same mesh-edge => boun dary edge too?).
+ *       Would make things much more complex though, and each UVMap would then need its own mesh mapping,
+ *       not sure we want that at all!
+ */
+static bool bke_check_island_boundary_uv(const MPoly *UNUSED(mp), const MLoop *UNUSED(ml), const MEdge *me,
+                                         const int UNUSED(nbr_egde_users))
+{
+	/* Edge is UV boundary if tagged as seam. */
+	return (me->flag & ME_SEAM) != 0;
+}
+
+static void bke_poly_loop_islands_compute(const MEdge *medge, const int totedge, const MPoly *mpoly, const int totpoly,
+                                          const MLoop *mloop, const int totloop, const bool use_bitflags,
+                                          check_island_boundary edge_boundary_check,
+                                          int **r_poly_groups, int *r_totgroup)
 {
 	int *poly_groups;
 	int *poly_stack;
@@ -402,7 +420,8 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
 
 	if (totpoly == 0) {
 		*r_totgroup = 0;
-		return NULL;
+		*r_poly_groups = NULL;
+		return;
 	}
 
 	BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
@@ -441,22 +460,19 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
 		while (ps_curr_idx != ps_end_idx) {
 			const MPoly *mp;
 			const MLoop *ml;
-			bool sharp_poly;
 			int j;
 
 			poly = poly_stack[ps_curr_idx++];
 			BLI_assert(poly_groups[poly] == poly_group_id);
 
 			mp = &mpoly[poly];
-			sharp_poly = !(mp->flag & ME_SMOOTH);
 			for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) {
 				/* loop over poly users */
+				const MEdge *me = &medge[ml->e];
 				const MeshElemMap *map_ele = &edge_poly_map[ml->e];
 				const int *p = map_ele->indices;
 				int i = map_ele->count;
-				/* Edge is smooth only if its poly is not sharp, edge is not sharp,
-				 * and edge is used by exactly two polygons. */
-				if (!sharp_poly && !(medge[ml->e].flag & ME_SHARP) && i == 2) {
+				if (!edge_boundary_check(mp, ml, me, i)) {
 					for (; i--; p++) {
 						/* if we meet other non initialized its a bug */
 						BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id));
@@ -532,9 +548,148 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
 	MEM_freeN(poly_stack);
 
 	*r_totgroup = tot_group;
+	*r_poly_groups = poly_groups;
+}
+
+/**
+ * Calculate smooth groups from sharp edges.
+ *
+ * \param r_totgroup The total number of groups, 1 or more.
+ * \return Polygon aligned array of group index values (bitflags if use_bitflags is true), starting at 1
+ *         (0 being used as 'invalid' flag).
+ *         Note it's callers's responsibility to MEM_freeN returned array.
+ */
+int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
+                                const MPoly *mpoly, const int totpoly,
+                                const MLoop *mloop, const int totloop,
+                                int *r_totgroup, const bool use_bitflags)
+{
+	int *poly_groups = NULL;
+
+	bke_poly_loop_islands_compute(medge, totedge, mpoly, totpoly, mloop, totloop, use_bitflags,
+	                              bke_check_island_boundary_smooth, &poly_groups, r_totgroup);
 
 	return poly_groups;
 }
+
+void BKE_loop_islands_init(MeshIslands *islands, const int num_loops)
+{
+	islands->loops_to_islands_idx = MEM_mallocN(sizeof(*islands->loops_to_islands_idx) * (size_t)num_loops, __func__);
+	islands->islands = NULL;
+	islands->nbr_islands = 0;
+	islands->mem = NULL;
+}
+
+void BKE_loop_islands_free(MeshIslands *islands)
+{
+	/* For now, we use mere MEM_mallocN, later we'll probably switch to memarena! */
+	int i = islands->nbr_islands;
+
+	if (i) {
+		while (i--) {
+			MeshIslandItem *it = &islands->islands[i];
+			if (it->nbr_polys) {
+				MEM_freeN(it->polys_idx);
+			}
+		}
+
+		MEM_freeN(islands->islands);
+		MEM_freeN(islands->loops_to_islands_idx);
+	}
+
+	islands->nbr_loops = 0;
+	islands->loops_to_islands_idx = NULL;
+	islands->nbr_islands = 0;
+	islands->islands = NULL;
+	islands->mem = NULL;
+}
+
+void BKE_loop_islands_add_island(MeshIslands *islands, const int num_loops, int *loop_indices,
+                                 const int num_polys, int *poly_indices)
+{
+	MeshIslandItem *isl;
+	const int curr_island_idx = islands->nbr_islands++;
+	const size_t curr_num_islands = (size_t)islands->nbr_islands;
+	int i = num_loops;
+
+	islands->nbr_loops = num_loops;
+	while (i--) {
+		islands->loops_to_islands_idx[loop_indices[i]] = curr_island_idx;
+	}
+
+	/* XXX TODO UGLY!!! Quick code, to be done better. */
+	isl = MEM_mallocN(sizeof(*isl) * curr_num_islands, __func__);
+	if (curr_island_idx) {
+		memcpy(isl, islands->islands, sizeof(*isl) * (curr_num_islands - 1));
+		MEM_freeN(islands->islands);
+	}
+	islands->islands = isl;
+
+	isl = &isl[curr_island_idx];
+	isl->nbr_polys = num_polys;
+	isl->polys_idx = MEM_mallocN(sizeof(*isl->polys_idx) * (size_t)num_polys, __func_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list