[Bf-blender-cvs] [58d7153] master: BKE: Add 'mesh remap' code.

Bastien Montagne noreply at git.blender.org
Fri Jan 9 18:36:04 CET 2015


Commit: 58d7153c6c4d52005cde1547592efaced1507d9c
Author: Bastien Montagne
Date:   Fri Jan 9 18:23:17 2015 +0100
Branches: master
https://developer.blender.org/rB58d7153c6c4d52005cde1547592efaced1507d9c

BKE: Add 'mesh remap' code.

This is the (big!) core of mesh transfer data, it defines a set of structures
to represent a mapping of mesh elements (verts, edges, polys of loops) between
two arbitrary meshes, and code to compute such mappings.

No similarity is required between source and destination meshes (though results
when using complete different meshes are rather unlikely to be useful!).

This code is not bound to data transfer, it is defined to be as generic as possible,
and easy to reuse or extend as needs arise.

Several methods of mapping generation are defined for each element type,
we probably will have to adjust that in future (remove useless ones, add
new ones...).

For loops, you can also define islands (for UVs e.g.) so that loops of a same
destination polygon do not 'spread' across several source islands.

Heavily reviewed and enhanced by Campbell, thanks a lot!

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

M	source/blender/blenkernel/BKE_mesh_mapping.h
A	source/blender/blenkernel/BKE_mesh_remap.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/mesh_mapping.c
A	source/blender/blenkernel/intern/mesh_remap.c

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

diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index ed7e506..da44c98 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -31,8 +31,9 @@
  *  \ingroup bke
  */
 
-struct MPoly;
+struct MVert;
 struct MEdge;
+struct MPoly;
 struct MLoop;
 struct MLoopUV;
 
@@ -109,6 +110,10 @@ void BKE_mesh_vert_poly_map_create(
         MeshElemMap **r_map, int **r_mem,
         const struct MPoly *mface, const struct MLoop *mloop,
         int totvert, int totface, int totloop);
+void BKE_mesh_vert_loop_map_create(
+        MeshElemMap **r_map, int **r_mem,
+        const struct MPoly *mface, const struct MLoop *mloop,
+        int totvert, int totface, int totloop);
 void BKE_mesh_vert_edge_map_create(
         MeshElemMap **r_map, int **r_mem,
         const struct MEdge *medge, int totvert, int totedge);
@@ -122,7 +127,61 @@ void BKE_mesh_origindex_map_create(
         const int totorig,
         const int *final_origindex, const int totfinal);
 
-/* smoothgroups */
+
+/* islands */
+
+/* Loop islands data helpers. */
+enum {
+	MISLAND_TYPE_NONE = 0,
+	MISLAND_TYPE_VERT = 1,
+	MISLAND_TYPE_EDGE = 2,
+	MISLAND_TYPE_POLY = 3,
+	MISLAND_TYPE_LOOP = 4,
+};
+
+typedef struct MeshIslandStore {
+	short item_type;      /* MISLAND_TYPE_... */
+	short island_type;    /* MISLAND_TYPE_... */
+	short innercut_type;  /* MISLAND_TYPE_... */
+
+	int  items_to_islands_num;
+	int *items_to_islands;  /* map the item to the island index */
+
+	int                  islands_num;
+	size_t               islands_num_alloc;
+	struct MeshElemMap **islands;    /* Array of pointers, one item per island. */
+	struct MeshElemMap **innercuts;  /* Array of pointers, one item per island. */
+
+	struct MemArena *mem;  /* Memory arena, internal use only. */
+} MeshIslandStore;
+
+void BKE_mesh_loop_islands_init(
+        MeshIslandStore *island_store,
+        const short item_type, const int item_num, const short island_type, const short innercut_type);
+void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store);
+void BKE_mesh_loop_islands_free(MeshIslandStore *island_store);
+void BKE_mesh_loop_islands_add(
+        MeshIslandStore *islands, const int item_num, int *item_indices,
+        const int num_island_items, int *island_item_indices,
+        const int num_innercut_items, int *innercut_item_indices);
+
+typedef bool (*MeshRemapIslandsCalc)(
+        struct MVert *verts, const int totvert,
+        struct MEdge *edges, const int totedge,
+        struct MPoly *polys, const int totpoly,
+        struct MLoop *loops, const int totloop,
+        struct MeshIslandStore *r_island_store);
+
+/* 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(
+        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);
+
 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/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
new file mode 100644
index 0000000..e1f37a6
--- /dev/null
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -0,0 +1,171 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_MESH_REMAP_H__
+#define __BKE_MESH_REMAP_H__
+
+/** \file BKE_mesh_remap.h
+ *  \ingroup bke
+ */
+
+struct CustomData;
+struct DerivedMesh;
+struct MVert;
+struct MeshElemMap;
+struct MemArena;
+
+/* Generic ways to map some geometry elements from a source mesh to a dest one. */
+
+typedef struct MeshPairRemapItem {
+	int    sources_num;
+	int   *indices_src;     /* NULL if no source found. */
+	float *weights_src;     /* NULL if no source found, else, always normalized! */
+	/* UNUSED (at the moment)*/
+	// float  hit_dist;     /* FLT_MAX if irrelevant or no source found. */
+	int    island;          /* For loops only. */
+} MeshPairRemapItem;
+
+/* All mapping computing func return this. */
+typedef struct MeshPairRemap {
+	int                items_num;
+	MeshPairRemapItem *items;  /* array, one item per dest element. */
+
+	struct MemArena *mem;  /* memory arena, internal use only. */
+} MeshPairRemap;
+
+/* Helpers! */
+void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num);
+void BKE_mesh_remap_free(MeshPairRemap *map);
+
+void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index);
+
+/* 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
+ * We could also use similar topology mappings inside a same mesh
+ * (cf. Campbell's 'select face islands from similar topology' wip work).
+ * Also, users will have to check, whether we can get rid of some modes here, not sure all will be useful!
+ */
+enum {
+	MREMAP_USE_VERT                      = 1 << 4,
+	MREMAP_USE_EDGE                      = 1 << 5,
+	MREMAP_USE_LOOP                      = 1 << 6,
+	MREMAP_USE_POLY                      = 1 << 7,
+
+	MREMAP_USE_NEAREST                   = 1 << 8,
+	MREMAP_USE_NORPROJ                   = 1 << 9,
+	MREMAP_USE_INTERP                    = 1 << 10,
+	MREMAP_USE_NORMAL                    = 1 << 11,
+
+	/* ***** Target's vertices ***** */
+	MREMAP_MODE_VERT                     = 1 << 24,
+	/* Nearest source vert. */
+	MREMAP_MODE_VERT_NEAREST             = MREMAP_MODE_VERT | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
+
+	/* Nearest vertex of nearest edge. */
+	MREMAP_MODE_VERT_EDGE_NEAREST        = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
+	/* This one uses two verts of selected edge (weighted interpolation). */
+	/* Nearest point on nearest edge. */
+	MREMAP_MODE_VERT_EDGEINTERP_NEAREST  = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+
+	/* Nearest vertex of nearest poly. */
+	MREMAP_MODE_VERT_POLY_NEAREST        = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+	/* Those two use all verts of selected poly (weighted interpolation). */
+	/* Nearest point on nearest poly. */
+	MREMAP_MODE_VERT_POLYINTERP_NEAREST  = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+	/* Point on nearest face hit by ray from target vertex's normal. */
+	MREMAP_MODE_VERT_POLYINTERP_VNORPROJ = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+	/* ***** Target's edges ***** */
+	MREMAP_MODE_EDGE                     = 1 << 25,
+
+	/* Source edge which both vertices are nearest of dest ones. */
+	MREMAP_MODE_EDGE_VERT_NEAREST        = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
+
+	/* Nearest source edge (using mid-point). */
+	MREMAP_MODE_EDGE_NEAREST             = MREMAP_MODE_EDGE | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
+
+	/* Nearest edge of nearest poly (using mid-point). */
+	MREMAP_MODE_EDGE_POLY_NEAREST        = MREMAP_MODE_EDGE | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+
+	/* Cast a set of rays from along dest edge, interpolating its vertices' normals, and use hit source edges. */
+	MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+	/* ***** Target's loops ***** */
+	/* Note: when islands are given to loop mapping func, all loops from the same destination face will always be mapped
+	 *       to loops of source faces within a same island, regardless of mapping mode. */
+	MREMAP_MODE_LOOP                     = 1 << 26,
+
+	/* Best normal-matching loop from nearest vert. */
+	MREMAP_MODE_LOOP_NEAREST_LOOPNOR     = MREMAP_MODE_LOOP | MREMAP_USE_LOOP | MREMAP_USE_VERT | MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
+	/* Loop from best normal-matching poly from nearest vert. */
+	MREMAP_MODE_LOOP_NEAREST_POLYNOR     = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_VERT | MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
+
+	/* Loop from nearest vertex of nearest poly. */
+	MREMAP_MODE_LOOP_POLY_NEAREST        = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+	/* Those two use all verts of selected poly (weighted interpolation). */
+	/* Nearest point on nearest poly. */
+	MREMAP_MODE_LOOP_POLYINTERP_NEAREST  = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+	/* Point on nearest face hit by ray from target loop's normal. */
+	MREMAP_MODE_LOOP_POLYINTERP_LNORPROJ = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+	/* ***** Target's polygons ***** */
+	MREMAP_MODE_POLY                     = 1 << 27,
+
+	/* Nearest source poly. */
+	MREMAP_MODE_POLY_NEAREST             = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+	/* Source poly from best normal-matching dest poly. */
+	MREMAP_MODE_POLY_NOR                 = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORMAL,
+
+	/* Project dest poly onto source mesh using its normal, and use interpolation of all intersecting source polys. */
+	MREMAP_MODE_POLY_POLYINTERP_PNORPROJ = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+	/* ***** Same topology, applies to all four element

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list