[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