Page MenuHome

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

Authored by Bastien Montagne (mont29) on Nov 10 2014, 10:54 AM.

Details

Summary

Mesh data transfer (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 BKE's data_transfer and customdata areas.
  • Transfer of single data layer, mostly handled in BKE's customdata area.

Note mapping supports complex 'Islands' cases, where you need all elements of a given dest entity to map into a same source island's elements - only used and implemented at Loop level currently (UVs, and in near future custom loop normals), but design should allow to extend it to other mesh types if needed.
Note multi-layers data mapping and data transfer itself use some generic code, but can be overriden as needed (done for vgroups in this patch).

Additional possibilities/refinements include (only relevant for a subset of data types):

  • A way to filter which elements of destination we actually want to affect (through a vgroup, and/or above/below threshold).
  • 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?

Available as both a modifier and an ObjectMode operator.

Open questions:

  • UI: mostly, modifier one - in fact, I’m wondering if allowing to transfer several data types at once is such a good idea... Pro is, it avoids recomputing mapping data, but it makes UI rather confusing...
  • Mapping modes: not sure all implemented ones are that useful. And I know a few that are needed (like loop projection along vertex normal, not loop normal). But I think this can be done later too, that would not affect general design.

Remaining TODOs (not considered blocking for master inclusion, imho):

  • Shape Keys (not handled, have to see how this merges with gsoc work too).

Diff Detail

Repository
rB Blender
Branch
mesh-transfer-data

Event Timeline

Bastien Montagne (mont29) retitled this revision from to Mesh Data Transfer **********.
Bastien Montagne (mont29) updated this object.

Checked the patch, (first pass)

Overall, it seems like this is heading in a good direction, but theres enough issues remaining too that need some attention.

Usability

The modifier is showing many options which probably wont apply in many use cases (copying vgroups for example - 2/3 of UI has edge/face options still),
This _is_ difficult to present to the user in a straightforward way.
Anecdotal evidence - recently I talked to 2 guys on the gooseberry team about weight-copy feature, and neither managed to get it working usefully, this is strange since whenever I test it, it works fine... and I think its not _so_ hard to use, just to say conveying what happens here to users needs to have some consideration.

Feedback from others would be good here,
(own suggestion) - have a checkbox for each mapping mode (vert/edge/face-corner/face), then at least if the user really needs they can enable all... better solutions may exist though

  • By Position (could be confused with 3d position), better use By Order ?
  • Nearest Corner And Best Matching Face Normal - (maybe this is great to have, but are these tested for real-world use cases?, lots of stuff we _might_ want, but maybe not needed.. nice to see examples where these options are needed)

Functionality

I'd like to test this more when its more stable, but some quick observations.

  • Mix Mode, Having the option to 'Replace' would be useful.
  • 'Freestyle Flag' should be 'Freestyle Mark' or 'Freestyle Settings' (flag is internal naming).

A more general concern is that this is both a modifier and a tool, where tools are acceptable to be slow & give high quality results and modifiers are expected to stay fast & interactive. Just a comment & no action needed, but its something to keep in mind how to manage settings if some high quality data-transfer method doesn't work so well for modifiers.


Code

Getting some asserts just testing the modifier. (as well as the one mentioned)
DerivedMesh.c:1455, dm_ensure_display_normals(), at 'CustomData_has_layer(&dm->polyData, CD_NORMAL) == 0'

Got this crash copying vertex groups:

1Read new prefs: /root/.config/blender/2.72/config/userpref.blend
2=================================================================
3==17340==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020002132f8 at pc 0x235e983 bp 0x7fff3f9ffd60 sp 0x7fff3f9ffd50
4READ of size 8 at 0x6020002132f8 thread T0
5 #0 0x235e982 in defvert_find_index /src/blender/source/blender/blenkernel/intern/deform.c:764
6 #1 0x236071f in vgroups_datatransfer_interp /src/blender/source/blender/blenkernel/intern/deform.c:1082
7 #2 0x2352556 in CustomData_data_transfer /src/blender/source/blender/blenkernel/intern/customdata.c:3751
8 #3 0x235860e in BKE_data_transfer_dm /src/blender/source/blender/blenkernel/intern/data_transfer.c:830
9 #4 0x1d57601 in applyModifier /src/blender/source/blender/modifiers/intern/MOD_datatransfer.c:149
10 #5 0x25505f6 in modwrap_applyModifier /src/blender/source/blender/blenkernel/intern/modifier.c:744
11 #6 0x221f1e1 in mesh_calc_modifiers /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:1777
12 #7 0x2223653 in mesh_build_data /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:2277
13 #8 0x2223f0f in makeDerivedMesh /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:2350
14 #9 0x25bc8d9 in BKE_object_handle_update_ex /src/blender/source/blender/blenkernel/intern/object.c:3045
15 #10 0x26a1126 in scene_update_object_func /src/blender/source/blender/blenkernel/intern/scene.c:1369
16 #11 0x2f51f15 in BLI_task_pool_work_and_wait /src/blender/source/blender/blenlib/intern/task.c:368
17 #12 0x26a18dd in scene_update_objects /src/blender/source/blender/blenkernel/intern/scene.c:1515
18 #13 0x26a1b14 in scene_update_tagged_recursive /src/blender/source/blender/blenkernel/intern/scene.c:1556
19 #14 0x26a215a in BKE_scene_update_tagged /src/blender/source/blender/blenkernel/intern/scene.c:1643
20 #15 0xc31944 in wm_event_do_notifiers /src/blender/source/blender/windowmanager/intern/wm_event_system.c:378
21 #16 0xc20bc4 in WM_main /src/blender/source/blender/windowmanager/intern/wm.c:495
22 #17 0xc1e7ea in main /src/blender/source/creator/creator.c:1784
23 #18 0x7fcc174a003f in __libc_start_main (/usr/lib/libc.so.6+0x2003f)
24 #19 0xc18cd8 (/src/cmake_debug/bin/blender+0xc18cd8)
25
260x6020002132f8 is located 0 bytes to the right of 8-byte region [0x6020002132f0,0x6020002132f8)
27allocated by thread T0 here:
28 #0 0x7fcc1d432797 in __interceptor_malloc (/usr/lib/libasan.so.1+0x57797)
29 #1 0x2fc369a in MEM_lockfree_mallocN /src/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:299
30 #2 0x23421a8 in customData_duplicate_referenced_layer_index /src/blender/source/blender/blenkernel/intern/customdata.c:1942
31 #3 0x23423b2 in CustomData_duplicate_referenced_layer /src/blender/source/blender/blenkernel/intern/customdata.c:1963
32 #4 0x2361196 in data_transfer_layersmapping_vgroups /src/blender/source/blender/blenkernel/intern/deform.c:1210
33 #5 0x2356c37 in data_transfer_layersmapping_generate /src/blender/source/blender/blenkernel/intern/data_transfer.c:574
34 #6 0x23585c6 in BKE_data_transfer_dm /src/blender/source/blender/blenkernel/intern/data_transfer.c:821
35 #7 0x1d57601 in applyModifier /src/blender/source/blender/modifiers/intern/MOD_datatransfer.c:149
36 #8 0x25505f6 in modwrap_applyModifier /src/blender/source/blender/blenkernel/intern/modifier.c:744
37 #9 0x221f1e1 in mesh_calc_modifiers /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:1777
38 #10 0x2223653 in mesh_build_data /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:2277
39 #11 0x2223f0f in makeDerivedMesh /src/blender/source/blender/blenkernel/intern/DerivedMesh.c:2350
40 #12 0x25bc8d9 in BKE_object_handle_update_ex /src/blender/source/blender/blenkernel/intern/object.c:3045
41 #13 0x26a1126 in scene_update_object_func /src/blender/source/blender/blenkernel/intern/scene.c:1369
42 #14 0x2f51f15 in BLI_task_pool_work_and_wait /src/blender/source/blender/blenlib/intern/task.c:368
43 #15 0x26a18dd in scene_update_objects /src/blender/source/blender/blenkernel/intern/scene.c:1515
44 #16 0x26a1b14 in scene_update_tagged_recursive /src/blender/source/blender/blenkernel/intern/scene.c:1556
45 #17 0x26a215a in BKE_scene_update_tagged /src/blender/source/blender/blenkernel/intern/scene.c:1643
46 #18 0xc31944 in wm_event_do_notifiers /src/blender/source/blender/windowmanager/intern/wm_event_system.c:378
47 #19 0xc20bc4 in WM_main /src/blender/source/blender/windowmanager/intern/wm.c:495
48 #20 0xc1e7ea in main /src/blender/source/creator/creator.c:1784
49 #21 0x7fcc174a003f in __libc_start_main (/usr/lib/libc.so.6+0x2003f)


I'd like to go over this patch more, but as first pass review, think there is enough feedback for first-pass

source/blender/blenkernel/intern/mesh_mapping.c
896

The modifier can trigger this assert, ideally the modifier would check beforehand and display error text. (and not call BKE_dm2mesh_mapping_verts_compute in this case)

2063

This isnt so efficient to check isect_point_poly_v2 (which in turn loops over all points),
fill_poly_v2i_n is better suited to this task. (much faster, used for lasso-fill drawing)

Thanks for that first review, Campbell! Addressed most of raised issues (along a few others) in branch now.

Inlined are some further comments.

Usability
 […]
 (own suggestion) - have a checkbox for each mapping mode (vert/edge/face-corner/face), then at least if the user really needs they can enable all... better solutions may exist though

Gave it a try, think UI is much better now. But of course, more feedback here would be great, this is a tricky part.

 - Nearest Corner And Best Matching Face Normal - (maybe this is great to have, but are these tested for real-world use cases?, lots of stuff we _might_ want, but maybe not needed.. nice to see examples where these options are needed)

Hmmm… Tbh, I’m not sure all proposed mapping modes are useful, but that one is for sure. Thing is, once you have found nearest vertex, there is a good chance all loops of this vert share the same normal (smooth vertex), so using face normal as discriminant is often the best solution here.

Code
 Getting some asserts just testing the modifier. (as well as the one mentioned)
DerivedMesh.c:1455, dm_ensure_display_normals(), at 'CustomData_has_layer(&dm->polyData, CD_NORMAL) == 0'

Yeah… Well, enhanced normal handling in the patch quite a bit. But this remains tricky too, I think computing poly normals and just throwing them away afterwards is stupid, in the DM context (this is not a cheap operation). Consequently, I’ve disabled that assert for now.

I’m not quite sure this is right/safe though, maybe we'd rather just always (re)compute that data for now, and let proper poly/loop normals caching for another refactor?

Got this crash copying vertex groups: P164

Tried to reproduce, no luck so far. Traceback is also rather odd, as if CustomData_duplicate_referenced_layer() got called with wrong number of elements, but I cannot see how that would happen of hands. Crashing file would help here I guess.