Commit: 924ee6922a8ab8a1b16798beb2ad42109d7e3096
Author: Bastien Montagne
Date:   Fri Sep 12 11:47:31 2014 +0200
Branches: mesh-transfer-data
https://developer.blender.org/rB924ee6922a8ab8a1b16798beb2ad42109d7e3096

Mesh Transfer Data
**********

WARNING - fully non-functional commit (not even compilable!).

Mesh transfer data (data here being either real CD layers, like e.g. skinning 
weights, UVs, etc., or 'fake' ones, like e.g. vgroups, shapekeys, but also edge 
crease, smooth/sharp/seam flags, etc.) is subdivided in several sub-modules:
* Mapping between mesh elements (verts, edges, polys or loops), in BKE's 
`mesh_mapping`.
* Mapping between data layers (for non-singleton data types), mostly handled in 
`ED_object` and BKE's `customdata` areas.
* Transfer of single data layer, mostly handled in BKE's `customdata` area.

Additional possibilities (only relevant for a subset of data types) are barely 
sketched up currently:
* A way to filter which elements of destination we actually want to affect 
(currently, all, also the possibility to only affect those below a given 
threshold - could also add e.g. vgroup-based selection, etc.).
* A way to alter destination elements' data in other ways than mere replace 
(add/sub/mul/div/etc.).

All this is designed to be both easy to setup (code-wise) for simple types, and 
yet flexible enough to be usable by complex/weird data types like vgroups and 
shapekeys. For now, it is only expected to work in Object/modifier contexts, 
not quite sure whether having this in BMesh would be that much useful?

Mesh Elements Mapping
-----
This part is rather independent. Vertices and edges mappings are implemented 
(but not really tested yet, think will have to write some gtests for that 
anyway). Polygons are also finished, but not tested at all. Loops are mostly 
written, but not yet finished nor compilable (the most complex ones, since we 
have to take islands in consideration here).

Note mapping supports a distance threshold, to prevent geometry to far away 
from each other to match.

Data Layers Mapping
-----
This is handled by a struct defined in BKE_customdata, but filled in ED_object 
code. Each instance of DataTransferLayerMapping contains all data needed to 
execute the data transfer for each element of the mesh mapping.

`object_transfer_data.c` handles the generation of those data layers mapping 
instance for basic types (usual CDLayers, but also bitflags and simple data 
like edge crease), complex types like vgroups and shapekeys are handled by 
dedicated helpers in there own files - trying to keep code well ordered.

Transfer of Single Data Layer
-----
This is a low-level simple func in BKE_customdata, that executes the data 
transfer itself, including weighted interpolation if needed. It expects 
pre-computed inputs (mesh elements' and data layers' mappings).

High Level
-----
`ED_data_transfer` is the high-level interface to all this, used by the 
`OBJECT_OT_data_transfer` operator. Once again, not all features are 
implemented yet, by far.

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

M       release/scripts/startup/bl_ui/space_view3d.py
M       source/blender/blenkernel/BKE_bvhutils.h
M       source/blender/blenkernel/BKE_customdata.h
M       source/blender/blenkernel/BKE_mesh_mapping.h
M       source/blender/blenkernel/BKE_modifier.h
M       source/blender/blenkernel/intern/bvhutils.c
M       source/blender/blenkernel/intern/customdata.c
M       source/blender/blenkernel/intern/mesh_mapping.c
M       source/blender/editors/include/ED_object.h
M       source/blender/editors/object/CMakeLists.txt
M       source/blender/editors/object/object_intern.h
M       source/blender/editors/object/object_ops.c
A       source/blender/editors/object/object_transfer_data.c
M       source/blender/editors/object/object_vgroup.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py 
b/release/scripts/startup/bl_ui/space_view3d.py
index 2249d2b..2fc2240 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1077,6 +1077,7 @@ class VIEW3D_MT_object(Menu):
         layout.separator()
 
         layout.operator("object.join")
+        layout.operator("object.data_transfer")
 
         layout.separator()
 
diff --git a/source/blender/blenkernel/BKE_bvhutils.h 
b/source/blender/blenkernel/BKE_bvhutils.h
index 4bc8fc4..f8649e9 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -56,8 +56,8 @@ typedef struct BVHTreeFromMesh {
        struct MEdge *edge;     /* only used for BVHTreeFromMeshEdges */
        struct MFace *face;
        bool vert_allocated;
-       bool face_allocated;
        bool edge_allocated;
+       bool face_allocated;
 
        /* radius for raycast */
        float sphere_radius;
@@ -69,36 +69,28 @@ typedef struct BVHTreeFromMesh {
 } BVHTreeFromMesh;
 
 /*
- * Builds a bvh tree where nodes are the vertexs of the given mesh.
+ * Builds a bvh tree where nodes are the relevant elements of the given mesh.
  * Configures BVHTreeFromMesh.
  *
  * The tree is build in mesh space coordinates, this means special care must 
be made on queries
  * so that the coordinates and rays are first translated on the mesh local 
coordinates.
- * Reason for this is that later bvh_from_mesh_* might use a cache system and 
so it becomes possible to reuse
- * a BVHTree.
+ * Reason for this is that bvh_from_mesh_* can use a cache in some cases and 
so it becomes possible to reuse a BVHTree.
  * 
  * free_bvhtree_from_mesh should be called when the tree is no longer needed.
  */
 BVHTree *bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct 
DerivedMesh *mesh, float epsilon, int tree_type, int axis);
-
-/*
- * Builds a bvh tree where nodes are the faces of the given mesh.
- * Configures BVHTreeFromMesh.
- *
- * The tree is build in mesh space coordinates, this means special care must 
be made on queries
- * so that the coordinates and rays are first translated on the mesh local 
coordinates.
- * Reason for this is that later bvh_from_mesh_* might use a cache system and 
so it becomes possible to reuse
- * a BVHTree.
- *
- * The returned value is the same as in data->tree, its only returned to make 
it easier to test
- * the success 
- * 
- * free_bvhtree_from_mesh should be called when the tree is no longer needed.
- */
-BVHTree *bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct 
DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data, struct MVert 
*vert, const int numVerts,
+                                    const bool vert_allocated, bool *mask, int 
numVerts_active,
+                                    float epsilon, int tree_type, int axis);
 
 BVHTree *bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct 
DerivedMesh *mesh, float epsilon, int tree_type, int axis);
 
+BVHTree *bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct 
DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_faces_ex(struct BVHTreeFromMesh *data, struct MVert 
*vert, const bool vert_allocated,
+                                    struct MFace *face, const int numFaces, 
const bool face_allocated,
+                                    bool *mask, int numFaces_active,
+                                    float epsilon, int tree_type, int axis);
+
 /*
  * Frees data allocated by a call to bvhtree_from_mesh_*.
  */
@@ -115,11 +107,12 @@ float nearest_point_in_tri_surface_squared(const float 
v0[3], const float v1[3],
  */
 
 //Using local coordinates
-#define BVHTREE_FROM_FACES      0
-#define BVHTREE_FROM_VERTICES   1
-#define BVHTREE_FROM_EDGES      2
-
-#define BVHTREE_FROM_FACES_EDITMESH  3
+enum {
+       BVHTREE_FROM_VERTS           = 0,
+       BVHTREE_FROM_EDGES           = 1,
+       BVHTREE_FROM_FACES           = 2,
+       BVHTREE_FROM_FACES_EDITMESH  = 3,
+};
 
 typedef struct LinkNode *BVHCache;
 
diff --git a/source/blender/blenkernel/BKE_customdata.h 
b/source/blender/blenkernel/BKE_customdata.h
index 9a6524c..f08fd3c 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -41,6 +41,8 @@ extern "C" {
 #include "BLI_sys_types.h"
 #include "BLI_utildefines.h"
 
+#include "DNA_customdata_types.h"
+
 struct BMesh;
 struct ID;
 struct CustomData;
@@ -77,6 +79,9 @@ extern const CustomDataMask CD_MASK_EVERYTHING;
 
 void customData_mask_layers__print(CustomDataMask mask);
 
+typedef void (*cd_interp)(void **sources, const float *weights, const float 
*sub_weights, int count, void *dest);
+typedef void (*cd_copy)(const void *source, void *dest, int count);
+
 /**
  * Checks if the layer at physical offset \a layer_n (in data->layers) support 
math
  * the below operations.
@@ -245,14 +250,14 @@ void *CustomData_bmesh_get_n(const struct CustomData 
*data, void *block, int typ
 void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, 
int n);
 
 bool CustomData_set_layer_name(const struct CustomData *data, int type, int n, 
const char *name);
+const char *CustomData_get_layer_name(const struct CustomData *data, int type, 
int n);
 
 /* gets a pointer to the active or first layer of type
  * returns NULL if there is no layer of type
  */
 void *CustomData_get_layer(const struct CustomData *data, int type);
 void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
-void *CustomData_get_layer_named(const struct CustomData *data, int type,
-                                 const char *name);
+void *CustomData_get_layer_named(const struct CustomData *data, int type, 
const char *name);
 int CustomData_get_offset(const struct CustomData *data, int type);
 int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
 
@@ -360,6 +365,60 @@ void CustomData_external_read(struct CustomData *data,
 void CustomData_external_reload(struct CustomData *data,
                                 struct ID *id, CustomDataMask mask, int 
totelem);
 
+/* Mesh-to-mesh transfer data. */
+
+struct Mesh2MeshMapping;
+typedef struct DataTransferLayerMapping DataTransferLayerMapping;
+
+typedef void (*cd_datatransfer_interp)(const DataTransferLayerMapping *laymap,
+                                       void **sources, const float *weights, 
int count, void *dest);
+
+/* Fake CD_LAYERS (those are actually 'real' data stored directly into 
elements' structs). */
+enum {
+       CD_FAKE             = 1 << 8,
+
+       /* Vertices. */
+       CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT,  /* *sigh* due to how 
vgroups are stored :( . */
+       CD_FAKE_SHAPEKEY    = CD_FAKE | CD_SHAPEKEY,  /* Not available as real 
CD layer in non-bmesh context. */
+
+       /* Edges. */
+       CD_FAKE_SEAM        = CD_FAKE | 100,  /* UV seam flag for edges. */
+       CD_FAKE_CREASE      = CD_FAKE | CD_CREASE,  /* *sigh*. */
+
+       /* Multiple types of mesh elements... */
+       CD_FAKE_BWEIGHT     = CD_FAKE | CD_BWEIGHT,  /* *sigh*. */
+
+       CD_FAKE_SHARP       = CD_FAKE | 200,  /* Sharp flag for edges, smooth 
flag for faces. */
+};
+
+enum {
+       ME_VERT = 1,
+       ME_EDGE = 2,
+       ME_POLY = 3,
+       ME_LOOP = 4,
+};
+
+typedef struct DataTransferLayerMapping {
+       DataTransferLayerMapping *next, *prev;
+
+       int data_type;
+
+       void *data_src;      /* Data source array (can be regular CD data, 
vertices/edges/etc., keyblocks...). */
+       void *data_dst;      /* Data dest array (same type as dat_src). */
+       int data_n_src;      /* Index to affect in data_src (used e.g. for 
vgroups). */
+       int data_n_dst;      /* Index to affect in data_dst (used e.g. for 
vgroups). */
+       size_t elem_size;    /* Size of one element of data_src/data_dst. */
+
+       size_t data_size;    /* Size of actual data we transfer. */
+       size_t data_offset;  /* Offset of actual data we transfer (in element 
contained in data_src/dst). */
+       uint64_t data_flag;  /* For bitflag transfer, flag(s) to affect in 
transfered data. */
+
+       cd_datatransfer_interp interp;
+} DataTransferLayerMapping;
+
+/* Those functions assume src_n and dst_n layers of given type exist in resp. 
src and dst. */
+void CustomData_data_transfer(const struct Mesh2MeshMapping *m2mmap, const 
DataTransferLayerMapping *laymap);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h 
b/source/blender/blenkernel/BKE_mesh_mapping.h
index ed7e506..235bb45 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -31,6 +31,9 @@
  *  \ingroup bke
  */
 
+struct CustomData;
+struct DerivedMesh;
+struct MVert;
 struct MPoly;
 struct MEdge;
 struct MLoop;
@@ -109,6 +112,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);
@@ -129,6 +136,149 @@ int *BKE_mesh_calc_smoothgroups(
         const struct MLoop *mloop, const int totloop,
         int *r_totgroup, const bool use_bitflags);
 
+/* Generic ways to map some geometry elements from a source mesh to a dest 
one. */
+
+typedef struct Mesh2MeshMappingItem {
+       int nbr_sources;
+       int *indices_src;  /* NULL if no source found. */
+       float *weights_src;  /* NULL if no source found, else, always 
normalized! */
+       float hit_distance;  /* FLT_MAX if irrelevant or no source found. */
+       int island;  /* For loops only. */
+} Mesh2MeshMappingItem;
+
+/* All mapping computing func return this. */
+typedef struct Mesh2MeshMapping {
+       Mesh2MeshMappingItem *items;  /* Array, one item per dest element. */
+       int nbr_items;
+       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 lo

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to